diff --git a/doomsday/apps/client/src/ui/widgets/singleplayersessionmenuwidget.cpp b/doomsday/apps/client/src/ui/widgets/singleplayersessionmenuwidget.cpp index 40acb2854c..2e9f2668a6 100644 --- a/doomsday/apps/client/src/ui/widgets/singleplayersessionmenuwidget.cpp +++ b/doomsday/apps/client/src/ui/widgets/singleplayersessionmenuwidget.cpp @@ -65,7 +65,7 @@ DENG_GUI_PIMPL(SingleplayerSessionMenuWidget) void setDataFiles(StringList const &paths) { - game->setUserFiles(paths); + //game->setUserFiles(paths); owner->updateItemLabels(); } }; @@ -137,10 +137,10 @@ DENG_GUI_PIMPL(SingleplayerSessionMenuWidget) .arg(game.title()) .arg(game.id()); - if(!game.userFiles().isEmpty()) + /*if(!game.userFiles().isEmpty()) { label += _E(b) " +" + QString::number(game.userFiles().size()); - } + }*/ return label; } @@ -168,9 +168,9 @@ DENG_GUI_PIMPL(SingleplayerSessionMenuWidget) void updateWidgetAction(GameItem const &item) { - self.itemWidget(item). + /*self.itemWidget(item). setDataFileAction(item.game.userFiles().isEmpty()? GameSessionWidget::Select : - GameSessionWidget::Clear); + GameSessionWidget::Clear);*/ } void updateWidgetWithGameStatus(ui::Item const &menuItem) diff --git a/doomsday/apps/libdoomsday/include/doomsday/DoomsdayApp b/doomsday/apps/libdoomsday/include/doomsday/DoomsdayApp new file mode 100644 index 0000000000..d9359b7ac4 --- /dev/null +++ b/doomsday/apps/libdoomsday/include/doomsday/DoomsdayApp @@ -0,0 +1 @@ +#include "doomsdayapp.h" diff --git a/doomsday/apps/libdoomsday/include/doomsday/doomsdayapp.h b/doomsday/apps/libdoomsday/include/doomsday/doomsdayapp.h index 2134c5b9b6..e921eeb1d4 100644 --- a/doomsday/apps/libdoomsday/include/doomsday/doomsdayapp.h +++ b/doomsday/apps/libdoomsday/include/doomsday/doomsdayapp.h @@ -32,8 +32,9 @@ namespace res { class Bundles; } -class Games; class Game; +class Games; +class GameProfiles; /** * Common application-level state and components. @@ -121,6 +122,7 @@ class LIBDOOMSDAY_PUBLIC DoomsdayApp static res::Bundles &bundles(); static Plugins &plugins(); static Games &games(); + static GameProfiles &gameProfiles(); static Players &players(); static BusyMode &busyMode(); static de::NativePath steamBasePath(); diff --git a/doomsday/apps/libdoomsday/include/doomsday/game.h b/doomsday/apps/libdoomsday/include/doomsday/game.h index 9908d66407..344f434287 100644 --- a/doomsday/apps/libdoomsday/include/doomsday/game.h +++ b/doomsday/apps/libdoomsday/include/doomsday/game.h @@ -100,10 +100,6 @@ class LIBDOOMSDAY_PUBLIC Game : public de::IObject void addRequiredPackage(de::String const &packageId); - void setUserFiles(de::StringList const &nativePaths); - - de::StringList const &userFiles() const; - /** * Returns the list of required package IDs for loading the game. */ diff --git a/doomsday/apps/libdoomsday/include/doomsday/gameprofiles.h b/doomsday/apps/libdoomsday/include/doomsday/gameprofiles.h index 4f7510cc3e..b10c05c0e7 100644 --- a/doomsday/apps/libdoomsday/include/doomsday/gameprofiles.h +++ b/doomsday/apps/libdoomsday/include/doomsday/gameprofiles.h @@ -23,6 +23,8 @@ #include +class Games; + /** * Game configuration profiles. */ @@ -35,7 +37,7 @@ class LIBDOOMSDAY_PUBLIC GameProfiles : public de::Profiles class LIBDOOMSDAY_PUBLIC Profile : public AbstractProfile { public: - Profile(); + Profile(de::String const &name = ""); void setGame(de::String const &id); void setPackages(de::StringList const &packagesInOrder); @@ -53,8 +55,19 @@ class LIBDOOMSDAY_PUBLIC GameProfiles : public de::Profiles public: GameProfiles(); + /** + * Sets the games collection associated with these profiles. Each of the games + * will get their own matching profile. + * + * @param games Games. + */ + void setGames(Games &games); + protected: AbstractProfile *profileFromInfoBlock(de::Info::BlockElement const &block); + +private: + DENG2_PRIVATE(d) }; #endif // LIBDOOMSDAY_GAMEPROFILES_H diff --git a/doomsday/apps/libdoomsday/src/doomsdayapp.cpp b/doomsday/apps/libdoomsday/src/doomsdayapp.cpp index 2e872f7b04..4f939903c7 100644 --- a/doomsday/apps/libdoomsday/src/doomsdayapp.cpp +++ b/doomsday/apps/libdoomsday/src/doomsdayapp.cpp @@ -61,7 +61,7 @@ static String const PATH_LOCAL_WADS("/local/wads"); static DoomsdayApp *theDoomsdayApp = nullptr; -DENG2_PIMPL_NOREF(DoomsdayApp) +DENG2_PIMPL(DoomsdayApp) { std::string ddBasePath; // Doomsday root directory is at...? std::string ddRuntimePath; @@ -107,13 +107,16 @@ DENG2_PIMPL_NOREF(DoomsdayApp) GameChangeScriptAudience scriptAudienceForGameChange; - Instance(Players::Constructor playerConstructor) - : players(playerConstructor) + Instance(Public *i, Players::Constructor playerConstructor) + : Base(i) + , players(playerConstructor) { Record &appModule = App::scriptSystem().nativeModule("App"); appModule.addArray("audienceForGameChange"); // game change observers audienceForGameChange += scriptAudienceForGameChange; + gameProfiles.setGames(games); + #ifdef WIN32 hInstance = GetModuleHandle(NULL); #endif @@ -347,7 +350,7 @@ DENG2_AUDIENCE_METHOD(DoomsdayApp, GameChange) DENG2_AUDIENCE_METHOD(DoomsdayApp, ConsoleRegistration) DoomsdayApp::DoomsdayApp(Players::Constructor playerConstructor) - : d(new Instance(playerConstructor)) + : d(new Instance(this, playerConstructor)) { DENG2_ASSERT(!theDoomsdayApp); theDoomsdayApp = this; @@ -412,6 +415,11 @@ Games &DoomsdayApp::games() return DoomsdayApp::app().d->games; } +GameProfiles &DoomsdayApp::gameProfiles() +{ + return DoomsdayApp::app().d->gameProfiles; +} + Players &DoomsdayApp::players() { return DoomsdayApp::app().d->players; diff --git a/doomsday/apps/libdoomsday/src/game.cpp b/doomsday/apps/libdoomsday/src/game.cpp index bde6f955f3..0f9cb6b208 100644 --- a/doomsday/apps/libdoomsday/src/game.cpp +++ b/doomsday/apps/libdoomsday/src/game.cpp @@ -20,12 +20,13 @@ #include "doomsday/game.h" #include "doomsday/games.h" +#include "doomsday/doomsdayapp.h" +#include "doomsday/GameProfiles" +#include "doomsday/SavedSession" #include "doomsday/console/cmd.h" #include "doomsday/filesys/file.h" #include "doomsday/resource/manifest.h" #include "doomsday/resource/resources.h" -#include "doomsday/doomsdayapp.h" -#include "doomsday/SavedSession" #include #include @@ -54,7 +55,6 @@ DENG2_PIMPL(Game) pluginid_t pluginId = 0; ///< Unique identifier of the registering plugin. Record params; StringList requiredPackages; ///< Packages required for starting the game. - StringList userFiles; Manifests manifests; ///< Required resource files (e.g., doomu.wad). @@ -79,6 +79,15 @@ DENG2_PIMPL(Game) { qDeleteAll(manifests); } + + StringList packagesFromProfile() const + { + auto const *profile = DoomsdayApp::gameProfiles().tryFind(self.title())->maybeAs(); + if(profile) + { + return profile->packages(); + } + } }; Game::Game(String const &id, Record const ¶ms) @@ -129,16 +138,6 @@ void Game::addRequiredPackage(String const &packageId) d->requiredPackages.append(packageId); } -void Game::setUserFiles(StringList const &nativePaths) -{ - d->userFiles = nativePaths; -} - -StringList const &Game::userFiles() const -{ - return d->userFiles; -} - StringList Game::requiredPackages() const { return d->requiredPackages; @@ -156,7 +155,7 @@ void Game::addManifest(ResourceManifest &manifest) bool Game::allStartupFilesFound() const { - for(String const &pkg : d->requiredPackages) + for(String const &pkg : d->requiredPackages + d->packagesFromProfile()) { if(!App::packageLoader().isAvailable(pkg)) return false; diff --git a/doomsday/apps/libdoomsday/src/game_init.cpp b/doomsday/apps/libdoomsday/src/game_init.cpp index f8c914abe8..51e185f5d5 100644 --- a/doomsday/apps/libdoomsday/src/game_init.cpp +++ b/doomsday/apps/libdoomsday/src/game_init.cpp @@ -291,12 +291,13 @@ int loadAddonResourcesBusyWorker(void *context) { DoomsdayApp::GameChangeParameters &parms = *(DoomsdayApp::GameChangeParameters *) context; + /* // User-selected files specified in the game itself. for(String const &path : DoomsdayApp::game().userFiles()) { NativePath const nativePath(path); Session::profile().resourceFiles << nativePath.withSeparators('/'); - } + }*/ char const *startupFiles = CVar_String(Con_FindVariable("file-startup")); diff --git a/doomsday/apps/libdoomsday/src/gameprofiles.cpp b/doomsday/apps/libdoomsday/src/gameprofiles.cpp index 651dd40d06..4e4a22a969 100644 --- a/doomsday/apps/libdoomsday/src/gameprofiles.cpp +++ b/doomsday/apps/libdoomsday/src/gameprofiles.cpp @@ -16,7 +16,9 @@ * http://www.gnu.org/licenses */ -#include "doomsday/gameprofiles.h" +#include "doomsday/GameProfiles" +#include "doomsday/Games" +#include "doomsday/DoomsdayApp" #include @@ -27,11 +29,38 @@ using namespace de; static String const VAR_GAME ("game"); static String const VAR_PACKAGES("packages"); +DENG2_PIMPL(GameProfiles) +, DENG2_OBSERVES(Games, Addition) +{ + Instance(Public *i) : Base(i) {} + + void gameAdded(Game &game) + { + /* + * Make sure there is a profile matching this game's title. The session + * configuration for each game is persistently stored using these profiles. + * (User-created profiles must use different names.) + */ + if(!self.tryFind(game.title())) + { + auto *prof = new Profile(game.title()); + prof->setGame(game.id()); + self.add(prof); + } + } +}; + GameProfiles::GameProfiles() + : d(new Instance(this)) { setPersistentName("game"); } +void GameProfiles::setGames(Games &games) +{ + games.audienceForAddition() += d; +} + Profiles::AbstractProfile *GameProfiles::profileFromInfoBlock(Info::BlockElement const &block) { std::unique_ptr prof(new Profile); @@ -56,8 +85,10 @@ DENG2_PIMPL_NOREF(GameProfiles::Profile) StringList packages; }; -GameProfiles::Profile::Profile() : d(new Instance) -{} +GameProfiles::Profile::Profile(String const &name) : d(new Instance) +{ + setName(name); +} void GameProfiles::Profile::setGame(String const &id) {