Skip to content

Commit

Permalink
Refactor: Continued splitting up App_ChangeGame()
Browse files Browse the repository at this point in the history
Setting up virtual path mappings belongs in libdoomsday.
Console registration is now initiated by DoomsdayApp via an audience.

All the code for tearing down subsystem/engine state is now gone
from App_ChangeGame(). Next up: loading the new game.
  • Loading branch information
skyjake committed Jan 22, 2016
1 parent e227166 commit de07004
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 69 deletions.
3 changes: 2 additions & 1 deletion doomsday/apps/client/include/clientapp.h
Expand Up @@ -103,7 +103,8 @@ public slots:
void endNativeUIMode();

protected:
void aboutToChangeGame(Game const &upcomingGame) override;
void unloadGame(Game const &upcomingGame) override;
void makeGameCurrent(Game &newGame) override;
void reset() override;

private:
Expand Down
2 changes: 2 additions & 0 deletions doomsday/apps/client/include/dd_main.h
Expand Up @@ -48,6 +48,8 @@ extern de::dint symbolicEchoMode;
de::dint DD_EarlyInit();
void DD_FinishInitializationAfterWindowReady();

void DD_ConsoleRegister();

/**
* Returns @c true if shutdown is in progress.
*/
Expand Down
30 changes: 24 additions & 6 deletions doomsday/apps/client/src/clientapp.cpp
Expand Up @@ -56,6 +56,7 @@
#include "gl/gl_main.h"
#include "gl/gl_texmanager.h"
#include "gl/gl_defer.h"
#include "gl/svg.h"

#include "world/map.h"
#include "world/contact.h"
Expand Down Expand Up @@ -129,6 +130,7 @@ DENG2_PIMPL(ClientApp)
, DENG2_OBSERVES(Games, Progress)
, DENG2_OBSERVES(DoomsdayApp, GameChange)
, DENG2_OBSERVES(DoomsdayApp, GameUnload)
, DENG2_OBSERVES(DoomsdayApp, ConsoleRegistration)
{
Binder binder;
QScopedPointer<Updater> updater;
Expand Down Expand Up @@ -226,13 +228,15 @@ DENG2_PIMPL(ClientApp)
DoomsdayApp::plugins().audienceForNotification() += this;
self.audienceForGameChange() += this;
self.audienceForGameUnload() += this;
self.audienceForConsoleRegistration() += this;
self.games().audienceForProgress() += this;
}

~Instance()
{
self.audienceForGameChange() -= this;
self.audienceForGameUnload() -= this;
self.audienceForConsoleRegistration() -= this;

try
{
Expand Down Expand Up @@ -310,6 +314,11 @@ DENG2_PIMPL(ClientApp)
Con_SetProgress(progress);
}

void consoleRegistration()
{
DD_ConsoleRegister();
}

void aboutToUnloadGame(Game const &/*gameBeingUnloaded*/)
{
DENG_ASSERT(ClientWindow::mainExists());
Expand All @@ -328,9 +337,10 @@ DENG2_PIMPL(ClientApp)
GL_LoadLightingSystemTextures();
GL_LoadFlareTextures();
Rend_ParticleLoadSystemTextures();

GL_ResetViewEffects();

infineSystem().reset();

if(App_GameLoaded())
{
// Write cvars and bindings to .cfg files.
Expand Down Expand Up @@ -756,9 +766,9 @@ void ClientApp::endNativeUIMode()
#endif
}

void ClientApp::aboutToChangeGame(Game const &upcomingGame)
void ClientApp::unloadGame(Game const &upcomingGame)
{
DoomsdayApp::aboutToChangeGame(upcomingGame);
DoomsdayApp::unloadGame(upcomingGame);

// Game has been set to null, update window.
ClientWindow::main().setWindowTitle(DD_ComposeMainWindowTitle());
Expand All @@ -775,16 +785,24 @@ void ClientApp::aboutToChangeGame(Game const &upcomingGame)
}
}

d->inputSys->initAllDevices();
R_InitViewWindow();
R_InitSvgs();
}

infineSystem().reset();
void ClientApp::makeGameCurrent(Game &newGame)
{
DoomsdayApp::makeGameCurrent(newGame);

// Game has been changed, update window.
ClientWindow::main().setWindowTitle(DD_ComposeMainWindowTitle());
}

void ClientApp::reset()
{
DoomsdayApp::reset();


if(App_GameLoaded())
{
d->inputSys->initAllDevices();
}
}
66 changes: 14 additions & 52 deletions doomsday/apps/client/src/dd_main.cpp
Expand Up @@ -166,8 +166,6 @@ class WadFileType : public de::NativeFileType
}
};

