patch for catch (by Scott)

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@6926 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: b5c1d77b003ea626ebbaa73eb21d29bde5004cee
Former-commit-id: a31f1f43364b08de9638477112da11319adca7ea
This commit is contained in:
torcs-ng 2020-04-19 23:22:42 +00:00
parent ffeb2061a1
commit 7ae1fa574e

View file

@ -16,8 +16,8 @@
* *
***************************************************************************/
/** @file
Application base
/** @file
Application base
@version $Id$
@ingroup tgf
*/
@ -47,499 +47,499 @@ GfApplication* GfApplication::_pSelf = 0;
GfApplication& GfApplication::self()
{
if (!_pSelf)
{
GfLogError("GfApplication not yet created ; exiting");
::exit(1);
}
return *_pSelf;
if (!_pSelf)
{
GfLogError("GfApplication not yet created ; exiting");
::exit(1);
}
return *_pSelf;
}
GfApplication::GfApplication(const char* pszName, const char* pszVersion, const char* pszDesc)
: _strName(pszName ? pszName : "GfApplication"), _strDesc(pszDesc ? pszDesc : ""),
_strVersion(pszVersion ? pszVersion : ""), _pEventLoop(0)
{
// Check that we are the only instance.
if (_pSelf)
{
fprintf(stderr, "More than one GfApplication instance ; exiting\n");
::exit(1);
}
// Check that we are the only instance.
if (_pSelf)
{
fprintf(stderr, "More than one GfApplication instance ; exiting\n");
::exit(1);
}
// Register oneself as the one.
_pSelf = this;
// Register oneself as the one.
_pSelf = this;
}
void GfApplication::initialize(bool bLoggingEnabled, int argc, char **argv)
{
// Store the command line args.
if (argv)
for (int i = 0; i < argc; i++)
_lstArgs.push_back(argv[i]);
// Store the command line args.
if (argv)
for (int i = 0; i < argc; i++)
_lstArgs.push_back(argv[i]);
// Initialize the gaming framework (beware: only GfLogDefault booted).
GfInit(bLoggingEnabled);
// Initialize the gaming framework (beware: only GfLogDefault booted).
GfInit(bLoggingEnabled);
// Trace app. information.
GfLogInfo("%s %s", _strName.c_str(), _strVersion.c_str());
if (!_strDesc.empty())
GfLogInfo(" (%s)", _strDesc.c_str());
GfLogInfo("\n");
GfLogInfo("%s %s", _strName.c_str(), _strVersion.c_str());
if (!_strDesc.empty())
GfLogInfo(" (%s)", _strDesc.c_str());
GfLogInfo("\n");
// Register the command line options (to be parsed).
registerOption("h", "help", /* nHasValue = */ false);
registerOption("v", "version", /* nHasValue = */ false);
registerOption("lc", "localdir", /* nHasValue = */ true);
registerOption("ld", "libdir", /* nHasValue = */ true);
registerOption("bd", "bindir", /* nHasValue = */ true);
registerOption("dd", "datadir", /* nHasValue = */ true);
registerOption("tl", "tracelevel", /* nHasValue = */ true);
registerOption("ts", "tracestream", /* nHasValue = */ true);
registerOption("nr", "norandom", /* nHasValue = */ false);
// Help about the command line options.
addOptionsHelpSyntaxLine("[-v|--version]");
addOptionsHelpSyntaxLine("[-h|--help]");
addOptionsHelpSyntaxLine("[-lc|--localdir <dir path>] [-ld|--libdir <dir path>]");
addOptionsHelpSyntaxLine("[-bd|--bindir <dir path>] [-dd|--datadir <dir path>]");
registerOption("h", "help", /* nHasValue = */ false);
registerOption("v", "version", /* nHasValue = */ false);
registerOption("lc", "localdir", /* nHasValue = */ true);
registerOption("ld", "libdir", /* nHasValue = */ true);
registerOption("bd", "bindir", /* nHasValue = */ true);
registerOption("dd", "datadir", /* nHasValue = */ true);
registerOption("tl", "tracelevel", /* nHasValue = */ true);
registerOption("ts", "tracestream", /* nHasValue = */ true);
registerOption("nr", "norandom", /* nHasValue = */ false);
// Help about the command line options.
addOptionsHelpSyntaxLine("[-v|--version]");
addOptionsHelpSyntaxLine("[-h|--help]");
addOptionsHelpSyntaxLine("[-lc|--localdir <dir path>] [-ld|--libdir <dir path>]");
addOptionsHelpSyntaxLine("[-bd|--bindir <dir path>] [-dd|--datadir <dir path>]");
#ifdef TRACE_OUT
addOptionsHelpSyntaxLine("[-tl|--tracelevel <integer>]"
" [-ts|--tracestream stdout|stderr|<file name>]");
addOptionsHelpSyntaxLine("[-tl|--tracelevel <integer>]"
" [-ts|--tracestream stdout|stderr|<file name>]");
#endif
addOptionsHelpSyntaxLine("[-nr|--norandom]");
addOptionsHelpExplainLine
("- locadir : Root dir of the tree where user settings files are stored");
addOptionsHelpExplainLine
(" (default=" SD_LOCALDIR ")");
addOptionsHelpExplainLine
("- libdir : Root dir of the tree where loadable modules are installed");
addOptionsHelpExplainLine
(" (default=" SD_LIBDIR ")");
addOptionsHelpExplainLine
("- bindir : Dir where the game exe and DLLs are installed");
addOptionsHelpExplainLine
(" (default=" SD_BINDIR ")");
addOptionsHelpExplainLine
("- datadir : Root dir of the data tree (cars, tracks, ...)");
addOptionsHelpExplainLine
(" (default=" SD_DATADIR ")");
addOptionsHelpSyntaxLine("[-nr|--norandom]");
addOptionsHelpExplainLine
("- locadir : Root dir of the tree where user settings files are stored");
addOptionsHelpExplainLine
(" (default=" SD_LOCALDIR ")");
addOptionsHelpExplainLine
("- libdir : Root dir of the tree where loadable modules are installed");
addOptionsHelpExplainLine
(" (default=" SD_LIBDIR ")");
addOptionsHelpExplainLine
("- bindir : Dir where the game exe and DLLs are installed");
addOptionsHelpExplainLine
(" (default=" SD_BINDIR ")");
addOptionsHelpExplainLine
("- datadir : Root dir of the data tree (cars, tracks, ...)");
addOptionsHelpExplainLine
(" (default=" SD_DATADIR ")");
#ifdef TRACE_OUT
addOptionsHelpExplainLine
("- tracelevel : Maximum level of displayed traces for the default logger");
addOptionsHelpExplainLine
(" (0=Fatal, 1=Error, 2=Warning, 3=Info, 4=Trace, 5=Debug, ... ; default=5)");
addOptionsHelpExplainLine
("- tracestream : Target output stream for the default logger (default=stderr)");
addOptionsHelpExplainLine
("- norandom : Force reproducible random sequences for every game session (default=off)");
addOptionsHelpExplainLine
("- tracelevel : Maximum level of displayed traces for the default logger");
addOptionsHelpExplainLine
(" (0=Fatal, 1=Error, 2=Warning, 3=Info, 4=Trace, 5=Debug, ... ; default=5)");
addOptionsHelpExplainLine
("- tracestream : Target output stream for the default logger (default=stderr)");
addOptionsHelpExplainLine
("- norandom : Force reproducible random sequences for every game session (default=off)");
#endif
}
const std::string& GfApplication::name() const
{
return _strName;
return _strName;
}
const std::string& GfApplication::description() const
{
return _strDesc;
return _strDesc;
}
const std::string& GfApplication::version() const
{
return _strVersion;
return _strVersion;
}
void GfApplication::updateUserSettings()
{
GfFileSetup();
// Complete logging system initialisation
// 1) Reparse the relevant options if present.
int nDefTraceLevel = std::numeric_limits<int>::min();
std::string strDefTraceStream;
GfFileSetup();
std::list<Option>::const_iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
{
// Not found in the command line => ignore / default value.
if (!itOpt->bFound)
continue;
// Trace level threshold (only #ifdef TRACE_OUT)
if (itOpt->strLongName == "tracelevel")
{
if (sscanf(itOpt->strValue.c_str(), "%d", &nDefTraceLevel) < 1)
{
printUsage("Error: Could not convert trace level to an integer.");
nDefTraceLevel = std::numeric_limits<int>::min();
}
}
// Target trace stream (only #ifdef TRACE_OUT)
else if (itOpt->strLongName == "tracestream")
{
strDefTraceStream = itOpt->strValue;
}
}
// Complete logging system initialisation
// 1) Reparse the relevant options if present.
int nDefTraceLevel = std::numeric_limits<int>::min();
std::string strDefTraceStream;
// 2) Take the options into account.
// Note: Not achieved earlier because we need one of the user settings files : logging.xml.
GfLogger::setup();
if (nDefTraceLevel != std::numeric_limits<int>::min())
GfLogDefault.setLevelThreshold(nDefTraceLevel);
if (!strDefTraceStream.empty())
GfLogDefault.setStream(strDefTraceStream);
std::list<Option>::const_iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
{
// Not found in the command line => ignore / default value.
if (!itOpt->bFound)
continue;
// Trace level threshold (only #ifdef TRACE_OUT)
if (itOpt->strLongName == "tracelevel")
{
if (sscanf(itOpt->strValue.c_str(), "%d", &nDefTraceLevel) < 1)
{
printUsage("Error: Could not convert trace level to an integer.");
nDefTraceLevel = std::numeric_limits<int>::min();
}
}
// Target trace stream (only #ifdef TRACE_OUT)
else if (itOpt->strLongName == "tracestream")
{
strDefTraceStream = itOpt->strValue;
}
}
// 2) Take the options into account.
// Note: Not achieved earlier because we need one of the user settings files : logging.xml.
GfLogger::setup();
if (nDefTraceLevel != std::numeric_limits<int>::min())
GfLogDefault.setLevelThreshold(nDefTraceLevel);
if (!strDefTraceStream.empty())
GfLogDefault.setStream(strDefTraceStream);
}
void GfApplication::setEventLoop(GfEventLoop* pEventLoop)
{
_pEventLoop = pEventLoop;
_pEventLoop = pEventLoop;
}
GfEventLoop& GfApplication::eventLoop()
{
if (!_pEventLoop)
GfLogError("GfApplication has no event loop ; crashing !\n");
return *_pEventLoop;
if (!_pEventLoop)
GfLogError("GfApplication has no event loop ; crashing !\n");
return *_pEventLoop;
}
void GfApplication::restart()
{
// Shutdown the gaming framework.
GfShutdown();
// Shutdown the gaming framework.
GfShutdown();
// Delete the event loop if any.
delete _pEventLoop;
_pEventLoop = 0;
// Delete the event loop if any.
delete _pEventLoop;
_pEventLoop = 0;
// Reset the Memory Manager
#ifdef __DEBUG_MEMORYMANAGER__
(*ReleaseData)();
#endif
// Reset the Memory Manager
#ifdef __DEBUG_MEMORYMANAGER__
(*ReleaseData)();
#endif
// Restart the process, using same command line args.
// 1) The process executable path-name is the 1st arg left untouched.
GfLogInfo("Restarting :\n");
GfLogInfo(" Command : %s\n", _lstArgs.front().c_str());
// Restart the process, using same command line args.
// 1) The process executable path-name is the 1st arg left untouched.
GfLogInfo("Restarting :\n");
GfLogInfo(" Command : %s\n", _lstArgs.front().c_str());
// 2) Allocate and populate the args array (last arg must be a null pointer).
// TODO: Add an API for filtering the args (some might not be relevant for a restart).
GfLogInfo(" Args : ");
char** apszArgs = (char**)malloc(sizeof(char*) * (_lstArgs.size() + 1));
// 2) Allocate and populate the args array (last arg must be a null pointer).
// TODO: Add an API for filtering the args (some might not be relevant for a restart).
GfLogInfo(" Args : ");
char** apszArgs = (char**)malloc(sizeof(char*) * (_lstArgs.size() + 1));
unsigned nArgInd = 0;
std::list<std::string>::const_iterator itArg;
for (itArg = _lstArgs.begin(); itArg != _lstArgs.end(); itArg++)
{
unsigned nArgInd = 0;
std::list<std::string>::const_iterator itArg;
for (itArg = _lstArgs.begin(); itArg != _lstArgs.end(); itArg++)
{
#ifdef WIN32
// execvp will not automatically surround args with spaces inside with double quotes !
if (itArg->find(' ') != std::string::npos)
{
char pszArg[512];
snprintf(pszArg, sizeof(pszArg), "\"%s\"", itArg->c_str());
apszArgs[nArgInd] = strdup(pszArg);
}
else
apszArgs[nArgInd] = strdup(itArg->c_str());
// execvp will not automatically surround args with spaces inside with double quotes !
if (itArg->find(' ') != std::string::npos)
{
char pszArg[512];
snprintf(pszArg, sizeof(pszArg), "\"%s\"", itArg->c_str());
apszArgs[nArgInd] = strdup(pszArg);
}
else
apszArgs[nArgInd] = strdup(itArg->c_str());
GfLogInfo("%s ", apszArgs[nArgInd]);
GfLogInfo("%s ", apszArgs[nArgInd]);
#else
// execvp will automatically surround args with spaces inside with double quotes.
apszArgs[nArgInd] = strdup(itArg->c_str());
// execvp will automatically surround args with spaces inside with double quotes.
apszArgs[nArgInd] = strdup(itArg->c_str());
if (itArg->find(' ') != std::string::npos)
GfLogInfo("\"%s\" ", itArg->c_str());
else
GfLogInfo("%s ", itArg->c_str());
if (itArg->find(' ') != std::string::npos)
GfLogInfo("\"%s\" ", itArg->c_str());
else
GfLogInfo("%s ", itArg->c_str());
#endif
// Next arg.
nArgInd++;
}
apszArgs[nArgInd] = 0;
GfLogInfo("...\n\n");
// 3) Exec the command with its args (replacing current process).
const int retcode = execvp(_lstArgs.front().c_str(), apszArgs);
// Next arg.
nArgInd++;
}
apszArgs[nArgInd] = 0;
GfLogInfo("...\n\n");
// If the restart was successfull, we never get there ... But if it failed ...
GfLogError("Failed to restart (exit code %d, %s)\n", retcode, strerror(errno));
for (nArgInd = 0; apszArgs[nArgInd]; nArgInd++)
free(apszArgs[nArgInd]);
free(apszArgs);
exit(1);
// 3) Exec the command with its args (replacing current process).
const int retcode = execvp(_lstArgs.front().c_str(), apszArgs);
// If the restart was successfull, we never get there ... But if it failed ...
GfLogError("Failed to restart (exit code %d, %s)\n", retcode, strerror(errno));
for (nArgInd = 0; apszArgs[nArgInd]; nArgInd++)
free(apszArgs[nArgInd]);
free(apszArgs);
exit(1);
}
void GfApplication::printUsage(const char* pszErrMsg) const
{
if (pszErrMsg)
std::cout << std::endl << "Error: " << pszErrMsg << std::endl << std::endl;
std::cout << "Usage: " << _lstArgs.front() << " ..." << std::endl;
if (pszErrMsg)
std::cout << std::endl << "Error: " << pszErrMsg << std::endl << std::endl;
std::list<std::string>::const_iterator itSynLine = _optionsHelp.lstSyntaxLines.begin();
while (itSynLine != _optionsHelp.lstSyntaxLines.end())
{
std::cout << " " << *itSynLine << std::endl;
itSynLine++;
}
std::cout << "Usage: " << _lstArgs.front() << " ..." << std::endl;
std::list<std::string>::const_iterator itExplLine = _optionsHelp.lstExplainLines.begin();
while (itExplLine != _optionsHelp.lstExplainLines.end())
{
std::cout << " " << *itExplLine << std::endl;
itExplLine++;
}
std::list<std::string>::const_iterator itSynLine = _optionsHelp.lstSyntaxLines.begin();
while (itSynLine != _optionsHelp.lstSyntaxLines.end())
{
std::cout << " " << *itSynLine << std::endl;
itSynLine++;
}
std::list<std::string>::const_iterator itExplLine = _optionsHelp.lstExplainLines.begin();
while (itExplLine != _optionsHelp.lstExplainLines.end())
{
std::cout << " " << *itExplLine << std::endl;
itExplLine++;
}
}
bool GfApplication::parseOptions()
{
// Determine and store run-time install root dir.
GfInitInstallDir(_lstArgs.front().c_str());
// Determine and store run-time install root dir.
GfInitInstallDir(_lstArgs.front().c_str());
// Parse args, looking for registered options.
GfLogInfo("Parsing command line args (%d)\n", _lstArgs.size() - 1);
std::list<std::string>::const_iterator itArg = _lstArgs.begin();
for (itArg++; itArg != _lstArgs.end(); itArg++)
{
bool bArgEaten = false;
if (itArg->find('-') == 0)
{
// We've probably got an option flag : check this a bit more in depth.
std::list<Option>::iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
{
if (itOpt->strShortName == itArg->substr(1, std::string::npos)
|| itOpt->strLongName == itArg->substr(2, std::string::npos))
{
// We've got a registered option flag : check if there's a value arg or not.
if (itOpt->bHasValue)
{
const std::string strFlag(*itArg);
itArg++;
if (itArg != _lstArgs.end() // Some extra arg available ...
&& itArg->find('-') != 0) // ... and not an option flag :
{
itOpt->strValue = *itArg; // We've got the value.
GfLogInfo(" %s %s : option '%s'\n", strFlag.c_str(),
itArg->c_str(), itOpt->strLongName.c_str());
}
else
{
// Should have a value arg, but it's not there ... error !
printUsage();
return false;
}
}
else
{
GfLogInfo(" %s : option '%s'\n",
itArg->c_str(), itOpt->strLongName.c_str());
}
// Parse args, looking for registered options.
GfLogInfo("Parsing command line args (%d)\n", _lstArgs.size() - 1);
std::list<std::string>::const_iterator itArg = _lstArgs.begin();
for (itArg++; itArg != _lstArgs.end(); itArg++)
{
bool bArgEaten = false;
if (itArg->find('-') == 0)
{
// We've probably got an option flag : check this a bit more in depth.
std::list<Option>::iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
{
if (itOpt->strShortName == itArg->substr(1, std::string::npos)
|| itOpt->strLongName == itArg->substr(2, std::string::npos))
{
// We've got a registered option flag : check if there's a value arg or not.
if (itOpt->bHasValue)
{
const std::string strFlag(*itArg);
itArg++;
if (itArg != _lstArgs.end() // Some extra arg available ...
&& itArg->find('-') != 0) // ... and not an option flag :
{
itOpt->strValue = *itArg; // We've got the value.
GfLogInfo(" %s %s : option '%s'\n", strFlag.c_str(),
itArg->c_str(), itOpt->strLongName.c_str());
}
else
{
// Should have a value arg, but it's not there ... error !
printUsage();
return false;
}
}
else
{
GfLogInfo(" %s : option '%s'\n",
itArg->c_str(), itOpt->strLongName.c_str());
}
// Value or not, we've got an option, and we eat the arg(s) : done.
itOpt->bFound = true;
bArgEaten = true;
break;
}
}
}
// Value or not, we've got an option, and we eat the arg(s) : done.
itOpt->bFound = true;
bArgEaten = true;
break;
}
}
}
// Save any ignored arg in the "remaining" list.
if (!bArgEaten)
{
_vecRemArgs.push_back(*itArg);
GfLogInfo(" %s : not a registered option\n", itArg->c_str());
}
}
// Interpret the detected command line options.
const char *pszLocalDir = 0;
const char *pszLibDir = 0;
const char *pszDataDir = 0;
const char *pszBinDir = 0;
// Save any ignored arg in the "remaining" list.
if (!bArgEaten)
{
_vecRemArgs.push_back(*itArg);
GfLogInfo(" %s : not a registered option\n", itArg->c_str());
}
}
bool bTrueRandom = true;
// Interpret the detected command line options.
const char *pszLocalDir = 0;
const char *pszLibDir = 0;
const char *pszDataDir = 0;
const char *pszBinDir = 0;
std::list<Option>::const_iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
{
// Not found in the command line => ignore / default value.
if (!itOpt->bFound)
continue;
// Help about command line
if (itOpt->strLongName == "help")
{
printUsage();
return false;
}
// Version information
else if (itOpt->strLongName == "version")
{
std::cout << _strName << ' ' << _strVersion << std::endl;
return false;
}
// Local dir (root dir of the tree where user settings files are stored)
else if (itOpt->strLongName == "localdir")
{
pszLocalDir = GfSetLocalDir(itOpt->strValue.c_str());
}
// Libraries dir (root dir of the tree where loadable modules are installed)
else if (itOpt->strLongName == "libdir")
{
pszLibDir = GfSetLibDir(itOpt->strValue.c_str());
}
// Binaries dir (the dir where the game exe and DLLs are installed)
else if (itOpt->strLongName == "bindir")
{
pszBinDir = GfSetBinDir(itOpt->strValue.c_str());
}
// Data dir (root dir of the data tree)
else if (itOpt->strLongName == "datadir")
{
pszDataDir = GfSetDataDir(itOpt->strValue.c_str());
}
// Initialize random generator or not.
else if (itOpt->strLongName == "norandom")
{
bTrueRandom = false;
}
else
{
// If we get here, this is normal : the derived classes might have declared
// specific options that it'll parse itself later.
}
}
bool bTrueRandom = true;
// If any of the Speed-Dreams dirs not run-time specified / empty,
// use associated compile-time variable SD_XXDIR to get default value
if (!(pszLocalDir && strlen(pszLocalDir)))
pszLocalDir = GfSetLocalDir(SD_LOCALDIR);
if (!(pszLibDir && strlen(pszLibDir)))
pszLibDir = GfSetLibDir(SD_LIBDIR);
if (!(pszBinDir && strlen(pszBinDir)))
pszBinDir = GfSetBinDir(SD_BINDIR);
if (!(pszDataDir && strlen(pszDataDir)))
pszDataDir = GfSetDataDir(SD_DATADIR);
std::list<Option>::const_iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
{
// Not found in the command line => ignore / default value.
if (!itOpt->bFound)
continue;
// If the data dir. is not a run-time usable one, may be it's because we are running
// without installing : try and use the _source_ data dir (it _is_ run-time usable).
std::string strDataDirProof(pszDataDir);
// A run-time usable data dir has a "config/logging.xml" file inside.
strDataDirProof += LOGGING_CFG;
if (pszDataDir && strlen(pszDataDir) && !GfFileExists(strDataDirProof.c_str()))
{
GfLogTrace("Data dir. '%s' not run-time usable, trying source data dir.\n",
pszDataDir);
pszDataDir = GfSetDataDir(SD_DATADIR_SRC);
}
// Check if ALL the Speed-dreams dirs have a usable value, and exit if not.
if (!(pszLocalDir && strlen(pszLocalDir)) || !(pszLibDir && strlen(pszLibDir))
|| !(pszBinDir && strlen(pszBinDir)) || !(pszDataDir && strlen(pszDataDir)))
{
GfLogTrace("User settings dir. : '%s'\n", GfLocalDir());
GfLogTrace("Libraries dir. : '%s'\n", GfLibDir());
GfLogTrace("Binaries dir. : '%s'\n", GfBinDir());
GfLogTrace("Data dir. : '%s'\n", GfDataDir());
GfLogError("Could not start %s :"
" at least 1 of local/data/lib/bin dir is empty\n\n", _strName.c_str());
return false;
}
// Help about command line
if (itOpt->strLongName == "help")
{
printUsage();
return false;
}
// Version information
else if (itOpt->strLongName == "version")
{
std::cout << _strName << ' ' << _strVersion << std::endl;
return false;
}
// Local dir (root dir of the tree where user settings files are stored)
else if (itOpt->strLongName == "localdir")
{
pszLocalDir = GfSetLocalDir(itOpt->strValue.c_str());
}
// Libraries dir (root dir of the tree where loadable modules are installed)
else if (itOpt->strLongName == "libdir")
{
pszLibDir = GfSetLibDir(itOpt->strValue.c_str());
}
// Binaries dir (the dir where the game exe and DLLs are installed)
else if (itOpt->strLongName == "bindir")
{
pszBinDir = GfSetBinDir(itOpt->strValue.c_str());
}
// Data dir (root dir of the data tree)
else if (itOpt->strLongName == "datadir")
{
pszDataDir = GfSetDataDir(itOpt->strValue.c_str());
}
// Initialize random generator or not.
else if (itOpt->strLongName == "norandom")
{
bTrueRandom = false;
}
else
{
// If we get here, this is normal : the derived classes might have declared
// specific options that it'll parse itself later.
}
}
// Initialize random generator with "random" seed, or not (=> always same rand() sequence).
if (bTrueRandom)
{
GfLogInfo("Initializing random number generator for 'true randomness'\n");
srand((unsigned)time(0));
}
// Note: Never calling srand is equivalent to calling it once with seed=1.
else
{
GfLogInfo("Not initializing random number generator, for 'repeatable randomness'\n");
}
return true;
// If any of the Speed-Dreams dirs not run-time specified / empty,
// use associated compile-time variable SD_XXDIR to get default value
if (!(pszLocalDir && strlen(pszLocalDir)))
pszLocalDir = GfSetLocalDir(SD_LOCALDIR);
if (!(pszLibDir && strlen(pszLibDir)))
pszLibDir = GfSetLibDir(SD_LIBDIR);
if (!(pszBinDir && strlen(pszBinDir)))
pszBinDir = GfSetBinDir(SD_BINDIR);
if (!(pszDataDir && strlen(pszDataDir)))
pszDataDir = GfSetDataDir(SD_DATADIR);
// If the data dir. is not a run-time usable one, may be it's because we are running
// without installing : try and use the _source_ data dir (it _is_ run-time usable).
std::string strDataDirProof(pszDataDir);
// A run-time usable data dir has a "config/logging.xml" file inside.
strDataDirProof += LOGGING_CFG;
if (pszDataDir && strlen(pszDataDir) && !GfFileExists(strDataDirProof.c_str()))
{
GfLogTrace("Data dir. '%s' not run-time usable, trying source data dir.\n",
pszDataDir);
pszDataDir = GfSetDataDir(SD_DATADIR_SRC);
}
// Check if ALL the Speed-dreams dirs have a usable value, and exit if not.
if (!(pszLocalDir && strlen(pszLocalDir)) || !(pszLibDir && strlen(pszLibDir))
|| !(pszBinDir && strlen(pszBinDir)) || !(pszDataDir && strlen(pszDataDir)))
{
GfLogTrace("User settings dir. : '%s'\n", GfLocalDir());
GfLogTrace("Libraries dir. : '%s'\n", GfLibDir());
GfLogTrace("Binaries dir. : '%s'\n", GfBinDir());
GfLogTrace("Data dir. : '%s'\n", GfDataDir());
GfLogError("Could not start %s :"
" at least 1 of local/data/lib/bin dir is empty\n\n", _strName.c_str());
return false;
}
// Initialize random generator with "random" seed, or not (=> always same rand() sequence).
if (bTrueRandom)
{
GfLogInfo("Initializing random number generator for 'true randomness'\n");
srand((unsigned)time(0));
}
// Note: Never calling srand is equivalent to calling it once with seed=1.
else
{
GfLogInfo("Not initializing random number generator, for 'repeatable randomness'\n");
}
return true;
}
void GfApplication::registerOption(const std::string& strShortName,
const std::string& strLongName,
bool bHasValue)
const std::string& strLongName,
bool bHasValue)
{
// Check if no already registered option has same short or long name.
std::list<Option>::const_iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
{
try
{
if (itOpt->strShortName == strShortName)
{
GfLogError("Can't register option -%s/--%s "
"with same short name as -%s/--%s ; ignoring.\n",
strShortName.c_str(), strLongName.c_str(),
itOpt->strShortName.c_str(), itOpt->strLongName.c_str());
return;
}
else if (itOpt->strLongName == strLongName)
{
GfLogError("Can't register option -%s/--%s "
"with same long name as -%s/--%s ; ignoring.\n",
strShortName.c_str(), strLongName.c_str(),
itOpt->strShortName.c_str(), itOpt->strLongName.c_str());
return;
}
}
catch (std::bad_exception)
{
GfLogError("GfApplication::registerOption -%s",strShortName.c_str());
}
// Check if no already registered option has same short or long name.
std::list<Option>::const_iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
{
try
{
if (itOpt->strShortName == strShortName)
{
GfLogError("Can't register option -%s/--%s "
"with same short name as -%s/--%s ; ignoring.\n",
strShortName.c_str(), strLongName.c_str(),
itOpt->strShortName.c_str(), itOpt->strLongName.c_str());
return;
}
else if (itOpt->strLongName == strLongName)
{
GfLogError("Can't register option -%s/--%s "
"with same long name as -%s/--%s ; ignoring.\n",
strShortName.c_str(), strLongName.c_str(),
itOpt->strShortName.c_str(), itOpt->strLongName.c_str());
return;
}
}
catch (const std::bad_exception&)
{
GfLogError("GfApplication::registerOption -%s",strShortName.c_str());
}
}
}
// All's right : register.
_lstOptions.push_back(Option(strShortName, strLongName, bHasValue));
// All's right : register.
_lstOptions.push_back(Option(strShortName, strLongName, bHasValue));
}
void GfApplication::addOptionsHelpSyntaxLine(const std::string& strTextLine)
{
_optionsHelp.lstSyntaxLines.push_back(strTextLine);
_optionsHelp.lstSyntaxLines.push_back(strTextLine);
}
void GfApplication::addOptionsHelpExplainLine(const std::string& strTextLine)
{
_optionsHelp.lstExplainLines.push_back(strTextLine);
_optionsHelp.lstExplainLines.push_back(strTextLine);
}
bool GfApplication::hasOption(const std::string& strLongName) const
{
std::list<Option>::const_iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
if (itOpt->bFound && itOpt->strLongName == strLongName)
return true;
std::list<Option>::const_iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
if (itOpt->bFound && itOpt->strLongName == strLongName)
return true;
return false;
return false;
}
bool GfApplication::hasOption(const std::string& strLongName,
std::string& strValue) const
std::string& strValue) const
{
std::list<Option>::const_iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
if (itOpt->bFound && itOpt->strLongName == strLongName)
{
strValue = itOpt->strValue;
return true;
}
std::list<Option>::const_iterator itOpt;
for (itOpt = _lstOptions.begin(); itOpt != _lstOptions.end(); itOpt++)
if (itOpt->bFound && itOpt->strLongName == strLongName)
{
strValue = itOpt->strValue;
return true;
}
return false;
return false;
}
// bool GfApplication::hasUnregisteredOption(const std::string& strShortName,
@ -577,13 +577,13 @@ bool GfApplication::hasOption(const std::string& strLongName,
GfApplication::~GfApplication()
{
// Shutdown the gaming framework.
GfShutdown();
// Shutdown the gaming framework.
GfShutdown();
// Delete the event loop if any.
delete _pEventLoop;
_pEventLoop = 0;
// Delete the event loop if any.
delete _pEventLoop;
_pEventLoop = 0;
// Really shutdown the singleton.
_pSelf = 0;
// Really shutdown the singleton.
_pSelf = 0;
}