Skip to content

Commit

Permalink
Refactor|Games: ClientApp owns the Games collection
Browse files Browse the repository at this point in the history
On the server, it still exists as a static variable in dd_main as
there is no ServerApp yet.
  • Loading branch information
skyjake committed May 21, 2013
1 parent aff1a68 commit ab1b19b
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 45 deletions.
3 changes: 3 additions & 0 deletions doomsday/client/include/clientapp.h
Expand Up @@ -25,6 +25,7 @@
#include "ui/inputsystem.h"
#include "ui/windowsystem.h"
#include "ui/widgets/widgetactions.h"
#include "Games"

/**
* The client application.
Expand All @@ -44,12 +45,14 @@ class ClientApp : public de::GuiApp
void postFrame();

public:
static bool haveApp();
static ClientApp &app();
static ServerLink &serverLink();
static InputSystem &inputSystem();
static WindowSystem &windowSystem();
static WidgetActions &widgetActions();
static de::GLShaderBank &glShaderBank();
static de::Games &games();

private:
DENG2_PRIVATE(d)
Expand Down
11 changes: 11 additions & 0 deletions doomsday/client/src/clientapp.cpp
Expand Up @@ -73,6 +73,7 @@ DENG2_PIMPL(ClientApp)
WindowSystem *winSys;
ServerLink *svLink;
GLShaderBank shaderBank;
Games games;

Instance(Public *i)
: Base(i),
Expand Down Expand Up @@ -216,6 +217,11 @@ void ClientApp::postFrame()
loop().resume();
}

bool ClientApp::haveApp()
{
return clientAppSingleton != 0;
}

ClientApp &ClientApp::app()
{
DENG2_ASSERT(clientAppSingleton != 0);
Expand Down Expand Up @@ -252,3 +258,8 @@ GLShaderBank &ClientApp::glShaderBank()
{
return app().d->shaderBank;
}

Games &ClientApp::games()
{
return app().d->games;
}
90 changes: 45 additions & 45 deletions doomsday/client/src/dd_main.cpp
Expand Up @@ -35,6 +35,7 @@
#include <de/NativePath>
#include <de/binangle.h>
#ifdef __CLIENT__
# include "clientapp.h"
# include <de/DisplayMode>
#endif

Expand Down Expand Up @@ -159,9 +160,6 @@ static size_t numSessionResourceFileList;
extern GETGAMEAPI GetGameAPI;
#endif

// The app's Game collection.
static Games *games;

// The app's MapArchive.
static MapArchive mapArchive;

Expand Down Expand Up @@ -716,15 +714,16 @@ static void destroyPathList(ddstring_t*** list, size_t* listSize)

boolean App_GameLoaded()
{
if(!games) return false;
return !isNullGame(games->current());
#ifdef __CLIENT__
if(!ClientApp::haveApp()) return false;
#endif
return !isNullGame(App_Games().current());
}

void DD_DestroyGames()
{
destroyPathList(&sessionResourceFileList, &numSessionResourceFileList);

delete games;
App_Games().clear();
}

/**
Expand Down Expand Up @@ -931,7 +930,7 @@ static int DD_LoadGameStartupResourcesWorker(void* parameters)
*/
Con_Message("Loading game resources%s", verbose >= 1? ":" : "...");

de::Game::Manifests const& gameManifests = games->current().manifests();
de::Game::Manifests const& gameManifests = App_Games().current().manifests();
int const numPackages = gameManifests.count(RC_PACKAGE);
int packageIdx = 0;
for(de::Game::Manifests::const_iterator i = gameManifests.find(RC_PACKAGE);
Expand Down Expand Up @@ -1185,10 +1184,10 @@ static int DD_ActivateGameWorker(void* parameters)
// Now that resources have been located we can begin to initialize the game.
if(App_GameLoaded() && gx.PreInit)
{
DENG_ASSERT(games->current().pluginId() != 0);
DENG_ASSERT(App_Games().current().pluginId() != 0);

DD_SetActivePluginId(games->current().pluginId());
gx.PreInit(games->id(games->current()));
DD_SetActivePluginId(App_Games().current().pluginId());
gx.PreInit(App_Games().id(App_Games().current()));
DD_SetActivePluginId(0);
}

Expand All @@ -1209,7 +1208,7 @@ static int DD_ActivateGameWorker(void* parameters)
}
else
{
configFileName = games->current().mainConfig();
configFileName = App_Games().current().mainConfig();
}

