Skip to content

Commit

Permalink
Refactor: Continued splitting up remaining old savegame system functi…
Browse files Browse the repository at this point in the history
…onality

It is no longer necessary for the engine to be made aware of which
map state reader is actually used for deserialization. This logic
can exist entirely in libcommon. In turn, there is no need to link
the sessions to the SavedSessionRepository, which, is now little
more than a collection of resource search routines.
  • Loading branch information
danij-deng committed Mar 16, 2014
1 parent 81c4692 commit 9601bc8
Show file tree
Hide file tree
Showing 17 changed files with 37 additions and 211 deletions.
11 changes: 0 additions & 11 deletions doomsday/client/src/resource/resourcesystem.cpp
Expand Up @@ -162,7 +162,6 @@ static detailvariantspecification_t &configureDetailTextureSpec(
#endif // __CLIENT__

DENG2_PIMPL(ResourceSystem)
, DENG2_OBSERVES(App, GameUnload) // Serialized map state format clearing
, DENG2_OBSERVES(Games, Addition) // Saved session repository population
, DENG2_OBSERVES(MaterialScheme, ManifestDefined)
, DENG2_OBSERVES(MaterialManifest, MaterialDerived)
Expand Down Expand Up @@ -375,7 +374,6 @@ DENG2_PIMPL(ResourceSystem)
#endif

App_Games().audienceForAddition += this;
App::app().audienceForGameUnload() += this;

// Determine the root directory of the saved session repository.
NativePath nativeSavePath;
Expand All @@ -400,7 +398,6 @@ DENG2_PIMPL(ResourceSystem)
~Instance()
{
App_Games().audienceForAddition -= this;
App::app().audienceForGameUnload() -= this;

qDeleteAll(resClasses);
self.clearAllAnimGroups();
Expand Down Expand Up @@ -1940,7 +1937,6 @@ DENG2_PIMPL(ResourceSystem)
{
String const &relPath = saveFolder.name() / i->first.fileNameWithoutExtension();
game::SavedSession *newSession = new game::SavedSession(relPath);
newSession->setRepository(&saveRepo);
saveRepo.add(relPath, newSession);

newSession->updateFromFile();
Expand All @@ -1952,19 +1948,12 @@ DENG2_PIMPL(ResourceSystem)
{
String const &relPath = saveFolder.name() / outFileName;
QScopedPointer<game::SavedSession> newSession(new game::SavedSession(relPath));
newSession->setRepository(&saveRepo);
if(convertSavegame(inputPath, *newSavedSession, gameId))
{
saveRepo.add(relPath, newSession.take());
}
}*/
}

void aboutToUnloadGame(game::Game const &)
{
// Clear the game-registered map state formats.
saveRepo.clearMapStateReaders();
}
};

ResourceSystem::ResourceSystem() : d(new Instance(this))
Expand Down
46 changes: 0 additions & 46 deletions doomsday/libdeng2/include/de/game/savedsession.h
Expand Up @@ -30,7 +30,6 @@ namespace de {
namespace game {

class MapStateReader;
class SavedSessionRepository;

/**
* Logical component representing a serialized game session on disk.
Expand All @@ -40,15 +39,9 @@ class SavedSessionRepository;
class DENG2_PUBLIC SavedSession
{
public:
/// Required/referenced repository is missing. @ingroup errors
DENG2_ERROR(MissingRepositoryError);

/// Required file package could not be located. @ingroup errors
DENG2_ERROR(MissingFileError);

/// The associated map state file was missing/unrecognized. @ingroup errors
DENG2_ERROR(UnrecognizedMapStateError);

/// Notified whenever the metadata of the saved session changes.
DENG2_DEFINE_AUDIENCE2(MetadataChange, void savedSessionMetadataChanged(SavedSession &session))

Expand Down Expand Up @@ -93,31 +86,9 @@ class DENG2_PUBLIC SavedSession
*/
String description() const;

/**
* Determines whether a repository is configured for the saved session.
*/
bool hasRepository() const;

/**
* Returns the saved session repository which owns the saved session.
*
* @see hasRepository()
*/
SavedSessionRepository &repository() const;

/**
* Configure the saved session to use the @a newRepository. Once set, the saved session file
* package (if present) is potentially @em loadable, @em updateable and @em removable.
*
* @param newRepository New SavedSessionRepository to configure for.
*/
void setRepository(SavedSessionRepository *newRepository);

/**
* Determines whether a file package exists for the saved session in the repository. Note that
* it may not be compatible with the current game session, however.
*
* @see setRepository()
*/
bool hasFile() const;

Expand All @@ -134,17 +105,13 @@ class DENG2_PUBLIC SavedSession
* reads the session metadata.
*
* @return @c true iff the session metadata was read successfully.
*
* @see setRepository()
*/
bool recognizeFile();

/**
* Attempt to update the status of the saved session from the file package in the repository.
* If the file path is invalid, unreachable, or the package is not recognized then the saved
* session is returned to a valid but non-loadable state.
*
* @see setRepository()
*/
void updateFromFile();

Expand All @@ -161,8 +128,6 @@ class DENG2_PUBLIC SavedSession

/**
* Removes the file package for the saved session from the repository (if configured).
*
* @see setRepository()
*/
void removeFile();

Expand All @@ -185,20 +150,9 @@ class DENG2_PUBLIC SavedSession
* Determines whether a serialized map state exists for the saved session.
*
* @param mapUri Unique map identifier.
*
* @see mapStateReader()
*/
bool hasMapState(String mapUriStr) const;

/**
* Determines whether a file package exists for the saved session in the repository and if so,
* reads the session metadata and then returns a new MapStateReader instance appropriate for
* deserializing map state data.
*
* @return New reader instance if recognized; otherwise @c 0. Ownership given to the caller.
*/
std::auto_ptr<MapStateReader> mapStateReader();

private:
DENG2_PRIVATE(d)
};
Expand Down
27 changes: 0 additions & 27 deletions doomsday/libdeng2/include/de/game/savedsessionrepository.h
Expand Up @@ -26,7 +26,6 @@
namespace de {
namespace game {

class MapStateReader;
class SavedSession;

/**
Expand All @@ -43,9 +42,6 @@ class DENG2_PUBLIC SavedSessionRepository
/// Notified whenever a saved session is added/removed from the repository.
DENG2_DEFINE_AUDIENCE2(AvailabilityUpdate, void repositoryAvailabilityUpdate(SavedSessionRepository const &repository))

/// Game map state reader instantiator function ptr.
typedef MapStateReader *(*MapStateReaderMakeFunc)(SavedSession const &find);

typedef std::map<String, SavedSession *> All;

public:
Expand Down Expand Up @@ -97,29 +93,6 @@ class DENG2_PUBLIC SavedSessionRepository
*/
All const &all() const;

/**
* Register a map state reader.
*
* @param formatName Symbolic identifier for the map format.
* @param maker Map state reader instantiator function.
*/
void declareMapStateReader(String formatName, MapStateReaderMakeFunc maker);

/**
* Unregister all map state readers.
*/
void clearMapStateReaders();

/**
* Determines whether a MapStateReader appropriate for the specified saved @a session
* is available and if so, returns a new instance for deserializing the map state.
*
* @param session The saved session to obtain a reader for.
*
* @return New reader instance if recognized; otherwise @c 0. Ownership given to the caller.
*/
MapStateReader *makeMapStateReader(SavedSession const &find) const;

private:
DENG2_PRIVATE(d)
};
Expand Down
41 changes: 0 additions & 41 deletions doomsday/libdeng2/src/game/savedsession.cpp
Expand Up @@ -21,8 +21,6 @@
#include "de/App"
#include "de/ArrayValue"
#include "de/game/Game"
#include "de/game/MapStateReader"
#include "de/game/SavedSessionRepository"
#include "de/Info"
#include "de/Log"
#include "de/NumberValue"
Expand Down Expand Up @@ -138,21 +136,16 @@ String SavedSession::Metadata::asTextWithInfoSyntax() const

DENG2_PIMPL(SavedSession)
{
SavedSessionRepository *repo; ///< The owning repository (if any).

String repoPath; ///< Relative path to the game session file.

QScopedPointer<Metadata> metadata;

Instance(Public *i)
: Base(i)
, repo (0)
, metadata (new Metadata)
{}

Instance(Public *i, Instance const &other)
: Base(i)
, repo (other.repo)
, repoPath (other.repoPath)
{
DENG2_ASSERT(!other.metadata.isNull());
Expand Down Expand Up @@ -204,7 +197,6 @@ DENG2_PIMPL(SavedSession)

PackageFolder *tryLocatePackage()
{
if(!repo) return false;
return App::fileSystem().root().tryLocate<PackageFolder>(String("/savegame") / repoPath);
}

Expand Down Expand Up @@ -232,27 +224,6 @@ SavedSession &SavedSession::operator = (SavedSession const &other)
return *this;
}

bool SavedSession::hasRepository() const
{
return d->repo != 0;
}

SavedSessionRepository &SavedSession::repository() const
{
if(d->repo)
{
return *d->repo;
}
/// @throw MissingRepositoryError No repository is configured.
throw MissingRepositoryError("SavedSession::repository", "No repository is configured");
}

void SavedSession::setRepository(SavedSessionRepository *newRepository)
{
d->repo = newRepository;
}


static String metadataAsStyledText(SavedSession::Metadata const &metadata)
{
return String(_E(b) "%1\n" _E(.)
Expand Down Expand Up @@ -294,7 +265,6 @@ void SavedSession::setPath(String newPath)

bool SavedSession::hasFile() const
{
if(!d->repo) return false;
return App::fileSystem().root().has(String("/savegame") / d->repoPath);
}

Expand Down Expand Up @@ -388,17 +358,6 @@ bool SavedSession::hasMapState(String mapUriStr) const
return false;
}

std::auto_ptr<MapStateReader> SavedSession::mapStateReader()
{
if(recognizeFile())
{
std::auto_ptr<MapStateReader> p(repository().makeMapStateReader(*this));
return p;
}
/// @throw UnrecognizedMapStateError The game state format was not recognized.
throw UnrecognizedMapStateError("SavedSession::mapStateReader", "Unrecognized map state format");
}

SavedSession::Metadata const &SavedSession::metadata() const
{
DENG2_ASSERT(!d->metadata.isNull());
Expand Down
43 changes: 0 additions & 43 deletions doomsday/libdeng2/src/game/savedsessionrepository.cpp
Expand Up @@ -36,19 +36,6 @@ DENG2_PIMPL(SavedSessionRepository)
All sessions;
bool availabilityUpdateDisabled;

struct FormatInfo {
String name;
MapStateReaderMakeFunc newMapStateReader;

FormatInfo(String name, MapStateReaderMakeFunc newMapStateReader)
: name(name), newMapStateReader(newMapStateReader)
{
DENG2_ASSERT(!name.isEmpty() && newMapStateReader != 0);
}
};
typedef QList<FormatInfo> FormatInfos;
FormatInfos formats;

Instance(Public *i)
: Base(i)
, availabilityUpdateDisabled(false)
Expand All @@ -65,18 +52,6 @@ DENG2_PIMPL(SavedSessionRepository)
DENG2_FOR_PUBLIC_AUDIENCE2(AvailabilityUpdate, i) i->repositoryAvailabilityUpdate(self);
}

FormatInfo const *infoForMapStateFormat(String const &name)
{
foreach(FormatInfo const &fmtInfo, formats)
{
if(!fmtInfo.name.compareWithoutCase(name))
{
return &fmtInfo;
}
}
return 0;
}

DENG2_PIMPL_AUDIENCE(AvailabilityUpdate)
};

Expand Down Expand Up @@ -159,23 +134,5 @@ SavedSessionRepository::All const &SavedSessionRepository::all() const
return d->sessions;
}

void SavedSessionRepository::declareMapStateReader(String formatName, MapStateReaderMakeFunc maker)
{
d->formats << Instance::FormatInfo(formatName, maker);
}

void SavedSessionRepository::clearMapStateReaders()
{
d->formats.clear();
}

MapStateReader *SavedSessionRepository::makeMapStateReader(SavedSession const &session) const
{
/// @todo Recognize the map state file to determine the format.
Instance::FormatInfo const *fmtInfo = d->infoForMapStateFormat("Native");
DENG2_ASSERT(fmtInfo != 0);
return fmtInfo->newMapStateReader(session);
}

} // namespace game
} // namespace de
1 change: 1 addition & 0 deletions doomsday/plugins/common/include/g_common.h
Expand Up @@ -179,6 +179,7 @@ D_CMD( CCmdExitLevel );

#if __cplusplus
#include <de/game/MapStateReader>
#include <de/game/SavedSessionRepository>
#include <de/String>
#include "gamerules.h"

Expand Down
2 changes: 0 additions & 2 deletions doomsday/plugins/common/include/mapstatereader.h
Expand Up @@ -37,8 +37,6 @@ class MapStateReader : public de::game::MapStateReader
MapStateReader(de::game::SavedSession const &session);
~MapStateReader();

static de::game::MapStateReader *make(de::game::SavedSession const &session);

/**
* Deserialize the saved map state.
*/
Expand Down
9 changes: 9 additions & 0 deletions doomsday/plugins/common/include/p_saveg.h
Expand Up @@ -28,6 +28,15 @@
class MapStateReader;
class MapStateWriter;

/**
* Determines whether a file package exists for the saved session in the repository and if so,
* reads the session metadata and then returns a new MapStateReader instance appropriate for
* deserializing map state data.
*
* @return New reader instance if recognized. Ownership given to the caller.
*/
std::auto_ptr<de::game::MapStateReader> SV_MapStateReader(de::game::SavedSession &session);

DENG_EXTERN_C int saveToRealPlayerNum[MAXPLAYERS];

#if __JHEXEN__
Expand Down

0 comments on commit 9601bc8

Please sign in to comment.