Skip to content

Commit

Permalink
Refactor: Continued splitting up App_ChangeGame()
Browse files Browse the repository at this point in the history
Operations mostly related to clearing/reseting application and
subsystem state when game is being unloaded.

Added virtualmappings.cpp with code from dd_main.cpp for setting up
virtual mappings (including -vdmap).
  • Loading branch information
skyjake committed Jan 22, 2016
1 parent 959c46b commit afd77d6
Show file tree
Hide file tree
Showing 15 changed files with 289 additions and 225 deletions.
7 changes: 2 additions & 5 deletions doomsday/apps/client/include/audio/system.h
Expand Up @@ -14,7 +14,7 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
* http://www.gnu.org/licenses</small>
*/

#ifndef CLIENT_AUDIO_SYSTEM_H
Expand Down Expand Up @@ -220,7 +220,7 @@ class System : public de::System
* SFX playback is @em not available.
*/
audiointerface_sfx_generic_t *sfx() const;

/**
* Returns the currently active, primary CD playback interface. @c nullptr is returned
* if CD playback is @em not available.
Expand All @@ -243,9 +243,6 @@ class System : public de::System
void worldMapChanged();
#endif

/// @todo refactor away.
void clearLogical();

/**
* Provides mutable access to the sound sample cache (waveforms).
*/
Expand Down
8 changes: 1 addition & 7 deletions doomsday/apps/client/include/resource/resourcesystem.h
Expand Up @@ -267,13 +267,7 @@ class ResourceSystem : public Resources
*
* @see forAllMaterialSchemes(), MaterialScheme::clear().
*/
inline void clearAllMaterialSchemes() {
forAllMaterialSchemes([] (de::MaterialScheme &scheme) {
scheme.clear();
return de::LoopContinue;
});
DENG2_ASSERT(materialCount() == 0); // sanity check
}
void clearAllMaterialSchemes() override;

/**
* Lookup a material manifest group by unique @a number.
Expand Down
13 changes: 5 additions & 8 deletions doomsday/apps/client/src/audio/system.cpp
Expand Up @@ -188,8 +188,8 @@ static bool recognizeMus(de::File1 &file)
#endif

DENG2_PIMPL(System)
#ifdef __CLIENT__
, DENG2_OBSERVES(DoomsdayApp, GameUnload)
#ifdef __CLIENT__
, DENG2_OBSERVES(SfxSampleCache, SampleRemove)
#endif
{
Expand Down Expand Up @@ -1379,13 +1379,15 @@ DENG2_PIMPL(System)
// this sample (the sample data will be gone soon).
unloadSoundID(sample.id);
}
#endif // __CLIENT__

void aboutToUnloadGame(Game const &)
{
#ifdef __CLIENT__
self.reset();
#endif
sfxClearLogical();
}

#endif // __CLIENT__
};

System::System() : d(new Instance(this))
Expand Down Expand Up @@ -2364,11 +2366,6 @@ void System::requestSfxListenerUpdate()

#endif // __CLIENT__

void System::clearLogical()
{
d->sfxClearLogical();
}

void System::startLogical(dint soundIdAndFlags, mobj_t *emitter)
{
d->sfxStartLogical(soundIdAndFlags, emitter);
Expand Down
10 changes: 10 additions & 0 deletions doomsday/apps/client/src/clientapp.cpp
Expand Up @@ -71,6 +71,7 @@
#include "ui/dialogs/alertdialog.h"
#include "ui/styledlogsinkformatter.h"
#include "render/rend_particle.h"
#include "render/r_draw.h"
#include "network/net_demo.h"
#include "updater.h"
#include "updater/downloaddialog.h"
Expand Down Expand Up @@ -759,6 +760,9 @@ void ClientApp::aboutToChangeGame(Game const &upcomingGame)
{
DoomsdayApp::aboutToChangeGame(upcomingGame);

// Game has been set to null, update window.
ClientWindow::main().setWindowTitle(DD_ComposeMainWindowTitle());

if(!upcomingGame.isNull())
{
ClientWindow &mainWin = ClientWindow::main();
Expand All @@ -770,6 +774,12 @@ void ClientApp::aboutToChangeGame(Game const &upcomingGame)
mainWin.canvas().trapMouse();
}
}

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

infineSystem().reset();
}

void ClientApp::reset()
Expand Down
198 changes: 2 additions & 196 deletions doomsday/apps/client/src/dd_main.cpp
Expand Up @@ -58,6 +58,7 @@
#include <doomsday/filesys/fs_main.h>
#include <doomsday/filesys/fs_util.h>
#include <doomsday/filesys/sys_direc.h>
#include <doomsday/filesys/virtualmappings.h>
#include <doomsday/resource/manifest.h>
#include <doomsday/help.h>
#include <doomsday/paths.h>
Expand Down Expand Up @@ -877,156 +878,6 @@ static dint addListFiles(QStringList const &list, FileType const &ftype)
return numAdded;
}

/**
* (Re-)Initialize the VFS path mappings.
*/
static void initPathMappings()
{
App_FileSystem().clearPathMappings();

if(DD_IsShuttingDown()) return;

// Create virtual directory mappings by processing all -vdmap options.
dint argC = CommandLine_Count();
for(dint i = 0; i < argC; ++i)
{
if(strnicmp("-vdmap", CommandLine_At(i), 6))
{
continue;
}

if(i < argC - 1 && !CommandLine_IsOption(i + 1) && !CommandLine_IsOption(i + 2))
{
String source = NativePath(CommandLine_PathAt(i + 1)).expand().withSeparators('/');
String destination = NativePath(CommandLine_PathAt(i + 2)).expand().withSeparators('/');
App_FileSystem().addPathMapping(source, destination);
i += 2;
}
}
}