Con_Message("Parsing primary config \"%s\"...", F_PrettyPath(Str_Text(configFileName)));
Expand All @@ -1225,7 +1224,7 @@ static int DD_ActivateGameWorker(void* parameters)
B_BindGameDefaults();

// Read bindings for this game and merge with the working set.
Con_ParseCommands2(Str_Text(games->current().bindingConfig()), CPCF_ALLOW_SAVE_BINDINGS);
Con_ParseCommands2(Str_Text(App_Games().current().bindingConfig()), CPCF_ALLOW_SAVE_BINDINGS);
}
#endif

Expand Down Expand Up @@ -1266,7 +1265,7 @@ static int DD_ActivateGameWorker(void* parameters)

if(gx.PostInit)
{
DD_SetActivePluginId(games->current().pluginId());
DD_SetActivePluginId(App_Games().current().pluginId());
gx.PostInit();
DD_SetActivePluginId(0);
}
Expand All @@ -1282,8 +1281,15 @@ static int DD_ActivateGameWorker(void* parameters)

de::Games &App_Games()
{
DENG2_ASSERT(games != 0);
return *games;
#ifdef __CLIENT__
return ClientApp::games();
#endif

#ifdef __SERVER__
/// @todo Add a ServerApp class, move this there.
static Games serverGames;
return serverGames;
#endif
}

de::Game &App_CurrentGame()
Expand Down Expand Up @@ -1314,7 +1320,7 @@ boolean DD_GameInfo(GameInfo *info)

if(App_GameLoaded())
{
populateGameInfo(*info, games->current());
populateGameInfo(*info, App_Games().current());
return true;
}

Expand All @@ -1328,12 +1334,11 @@ boolean DD_GameInfo(GameInfo *info)
void DD_AddGameResource(gameid_t gameId, resourceclassid_t classId, int rflags,
char const *names, void *params)
{
if(!games) Con_Error("DD_AddGameResource: Game collection not yet initialized.");
if(!VALID_RESOURCECLASSID(classId)) Con_Error("DD_AddGameResource: Unknown resource class %i.", (int)classId);
if(!names || !names[0]) Con_Error("DD_AddGameResource: Invalid name argument.");

// Construct and attach the new resource record.
de::Game &game = games->byId(gameId);
de::Game &game = App_Games().byId(gameId);
ResourceManifest *manifest = new ResourceManifest(classId, rflags);
game.addManifest(*manifest);

Expand Down Expand Up @@ -1367,10 +1372,9 @@ gameid_t DD_DefineGame(GameDef const *def)
}

// Game mode identity keys must be unique. Ensure that is the case.
DENG_ASSERT(games);
try
{
/*de::Game& game =*/ games->byIdentityKey(def->identityKey);
/*de::Game& game =*/ App_Games().byIdentityKey(def->identityKey);
#if _DEBUG
Con_Message("Warning: DD_DefineGame: Failed adding game \"%s\", identity key '%s' already in use, ignoring.", def->defaultTitle, def->identityKey);
#endif
Expand All @@ -1384,17 +1388,16 @@ gameid_t DD_DefineGame(GameDef const *def)

// Add this game to our records.
game->setPluginId(DD_ActivePluginId());
games->add(*game);
return games->id(*game);
App_Games().add(*game);
return App_Games().id(*game);
}

