Skip to content

Commit

Permalink
Allow specifying startup options in config XML files.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jukka Jylänki committed Sep 25, 2011
1 parent 77c8fee commit 639c19e
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 49 deletions.
104 changes: 88 additions & 16 deletions src/Core/Framework/Framework.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#endif
#include <iostream>
#include <QDir>
#include <QDomDocument>

#include "MemoryLeakCheck.h"

Expand Down Expand Up @@ -114,6 +115,20 @@ Framework::Framework(int argc, char** argv) :
// Remember this Framework instance in a static pointer. Note that this does not help visibility for external DLL code linking to Framework.
instance = this;

// Remember all startup command line options.
// Skip argv[0], since it is the program name.
for(int i = 1; i < argc; ++i)
startupOptions << argv[i];

// Load command line options from each config XML file.
QStringList cmdLineParams = CommandLineParameters("--config");
if (cmdLineParams.size() == 0)
LoadStartupOptionsFromXML("plugins.xml");
foreach(const QString &config, cmdLineParams)
LoadStartupOptionsFromXML(config);

PrintStartupOptions();

// Api/Application name and version. Can be accessed via ApiVersionInfo() and ApplicationVersionInfo().
/// @note Modify these values when you are making a custom Tundra. Also the version needs to be changed here on releases.
apiVersionInfo = new ApiVersionInfo(2, 0, 0, 0);
Expand Down Expand Up @@ -175,6 +190,7 @@ Framework::Framework(int argc, char** argv) :
// Create core APIs
frame = new FrameAPI(this);
scene = new SceneAPI(this);
plugin = new PluginAPI(this);
asset = new AssetAPI(this, headless_);

QString assetCacheDir = Application::UserDataDirectory() + QDir::separator() + "assetcache";
Expand All @@ -188,7 +204,6 @@ Framework::Framework(int argc, char** argv) :
ui = new UiAPI(this);
audio = new AudioAPI(this, asset); // AudioAPI depends on the AssetAPI, so must be loaded after it.
input = new InputAPI(this);
plugin = new PluginAPI(this);
console = new ConsoleAPI(this);
console->RegisterCommand("exit", "Shuts down gracefully.", this, SLOT(Exit()));

Expand Down Expand Up @@ -418,17 +433,7 @@ ConfigAPI *Framework::Config() const
{
return config;
}
/*
ConnectionAPI *Framework::Connection() const
{
return connection;
}

ServerAPI *Framework::Server() const
{
return server;
}
*/
PluginAPI *Framework::Plugins() const
{
return plugin;
Expand Down Expand Up @@ -483,20 +488,87 @@ bool Framework::RegisterDynamicObject(QString name, QObject *object)
return true;
}

QString LookupRelativePath(QString path);

void Framework::LoadStartupOptionsFromXML(QString configurationFile)
{
configurationFile = LookupRelativePath(configurationFile);

QDomDocument doc("plugins");
QFile file(configurationFile);
if (!file.open(QIODevice::ReadOnly))
{
LogError("Framework::LoadStartupOptionsFromXML: Failed to open file \"" + configurationFile + "\"!");
return;
}
if (!doc.setContent(&file))
{
LogError("Framework::LoadStartupOptionsFromXML: Failed to parse XML file \"" + configurationFile + "\"!");
file.close();
return;
}
file.close();

QDomElement docElem = doc.documentElement();

QDomNode n = docElem.firstChild();
while(!n.isNull())
{
QDomElement e = n.toElement(); // try to convert the node to an element.
if (!e.isNull() && e.tagName() == "option" && e.hasAttribute("name"))
{
#ifdef _DEBUG
QString build = "debug";
#else
QString build = "release";
#endif
if (e.hasAttribute("build") && build.compare(e.attribute("build"), Qt::CaseInsensitive) != 0)
continue; // The command line parameter was specified to be included only in the given build (debug/release), but we are not running that build.

/// \bug Appended in this way, the parsing is not perfect (one configuration can continue from the other)
startupOptions << e.attribute("name");

if (e.hasAttribute("value"))
startupOptions << e.attribute("value");
}
n = n.nextSibling();
}
}

bool Framework::HasCommandLineParameter(const QString &value) const
{
for(int i = 0; i < argc_; ++i)
if (QString(argv_[i]) == value)
for(int i = 0; i < startupOptions.size(); ++i)
if (!startupOptions[i].compare(value, Qt::CaseInsensitive))
return true;
return false;
}