/// Skip all whitespace except newlines.
static inline char const *skipSpace(char const *ptr)
{
DENG2_ASSERT(ptr != 0);
while(*ptr && *ptr != '\n' && isspace(*ptr))
{ ptr++; }
return ptr;
}

static bool parsePathLumpMapping(char lumpName[9/*LUMPNAME_T_MAXLEN*/], ddstring_t *path, char const *buffer)
{
DENG2_ASSERT(lumpName != 0 && path != 0);

// Find the start of the lump name.
char const *ptr = skipSpace(buffer);

// Just whitespace?
if(!*ptr || *ptr == '\n') return false;

// Find the end of the lump name.
char const *end = (char const *)M_FindWhite((char *)ptr);
if(!*end || *end == '\n') return false;

size_t len = end - ptr;
// Invalid lump name?
if(len > 8) return false;

memset(lumpName, 0, 9/*LUMPNAME_T_MAXLEN*/);
strncpy(lumpName, ptr, len);
strupr(lumpName);

// Find the start of the file path.
ptr = skipSpace(end);
if(!*ptr || *ptr == '\n') return false; // Missing file path.

// We're at the file path.
Str_Set(path, ptr);
// Get rid of any extra whitespace on the end.
Str_StripRight(path);
F_FixSlashes(path, path);
return true;
}

/**
* <pre> LUMPNAM0 \\Path\\In\\The\\Base.ext
* LUMPNAM1 Path\\In\\The\\RuntimeDir.ext
* :</pre>
*/
static bool parsePathLumpMappings(char const *buffer)
{
DENG2_ASSERT(buffer != 0);

bool successful = false;
ddstring_t path; Str_Init(&path);
ddstring_t line; Str_Init(&line);

char const *ch = buffer;
char lumpName[9/*LUMPNAME_T_MAXLEN*/];
do
{
ch = Str_GetLine(&line, ch);
if(!parsePathLumpMapping(lumpName, &path, Str_Text(&line)))
{
// Failure parsing the mapping.
// Ignore errors in individual mappings and continue parsing.
//goto parseEnded;
}
else
{
String destination = NativePath(Str_Text(&path)).expand().withSeparators('/');
App_FileSystem().addPathLumpMapping(lumpName, destination);
}
} while(*ch);

// Success.
successful = true;

//parseEnded:
Str_Free(&line);
Str_Free(&path);
return successful;
}

