diff --git a/src/MetaData.cpp b/src/MetaData.cpp index 5879888d2..4a782f5bc 100644 --- a/src/MetaData.cpp +++ b/src/MetaData.cpp @@ -6,36 +6,57 @@ #include "components/RatingComponent.h" #include "components/DateTimeComponent.h" -MetaDataList::MetaDataList() + +MetaDataDecl gameDecls[] = { + {"name", MD_STRING, "", false}, + {"desc", MD_MULTILINE_STRING, "", false}, + {"image", MD_IMAGE_PATH, "", false}, + {"thumbnail", MD_IMAGE_PATH, "", false}, + {"rating", MD_RATING, "0", false}, + {"releasedate", MD_DATE, "0", false}, + {"playcount", MD_INT, "0", true}, + {"lastplayed", MD_TIME, "0", true} +}; +const std::vector gameMDD(gameDecls, gameDecls + sizeof(gameDecls) / sizeof(gameDecls[0])); + +MetaDataDecl folderDecls[] = { + {"name", MD_STRING, "", false}, + {"desc", MD_MULTILINE_STRING, "", false}, + {"image", MD_IMAGE_PATH, "", false}, + {"thumbnail", MD_IMAGE_PATH, "", false}, +}; +const std::vector folderMDD(folderDecls, folderDecls + sizeof(folderDecls) / sizeof(folderDecls[0])); + +const std::vector& getMDDByType(MetaDataListType type) { + switch(type) + { + case GAME_METADATA: + return gameMDD; + case FOLDER_METADATA: + return folderMDD; + } + + LOG(LogError) << "Invalid MDD type"; + return gameMDD; } -MetaDataList::MetaDataList(const std::vector& mdd) + + +MetaDataList::MetaDataList(MetaDataListType type) + : mType(type) { + const std::vector& mdd = getMDD(); for(auto iter = mdd.begin(); iter != mdd.end(); iter++) set(iter->key, iter->defaultValue); } -std::vector MetaDataList::getDefaultGameMDD() -{ - MetaDataDecl decls[] = { - {"name", MD_STRING, "", false}, - {"desc", MD_MULTILINE_STRING, "", false}, - {"image", MD_IMAGE_PATH, "", false}, - {"thumbnail", MD_IMAGE_PATH, "", false}, - {"rating", MD_RATING, "0", false}, - {"releasedate", MD_DATE, "0", false}, - {"playcount", MD_INT, "0", true}, - {"lastplayed", MD_TIME, "0", true} - }; - std::vector mdd(decls, decls + sizeof(decls) / sizeof(decls[0])); - return mdd; -} - -MetaDataList MetaDataList::createFromXML(const std::vector& mdd, pugi::xml_node node) +MetaDataList MetaDataList::createFromXML(MetaDataListType type, pugi::xml_node node) { - MetaDataList mdl; + MetaDataList mdl(type); + + const std::vector& mdd = mdl.getMDD(); for(auto iter = mdd.begin(); iter != mdd.end(); iter++) { @@ -51,19 +72,25 @@ MetaDataList MetaDataList::createFromXML(const std::vector& mdd, p return mdl; } -void MetaDataList::appendToXML(pugi::xml_node parent, const std::vector& ignoreDefaults) const +void MetaDataList::appendToXML(pugi::xml_node parent, bool ignoreDefaults) const { + const std::vector& mdd = getMDD(); + for(auto iter = mMap.begin(); iter != mMap.end(); iter++) { bool write = true; - for(auto mddIter = ignoreDefaults.begin(); mddIter != ignoreDefaults.end(); mddIter++) - { - if(mddIter->key == iter->first) - { - if(iter->second == mddIter->defaultValue) - write = false; - break; + if(ignoreDefaults) + { + for(auto mddIter = mdd.begin(); mddIter != mdd.end(); mddIter++) + { + if(mddIter->key == iter->first) + { + if(iter->second == mddIter->defaultValue) + write = false; + + break; + } } } diff --git a/src/MetaData.h b/src/MetaData.h index f83d2aeed..48c6c3f5c 100644 --- a/src/MetaData.h +++ b/src/MetaData.h @@ -31,16 +31,22 @@ struct MetaDataDecl boost::posix_time::ptime string_to_ptime(const std::string& str, const std::string& fmt = "%Y%m%dT%H%M%S%F%q"); +enum MetaDataListType +{ + GAME_METADATA, + FOLDER_METADATA +}; + +const std::vector& getMDDByType(MetaDataListType type); + class MetaDataList { public: - static std::vector getDefaultGameMDD(); - - static MetaDataList createFromXML(const std::vector& mdd, pugi::xml_node node); - - //MetaDataDecl required to set our defaults. - MetaDataList(const std::vector& mdd); + static MetaDataList createFromXML(MetaDataListType type, pugi::xml_node node); + void appendToXML(pugi::xml_node parent, bool ignoreDefaults = false) const; + MetaDataList(MetaDataListType type); + void set(const std::string& key, const std::string& value); void setTime(const std::string& key, const boost::posix_time::ptime& time); //times are internally stored as ISO strings (e.g. boost::posix_time::to_iso_string(ptime)) @@ -52,11 +58,11 @@ public: static GuiComponent* makeDisplay(Window* window, MetaDataType as); static GuiComponent* makeEditor(Window* window, MetaDataType as); - void appendToXML(pugi::xml_node parent, const std::vector& ignoreDefaults = std::vector()) const; + inline MetaDataListType getType() const { return mType; } + inline const std::vector& getMDD() const { return getMDDByType(getType()); } private: - MetaDataList(); - + MetaDataListType mType; std::map mMap; }; @@ -64,7 +70,8 @@ private: //options for storing metadata... //store internally everything as a string - this is all going to be read to/from XML anyway, after all -//store using individual get/set functions ala Settings - this is a fair amount of work but the most explicit, for better or worse +// - problem: this does not play nice with lists of values +//store using individual get/set functions ala Settings - this is a fair amount of work but the most explicit and type-safe, for better or worse //let's think about some of the special types we would like to support... //image paths, sound paths, ratings, play counts diff --git a/src/ScraperCmdLine.cpp b/src/ScraperCmdLine.cpp index f62b64a03..53fce16c5 100644 --- a/src/ScraperCmdLine.cpp +++ b/src/ScraperCmdLine.cpp @@ -243,7 +243,7 @@ int run_scraper_cmdline() for(auto gameIt = files.begin(); gameIt != files.end(); gameIt++) { GameData* game = (GameData*)(*gameIt); - std::vector mdd = (*sysIt)->getGameMDD(); + const std::vector& mdd = game->metadata()->getMDD(); for(auto i = mdd.begin(); i != mdd.end(); i++) { std::string key = i->key; diff --git a/src/SystemData.cpp b/src/SystemData.cpp index 9a308510a..84b3e7ddd 100644 --- a/src/SystemData.cpp +++ b/src/SystemData.cpp @@ -142,7 +142,7 @@ void SystemData::populateFolder(FolderData* folder) isGame = false; if(std::find(mSearchExtensions.begin(), mSearchExtensions.end(), extension) != mSearchExtensions.end()) { - GameData* newGame = new GameData(filePath.generic_string(), MetaDataList(getGameMDD())); + GameData* newGame = new GameData(filePath.generic_string(), MetaDataList(GAME_METADATA)); folder->pushFileData(newGame); isGame = true; } @@ -335,11 +335,6 @@ bool SystemData::hasGamelist() return (fs::exists(getGamelistPath())); } -std::vector SystemData::getGameMDD() -{ - return MetaDataList::getDefaultGameMDD(); -} - PlatformIds::PlatformId SystemData::getPlatformId() { return mPlatformId; diff --git a/src/SystemData.h b/src/SystemData.h index fb82961b9..6040d2e61 100644 --- a/src/SystemData.h +++ b/src/SystemData.h @@ -27,8 +27,7 @@ public: std::string getGamelistPath(); bool hasGamelist(); - std::vector getGameMDD(); - + unsigned int getGameCount(); void launchGame(Window* window, GameData* game); diff --git a/src/XMLReader.cpp b/src/XMLReader.cpp index 5cd25df08..35f8fdcda 100644 --- a/src/XMLReader.cpp +++ b/src/XMLReader.cpp @@ -91,7 +91,7 @@ GameData* createGameFromPath(std::string gameAbsPath, SystemData* system) loops++; } - GameData* game = new GameData(gameAbsPath, MetaDataList(system->getGameMDD())); + GameData* game = new GameData(gameAbsPath, MetaDataList(GAME_METADATA)); folder->pushFileData(game); return game; } @@ -156,7 +156,7 @@ void parseGamelist(SystemData* system) game = createGameFromPath(path, system); //load the metadata - *(game->metadata()) = MetaDataList::createFromXML(system->getGameMDD(), gameNode); + *(game->metadata()) = MetaDataList::createFromXML(GAME_METADATA, gameNode); //make sure name gets set if one didn't exist if(game->metadata()->get("name").empty()) @@ -173,7 +173,7 @@ void addGameDataNode(pugi::xml_node& parent, const GameData* game, SystemData* s pugi::xml_node newGame = parent.append_child("game"); //write metadata - const_cast(game)->metadata()->appendToXML(newGame, system->getGameMDD()); + const_cast(game)->metadata()->appendToXML(newGame, true); if(newGame.children().begin() == newGame.child("name") //first element is name && ++newGame.children().begin() == newGame.children().end() //theres only one element diff --git a/src/components/GuiGameList.cpp b/src/components/GuiGameList.cpp index c7c5a6baa..88908c6d7 100644 --- a/src/components/GuiGameList.cpp +++ b/src/components/GuiGameList.cpp @@ -149,7 +149,7 @@ bool GuiGameList::input(InputConfig* config, Input input) ScraperSearchParams searchParams; searchParams.game = game; searchParams.system = mSystem; - mWindow->pushGui(new GuiMetaDataEd(mWindow, game->metadata(), mSystem->getGameMDD(), searchParams, game->getBaseName(), + mWindow->pushGui(new GuiMetaDataEd(mWindow, game->metadata(), game->metadata()->getMDD(), searchParams, game->getBaseName(), [&] { updateDetailData(); }, [game, root, this] { boost::filesystem::remove(game->getPath()); diff --git a/src/scrapers/GamesDBScraper.cpp b/src/scrapers/GamesDBScraper.cpp index 00dfe1765..10be80824 100644 --- a/src/scrapers/GamesDBScraper.cpp +++ b/src/scrapers/GamesDBScraper.cpp @@ -99,7 +99,7 @@ std::vector GamesDBScraper::parseReq(ScraperSearchParams params, s pugi::xml_node game = data.child("Game"); while(game && resultNum < MAX_SCRAPER_RESULTS) { - mdl.push_back(MetaDataList(params.system->getGameMDD())); + mdl.push_back(MetaDataList(GAME_METADATA)); mdl.back().set("name", game.child("GameTitle").text().get()); mdl.back().set("desc", game.child("Overview").text().get()); diff --git a/src/scrapers/Scraper.cpp b/src/scrapers/Scraper.cpp index 8f8058ac6..4f5d0a7af 100644 --- a/src/scrapers/Scraper.cpp +++ b/src/scrapers/Scraper.cpp @@ -177,7 +177,7 @@ std::shared_ptr createScraperByName(const std::string& name) void resolveMetaDataAssetsAsync(Window* window, const ScraperSearchParams& params, MetaDataList mdl, std::function returnFunc) { - std::vector mdd = params.system->getGameMDD(); + const std::vector& mdd = params.game->metadata()->getMDD(); for(auto it = mdd.begin(); it != mdd.end(); it++) { std::string key = it->key; diff --git a/src/scrapers/TheArchiveScraper.cpp b/src/scrapers/TheArchiveScraper.cpp index efa542a77..4ad80a161 100644 --- a/src/scrapers/TheArchiveScraper.cpp +++ b/src/scrapers/TheArchiveScraper.cpp @@ -44,7 +44,7 @@ std::vector TheArchiveScraper::parseReq(ScraperSearchParams params pugi::xml_node game = data.child("game"); while(game && resultNum < MAX_SCRAPER_RESULTS) { - mdl.push_back(MetaDataList(params.system->getGameMDD())); + mdl.push_back(MetaDataList(GAME_METADATA)); mdl.back().set("name", game.child("title").text().get()); mdl.back().set("desc", game.child("description").text().get());