#undef DD_GameIdForKey
gameid_t DD_GameIdForKey(char const *identityKey)
{
DENG_ASSERT(games);
try
{
return games->id(games->byIdentityKey(identityKey));
return App_Games().id(App_Games().byIdentityKey(identityKey));
}
catch(Games::NotFoundError const &)
{
Expand Down Expand Up @@ -1518,15 +1521,15 @@ bool DD_ChangeGame(de::Game& game, bool allowReload = false)
Con_ClearDatabases();

{ // Tell the plugin it is being unloaded.
void* unloader = DD_FindEntryPoint(games->current().pluginId(), "DP_Unload");
void* unloader = DD_FindEntryPoint(App_Games().current().pluginId(), "DP_Unload");
DEBUG_Message(("DD_ChangeGame: Calling DP_Unload (%p)\n", unloader));
DD_SetActivePluginId(games->current().pluginId());
DD_SetActivePluginId(App_Games().current().pluginId());
if(unloader) ((pluginfunc_t)unloader)();
DD_SetActivePluginId(0);
}

// The current game is now the special "null-game".
games->setCurrent(games->nullGame());
App_Games().setCurrent(App_Games().nullGame());

Con_InitDatabases();
DD_Register();
Expand Down Expand Up @@ -1598,7 +1601,7 @@ bool DD_ChangeGame(de::Game& game, bool allowReload = false)
}

// This is now the current game.
games->setCurrent(game);
App_Games().setCurrent(game);

#ifdef __CLIENT__
DD_ComposeMainWindowTitle(buf);
Expand Down Expand Up @@ -1639,9 +1642,9 @@ bool DD_ChangeGame(de::Game& game, bool allowReload = false)
{
// Tell the plugin it is being loaded.
/// @todo Must this be done in the main thread?
void* loader = DD_FindEntryPoint(games->current().pluginId(), "DP_Load");
void* loader = DD_FindEntryPoint(App_Games().current().pluginId(), "DP_Load");
DEBUG_Message(("DD_ChangeGame: Calling DP_Load (%p)\n", loader));
DD_SetActivePluginId(games->current().pluginId());
DD_SetActivePluginId(App_Games().current().pluginId());
if(loader) ((pluginfunc_t)loader)();
DD_SetActivePluginId(0);
}
Expand All @@ -1663,7 +1666,7 @@ bool DD_ChangeGame(de::Game& game, bool allowReload = false)

if(App_GameLoaded())
{
de::Game::printBanner(games->current());
de::Game::printBanner(App_Games().current());
}
else
{
Expand Down Expand Up @@ -1718,7 +1721,7 @@ de::Game* DD_AutoselectGame(void)
char const* identityKey = CommandLine_Next();
try
{
de::Game& game = games->byIdentityKey(identityKey);
de::Game& game = App_Games().byIdentityKey(identityKey);
if(game.allStartupFilesFound())
{
return &game;
Expand All @@ -1729,9 +1732,9 @@ de::Game* DD_AutoselectGame(void)
}

// If but one lonely game; select it.
if(games->numPlayable() == 1)
if(App_Games().numPlayable() == 1)
{
return games->firstPlayable();
return App_Games().firstPlayable();
}

// We don't know what to do.
Expand All @@ -1757,9 +1760,6 @@ int DD_EarlyInit()
// Register the engine's console commands and variables.
DD_Register();

// Instantiate the Games collection.
games = new Games();

return true;
}

Expand Down Expand Up @@ -1898,7 +1898,7 @@ boolean DD_Init(void)

// Try to locate all required data files for all registered games.
Con_InitProgress2(200, .25f, 1); // Second half.
games->locateAllResources();
App_Games().locateAllResources();

// Attempt automatic game selection.
if(!CommandLine_Exists("-noautoselect") || isDedicated)
Expand Down Expand Up @@ -2742,7 +2742,7 @@ D_CMD(Load)
// Are we loading a game?
try
{
Game &game = games->byIdentityKey(Str_Text(searchPath));
Game &game = App_Games().byIdentityKey(Str_Text(searchPath));
if(!game.allStartupFilesFound())
{
Con_Message("Failed to locate all required startup resources:");
Expand Down Expand Up @@ -2817,7 +2817,7 @@ static bool tryUnloadFile(de::Uri const& search)
QByteArray pathUtf8 = NativePath(foundFileUri.asText()).pretty().toUtf8();

// Do not attempt to unload a resource required by the current game.
if(games->current().isRequiredFile(file))
if(App_Games().current().isRequiredFile(file))
{
Con_Message("\"%s\" is required by the current game.\n"
"Required game files cannot be unloaded in isolation.",
Expand Down Expand Up @@ -2850,7 +2850,7 @@ D_CMD(Unload)
Con_Message("There is no game currently loaded.");
return true;
}
return DD_ChangeGame(games->nullGame());
return DD_ChangeGame(App_Games().nullGame());
}

AutoStr *searchPath = AutoStr_NewStd();
Expand All @@ -2872,10 +2872,10 @@ D_CMD(Unload)
{
try
{
Game &game = games->byIdentityKey(Str_Text(searchPath));
Game &game = App_Games().byIdentityKey(Str_Text(searchPath));
if(App_GameLoaded())
{
return DD_ChangeGame(games->nullGame());
return DD_ChangeGame(App_Games().nullGame());
}

Con_Message("%s is not currently loaded.", Str_Text(game.identityKey()));
Expand Down Expand Up @@ -2930,7 +2930,7 @@ D_CMD(ReloadGame)
Con_Message("No game is presently loaded.");
return true;
}
DD_ChangeGame(games->current(), true/* allow reload */);
DD_ChangeGame(App_Games().current(), true/* allow reload */);
return true;
}

Expand Down

0 comments on commit ab1b19b

Please sign in to comment.