/**
* (Re-)Initialize the path => lump mappings.
* @note Should be called after WADs have been processed.
*/
static void initPathLumpMappings()
{
// Free old paths, if any.
App_FileSystem().clearPathLumpMappings();

if(DD_IsShuttingDown()) return;

size_t bufSize = 0;
uint8_t *buf = 0;

// Add the contents of all DD_DIREC lumps.
/// @todo fixme: Enforce scope to the containing package!
LumpIndex const &lumpIndex = App_FileSystem().nameIndex();
LumpIndex::FoundIndices foundDirecs;
lumpIndex.findAll("DD_DIREC.lmp", foundDirecs);
DENG2_FOR_EACH_CONST(LumpIndex::FoundIndices, i, foundDirecs) // in load order
{
File1 &lump = lumpIndex[*i];
FileInfo const &lumpInfo = lump.info();

// Make a copy of it so we can ensure it ends in a null.
if(bufSize < lumpInfo.size + 1)
{
bufSize = lumpInfo.size + 1;
buf = (uint8_t *) M_Realloc(buf, bufSize);
}

lump.read(buf, 0, lumpInfo.size);
buf[lumpInfo.size] = 0;
parsePathLumpMappings(reinterpret_cast<char const *>(buf));
}

M_Free(buf);
}

static dint DD_LoadAddonResourcesWorker(void *context)
{
ddgamechange_params_t &parms = *static_cast<ddgamechange_params_t *>(context);
Expand Down Expand Up @@ -1297,49 +1148,10 @@ bool App_ChangeGame(Game &game, bool allowReload)
// If a game is presently loaded; unload it.
if(App_GameLoaded())
{
DoomsdayApp::app().reset();
Resources::get().clear();

App_AudioSystem().clearLogical();

Con_ClearDatabases();

// We do not want to load session resources specified on the command line again.
Session::profile().resourceFiles.clear();

// The current game is now the special "null-game".
DoomsdayApp::setGame(App_Games().nullGame());

Con_InitDatabases();
/// @todo Use an audience? -jk
consoleRegister();

R_InitSvgs();

#ifdef __CLIENT__
ClientApp::inputSystem().initAllDevices();
R_InitViewWindow();
#endif

App_FileSystem().unloadAllNonStartupFiles();

// Reset file IDs so previously seen files can be processed again.
/// @todo this releases the IDs of startup files too but given the
/// only startup file is doomsday.pk3 which we never attempt to load
/// again post engine startup, this isn't an immediate problem.
App_FileSystem().resetFileIds();

// Update the dir/WAD translations.
initPathLumpMappings();
initPathMappings();

App_FileSystem().resetAllSchemes();
}

App_InFineSystem().reset();

/// @todo The entire material collection should not be destroyed during a reload.
App_ResourceSystem().clearAllMaterialSchemes();

if(!game.isNull())
{
LOG_MSG("Loading game '%s'...") << game.id();
Expand All @@ -1351,10 +1163,6 @@ bool App_ChangeGame(Game &game, bool allowReload)

Library_ReleaseGames();

#ifdef __CLIENT__
ClientWindow::main().setWindowTitle(DD_ComposeMainWindowTitle());
#endif

if(!DD_IsShuttingDown())
{
// Re-initialize subsystems needed even when in ringzero.
Expand Down Expand Up @@ -1913,9 +1721,7 @@ static dint DD_StartupWorker(void * /*context*/)
R_BuildTexGammaLut();
#ifdef __CLIENT__
UI_LoadFonts();
#endif
R_InitSvgs();
#ifdef __CLIENT__
R_InitViewWindow();
R_ResetFrameCount();
#endif
Expand Down
9 changes: 9 additions & 0 deletions doomsday/apps/client/src/resource/resourcesystem.cpp
Expand Up @@ -4506,3 +4506,12 @@ String ResourceSystem::resolveSymbol(String const &symbol) // static
"Symbol '" + symbol + "' is unknown");
}
}

void ResourceSystem::clearAllMaterialSchemes()
{
forAllMaterialSchemes([] (MaterialScheme &scheme) {
scheme.clear();
return LoopContinue;
});
DENG2_ASSERT(materialCount() == 0); // sanity check
}

0 comments on commit afd77d6

Please sign in to comment.