static void consoleRegister();
static void initPathMappings();
static dint DD_StartupWorker(void *context);
static dint DD_DummyWorker(void *context);
static void DD_AutoLoad();
Expand Down Expand Up @@ -808,7 +806,7 @@ static dint DD_LoadGameStartupResourcesWorker(void *context)

// Reset file Ids so previously seen files can be processed again.
App_FileSystem().resetFileIds();
initPathMappings();
FS_InitVirtualPathMappings();
App_FileSystem().resetAllSchemes();

if(parms.initiatedBusyMode)
Expand Down Expand Up @@ -930,7 +928,7 @@ static dint DD_LoadAddonResourcesWorker(void *context)
Con_SetProgress(180);
}

initPathLumpMappings();
FS_InitPathLumpMappings();

// Re-initialize the resource locator as there are now new resources to be found
// on existing search paths (probably that is).
Expand Down Expand Up @@ -1135,53 +1133,17 @@ bool App_ChangeGame(Game &game, bool allowReload)
isReload = true;
}

// The current game will be gone very soon.
// The current game now be unloaded.
DENG2_FOR_EACH_OBSERVER(DoomsdayApp::GameUnloadAudience, i,
DoomsdayApp::app().audienceForGameUnload())
{
i->aboutToUnloadGame(DoomsdayApp::game());
}

// Notify about which game will be loaded.
DoomsdayApp::app().aboutToChangeGame(game);
DoomsdayApp::app().unloadGame(game);

// If a game is presently loaded; unload it.
if(App_GameLoaded())
{
/// @todo Use an audience? -jk
consoleRegister();
}

if(!game.isNull())
{
LOG_MSG("Loading game '%s'...") << game.id();
}
else if(!isReload)
{
LOG_MSG("Unloaded game");
}

Library_ReleaseGames();

if(!DD_IsShuttingDown())
{
// Re-initialize subsystems needed even when in ringzero.
if(!DoomsdayApp::plugins().exchangeGameEntryPoints(game.pluginId()))
{
LOG_WARNING("Game plugin for '%s' is invalid") << game.id();
LOGDEV_WARNING("Failed exchanging entrypoints with plugin %i")
<< dint(game.pluginId());
return false;
}
}

// This is now the current game.
DoomsdayApp::setGame(game);
Session::profile().gameId = game.id();

#ifdef __CLIENT__
ClientWindow::main().setWindowTitle(DD_ComposeMainWindowTitle());
#endif
// Do the switch.
DoomsdayApp::app().makeGameCurrent(game);

/*
* If we aren't shutting down then we are either loading a game or switching
Expand Down Expand Up @@ -1322,7 +1284,7 @@ dint DD_EarlyInit()
Con_InitDatabases();

// Register the engine's console commands and variables.
consoleRegister();
DD_ConsoleRegister();

return true;
}
Expand Down Expand Up @@ -1477,7 +1439,7 @@ static void initialize()
#endif
}

initPathLumpMappings();
FS_InitPathLumpMappings();

// Re-initialize the filesystem subspace schemes as there are now new
// resources to be found on existing search paths (probably that is).
Expand Down Expand Up @@ -1580,8 +1542,8 @@ static void initialize()
// Lets get most of everything else initialized.
// Reset file IDs so previously seen files can be processed again.
App_FileSystem().resetFileIds();
initPathLumpMappings();
initPathMappings();
FS_InitPathLumpMappings();
FS_InitVirtualPathMappings();
App_FileSystem().resetAllSchemes();

App_ResourceSystem().initTextures();
Expand Down Expand Up @@ -1668,7 +1630,7 @@ static dint DD_StartupWorker(void * /*context*/)
LOG_WARNING("User directory not found (check -userdir)");
}

initPathMappings();
FS_InitVirtualPathMappings();
App_FileSystem().resetAllSchemes();

Con_SetProgress(40);
Expand Down Expand Up @@ -1856,8 +1818,8 @@ void DD_UpdateEngineState()
//App_FileSystem().resetFileIds();

// Update the dir/WAD translations.
initPathLumpMappings();
initPathMappings();
FS_InitPathLumpMappings();
FS_InitVirtualPathMappings();
// Re-build the filesystem subspace schemes as there may be new resources to be found.
App_FileSystem().resetAllSchemes();

Expand Down Expand Up @@ -2749,7 +2711,7 @@ D_CMD(Clear)
}
#endif

