The playFile program creates a logger, opens a logger tape, and plays it back.
Periodic messages output the current tape time. If 'q' is pressed playback stops and the program exits\ immediately, otherwise it will continue to the end of the tape at which point it will exit.
#include <vlutil/vlProcessControl.h>
#include <vlutil/vlPrint.h>
#include <vlutil/vlMiniDumper.h>
#include <cmdLine/cmdLine.h>
#if DtDIS
#include <vl/exerciseConnInitializerDIS.h>
#endif
#if DtHLA
#include <vl/exerciseConnInitializerHLA.h>
#include <vl/emptyFomMapper.h>
#endif
#include "vlutil/vlLogFileInfo.h"
#include "lgrUtil/svnRev.h"
using namespace MAKLogger;
#if DtDIS
const char defaultFileName[] = "..\\logger_tapes\\bombMission2025-DIS.lgr";
#elif DtHLA_4
const char defaultFileName[] = "..\\logger_tapes\\bombMission2025-HLA4-NETN.lgr";
#endif
bool fileTypeMatches(DtString& filename);
void setConfigParameters(DtExerciseConnInitializer& exConnInit, const DtFilename& filename);
bool keyCheck(const char* keysToCheck);
int playFile(int argc, char** argv)
{
DtCmdLine::UnlabeledMultiArg<DtString> filenameArg("Filename","The name of the logger file to play.","string");
DtCmdLine::ValueArg<double> playbackSpeed("s","speed", "The playback speed.",false, 1.0,"double");
cmdLine.add(&filenameArg);
cmdLine.add(playbackSpeed);
cmdLine.parse(argc,argv);
std::vector<DtString> values = filenameArg.getValue();
if(values.size() == 0)
{
#ifdef DtHLA_4
values.push_back(defaultFileName);
#elif DtHLA_1516_EVOLVED
DtInfo << "Please provide a logger file using the HLA 1516 Evolved protocol to read." << std::endl;
return 1;
#elif DtDIS
values.push_back(defaultFileName);
#elif DtHLA_1516
DtInfo << "Please provide a logger file using the HLA 1516 protocol to read." << std::endl;
return 1;
#else
DtInfo << "Please provide a logger file using the HLA 1.3 protocol to read." << std::endl;
return 1;
#endif
}
DtFilename filename(values.front().c_str());
try
{
DtExerciseConnInitializer exConnInit;
#if DtDIS
#else
exConnInit.setFederateType("playFile");
exConnInit.setFederateName("playFile");
DtHlaLogger* aLogger = DtHlaLogger::create(true);
#endif
if (!fileTypeMatches(filename))
{
DtInfo << "Unable to process file (" <<
filename.c_str() << "): file format designator does not match, unknown or corrupted." << std::endl;
return 1;
}
#if DtHLA
setConfigParameters(exConnInit, filename);
#endif
aLogger->connect(exConnInit);
aLogger->tick();
{
DtInfo << "Unable to connect." << std::endl;
return 1;
}
delete simInterface;
if(!pbInterface)
{
DtInfo << "Error: Unable to create playback interface." << std::endl;
return 1;
}
aLogger->tick();
{
DtInfo << "Unable to open file: " << filename << "." << std::endl;
return 1;
}
if (playbackSpeed.isSet())
{
DtInfo << "Setting playback speed to " << playbackSpeed.getValue() << std::endl;
}
DtInfo << "Playing file: " << filename << "." << std::endl;
DtInfo << "Press 'q' or 'enter' to quit." << std::endl;
aLogger->tick();
{
DtInfo << "Unable to play file." << std::endl;
return 1;
}
double printDelay = 1.0;
double printLoopTotal = 0;
double loopDelay = .1;
{
aLogger->tick();
if(printLoopTotal >= printDelay)
{
DtInfo <<
"Current Time = " << pbInterface->
currentTime() <<
"." << std::endl;
printLoopTotal = 0.0;
}
printLoopTotal += loopDelay;
DtSleep(loopDelay);
if(keyCheck("q\r")) break;
}
{
DtInfo << "Stopping playback." << std::endl;
aLogger->tick();
}
DtInfo << "Finished playing file." << std::endl;
DtRestoreKbHit();
delete pbInterface;
delete aLogger;
}
catch (DtException& ex)
{
DtInfo << output << std::endl;
return 0;
}
return 0;
}
int main(int argc, char** argv)
{
DtLogFileInfo::instance().setAppName("PlayFile");
DtLogFileInfo::instance().setProtocol(DT_PROTOCOL_SHORT_NAME);
DtLogFileInfo::instance().setSvnRev(SVN_REV);
DtINIT_MINIDUMPER(DtLogFileInfo::instance().getFullString().c_str());
return playFile(argc,argv);
}
bool keyCheck(const char* keysToCheck)
{
if(DtKbHit())
{
char c = DtGetCh();
return strchr(keysToCheck,c) != 0;
}
return false;
}
bool fileTypeMatches(DtString& filename)
{
unsigned int magic = 0;
std::ifstream fs;
fs.open(filename.c_str(),std::ios::binary );
if(!fs.is_open() || !fs.good())
{
DtInfo << "Unable to open file: " << filename << "." << std::endl;
exit(1);
}
fs.read((char*)&magic,4);
magic = (magic >> 24) | ((magic >> 8) & 0xFF00) |
((magic << 8) & 0xFF0000) | (magic << 24);
#if DtDIS
#else
return DtString("Unknown") != DtLgrHlaFileFormats::versionString(magic);
#endif
}
#if DtHLA
void setConfigParameters(DtExerciseConnInitializer& exConnInit, const DtFilename& filename)
{
try
{
}
catch(DtException& ex)
{
DtInfo << output << std::endl;
}
if(configPacket)
{
}
exConnInit.setRprFomVersion(configData.
fomVersion().toDouble());
{
{
}
}
{
exConnInit.setFomMapper(new DtEmptyFomMapper());
}
DtFilename fedFile(configData.
fedFile().c_str());
fedFile.stripPath();
exConnInit.setFedFileName(fedFile);
#if DtHLA_1516_EVOLVED
std::vector<DtString> fomModNames;
int numberModules = fomModNames.size();
if (numberModules > 0)
{
for (int fmIndex=0; fmIndex < numberModules; ++fmIndex)
{
DtFilename fmFilename(fomModNames[fmIndex].c_str());
fmFilename.stripPath();
fomModNames[fmIndex] = fmFilename;
}
exConnInit.setFomModules(fomModNames);
}
if (!configData.
mim().isEmpty())
{
DtFilename mim(configData.
mim().c_str());
mim.stripPath();
exConnInit.setMimModule(mim);
}
#endif
delete file;
}
#endif