QStringList Framework::CommandLineParameters(const QString &key) const
{
QStringList ret;
for(int i = 0; i < argc_; ++i)
if (QString(argv_[i]) == key && i+1 < argc_ && !QString(argv_[i+1]).startsWith("--"))
ret.append(argv_[++i]);
for(int i = 0; i+1 < startupOptions.size(); ++i)
if (!startupOptions[i].compare(key, Qt::CaseInsensitive) && !startupOptions[i+1].startsWith("--"))
ret.append(startupOptions[++i]);
return ret;
}

void Framework::PrintStartupOptions()
{
int i = 0;
LogInfo("Startup options:");
while(i < startupOptions.size())
{
if (!startupOptions[i].startsWith("--"))
LogWarning("Warning: Orphaned startup option parameter value \"" + startupOptions[i] + "\" specified!");
if (i+1 < startupOptions.size() && !startupOptions[i+1].startsWith("--"))
{
LogInfo(" '" + startupOptions[i] + "' '" + startupOptions[i+1] + "'");
i += 2;
}
else
{
LogInfo(" '" + startupOptions[i] + "'");
++i;
}
}
}
21 changes: 13 additions & 8 deletions src/Core/Framework/Framework.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,6 @@ public slots:
/// Returns core API Config object.
ConfigAPI *Config() const;

/// Returns core API Connection object.
// ConnectionAPI *Connection() const;

/// Returns core API Server object if we're acting as a network server.
// ServerAPI *Server() const;

PluginAPI *Plugins() const;

void RegisterRenderer(IRenderer *renderer);
Expand All @@ -115,9 +109,11 @@ public slots:
IRenderer *Renderer() const;

/// Returns Tundra API version info object.
///\todo Delete/simplify.
ApiVersionInfo *ApiVersion() const;

/// Returns Tundra application version info object.
///\todo Delete/simplify.
ApplicationVersionInfo *ApplicationVersion() const;

/// Returns the global Framework instance.
Expand Down Expand Up @@ -156,6 +152,9 @@ public slots:
@param key Key with possible prefixes. */
QStringList CommandLineParameters(const QString &key) const;

/// Prints to console all the used startup options.
void PrintStartupOptions();

private:
Q_DISABLE_COPY(Framework)

Expand All @@ -176,14 +175,20 @@ public slots:
ConfigAPI *config; ///< The Config API.
PluginAPI *plugin;
IRenderer *renderer;
// ConnectionAPI *connection; ///< The Connection API.
// ServerAPI *server; ///< The Server API, null if we're not operating as a server.

/// Appends all found startup options from the given file to the startupOptions member.
void LoadStartupOptionsFromXML(QString configurationFile);

/// Stores all command line parameters and startup options specified in the Config XML files.
QStringList startupOptions;

/// The Tundra API version info of this build. May differ from the end user
/// application version of the default distribution, i.e. app may change when api stays same.
///\todo Delete/simplify.
ApiVersionInfo *apiVersionInfo;

/// The Tundra application version info for this build.
///\todo Delete/simplify.
ApplicationVersionInfo *applicationVersionInfo;

/// Framework owns the memory of all the modules in the system. These are freed when Framework is exiting.
Expand Down
26 changes: 1 addition & 25 deletions src/Core/Tundra/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,33 +96,9 @@ int run(int argc, char **argv)
int return_value = EXIT_SUCCESS;

// Initilizing prints
LogInfo("Starting up Tundra");
LogInfo("Starting up Tundra.");
LogInfo("* Working directory: " + QDir::currentPath());

// Parse and print command arguments
QStringList arguments;
for(int i = 1; i < argc; ++i)
arguments << argv[i];
QString fullArguments = arguments.join(" ");
if (fullArguments.contains("--"))
{
LogInfo("* Command arguments:");
int iStart = fullArguments.indexOf("--");
while (iStart != -1)
{
int iStop = fullArguments.indexOf("--", iStart+1);
QString subStr = fullArguments.mid(iStart, iStop-iStart);
if (!subStr.isEmpty() && !subStr.isNull())
{
LogInfo(" " + subStr);
iStart = fullArguments.indexOf("--", iStart+1);
}
else
iStart = -1;
}
}
LogInfo(""); // endl

// Create application object
#if !defined(_DEBUG) || !defined (_MSC_VER)
try
Expand Down

0 comments on commit 639c19e

Please sign in to comment.