static void consoleRegister()
void DD_ConsoleRegister()
{
C_VAR_CHARPTR("file-startup", &startupFiles, 0, 0, 0);

Expand Down
4 changes: 2 additions & 2 deletions doomsday/apps/client/src/ui/controllerpresets.cpp
Expand Up @@ -118,14 +118,14 @@ DENG2_PIMPL_NOREF(ControllerPresets)

void currentGameChanged(Game const &newGame)
{
String const currentScheme = CVar_String(presetCVar());

DENG2_ASSERT(deviceId == IDEV_JOY1); /// @todo Expand for other devices as needed. -jk

// When loading a game, automatically apply the control scheme matching
// the connected game controller (unless a specific scheme is already set).
if(!newGame.isNull() && !Joystick_Name().isEmpty())
{
String const currentScheme = CVar_String(presetCVar());

if(auto const *gamepad = findMatching(Joystick_Name()))
{
if(currentScheme.isEmpty())
Expand Down
11 changes: 9 additions & 2 deletions doomsday/apps/libdoomsday/include/doomsday/doomsdayapp.h
Expand Up @@ -52,6 +52,11 @@ class LIBDOOMSDAY_PUBLIC DoomsdayApp
*/
DENG2_DEFINE_AUDIENCE2(GameChange, void currentGameChanged(Game const &newGame))

/**
* Notified when console variables and commands should be registered.
*/
DENG2_DEFINE_AUDIENCE2(ConsoleRegistration, void consoleRegistration())

public:
DoomsdayApp(Players::Constructor playerConstructor);

Expand Down Expand Up @@ -99,14 +104,16 @@ class LIBDOOMSDAY_PUBLIC DoomsdayApp
*/
static Game &game();

//protected:
//protected: // TODO: after changeGame() is moved here, make protected again
/**
* Called just before a game change is about to begin. The GameUnload
* audience has already been notified.
*
* @param upcomingGame Upcoming game that we will be changing to.
*/
virtual void aboutToChangeGame(Game const &upcomingGame);
virtual void unloadGame(Game const &upcomingGame);

virtual void makeGameCurrent(Game &newGame);

/**
* Clears all allocated resources and subsystems. This is called when
Expand Down
39 changes: 38 additions & 1 deletion doomsday/apps/libdoomsday/src/doomsdayapp.cpp
Expand Up @@ -23,8 +23,10 @@
#include "doomsday/filesys/fs_util.h"
#include "doomsday/resource/resources.h"
#include "doomsday/resource/bundles.h"
#include "doomsday/filesys/fs_main.h"
#include "doomsday/filesys/datafile.h"
#include "doomsday/filesys/datafolder.h"
#include "doomsday/filesys/virtualmappings.h"
#include "doomsday/paths.h"
#include "doomsday/world/world.h"
#include "doomsday/world/entitydef.h"
Expand Down Expand Up @@ -329,10 +331,12 @@ DENG2_PIMPL_NOREF(DoomsdayApp)

DENG2_PIMPL_AUDIENCE(GameUnload)
DENG2_PIMPL_AUDIENCE(GameChange)
DENG2_PIMPL_AUDIENCE(ConsoleRegistration)
};

DENG2_AUDIENCE_METHOD(DoomsdayApp, GameUnload)
DENG2_AUDIENCE_METHOD(DoomsdayApp, GameChange)
DENG2_AUDIENCE_METHOD(DoomsdayApp, ConsoleRegistration)

DoomsdayApp::DoomsdayApp(Players::Constructor playerConstructor)
: d(new Instance(playerConstructor))
Expand Down Expand Up @@ -473,12 +477,14 @@ Game &DoomsdayApp::game()
return *app().d->currentGame;
}

void DoomsdayApp::aboutToChangeGame(Game const &)
void DoomsdayApp::unloadGame(Game const &)
{
auto &gx = plugins().gameExports();

if(App_GameLoaded())
{
LOG_MSG("Unloading game...");

if(gx.Shutdown)
{
gx.Shutdown();
Expand Down Expand Up @@ -531,15 +537,46 @@ void DoomsdayApp::reset()

P_ShutdownMapEntityDefs();

// Reinitialize the console.
Con_ClearDatabases();
Con_InitDatabases();
DENG2_FOR_AUDIENCE2(ConsoleRegistration, i)
{
i->consoleRegistration();
}
}

void DoomsdayApp::setGame(Game &game)
{
app().d->currentGame = &game;
}

void DoomsdayApp::makeGameCurrent(Game &newGame)
{
if(!newGame.isNull())
{
LOG_MSG("Loading game '%s'...") << newGame.id();
}

Library_ReleaseGames();

//if(!DD_IsShuttingDown())
{
// Re-initialize subsystems needed even when in ringzero.
if(!plugins().exchangeGameEntryPoints(newGame.pluginId()))
{
LOG_WARNING("Game plugin for '%s' is invalid") << newGame.id();
LOGDEV_WARNING("Failed exchanging entrypoints with plugin %i")
<< dint(newGame.pluginId());
return false;
}
}

// This is now the current game.
setGame(newGame);
Session::profile().gameId = newGame.id();
}

bool App_GameLoaded()
{
return App::appExists() && !DoomsdayApp::currentGame().isNull();
Expand Down

0 comments on commit de07004

Please sign in to comment.