Adding support for auto-scanning .sub files (for merging lists). Depricated menu.xml in favor of menu.txtwq.

This commit is contained in:
Don Honerbrink 2015-07-28 13:23:30 -05:00
parent 72c905b981
commit 2cc15babf9
6 changed files with 119 additions and 44 deletions

View File

@ -0,0 +1,2 @@
Sega Genesis
Arcade

View File

@ -1,4 +0,0 @@
<menu>
<item collection="Sega Genesis"/>
<item collection="Arcade"/>
</menu>

View File

@ -252,7 +252,7 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me
if(mergedCollectionName != "")
{
std::string mergedFile = Utils::combinePath(Configuration::absolutePath, "collections", mergedCollectionName, info->name + ".merge");
std::string mergedFile = Utils::combinePath(Configuration::absolutePath, "collections", mergedCollectionName, info->name + ".sub");
Logger::write(Logger::ZONE_INFO, "CollectionInfoBuilder", "Checking for \"" + mergedFile + "\"");
(void)conf_.getProperty("collections." + mergedCollectionName + ".list.includeMissingItems", showMissing);
ImportBasicList(info, mergedFile, includeFilter);

View File

@ -40,8 +40,67 @@ MenuParser::~MenuParser()
{
}
//todo: clean up this method, too much nesting
bool MenuParser::buildMenuItems(CollectionInfo *collection, bool sort, CollectionInfoBuilder &builder)
bool MenuParser::buildMenuItems(CollectionInfo *collection, bool sort)
{
if(!buildTextMenu(collection, sort))
{
return buildLegacyXmlMenu(collection, sort);
}
return true;
}
bool MenuParser::buildTextMenu(CollectionInfo *collection, bool sort)
{
std::string file = Utils::combinePath(Configuration::absolutePath, "collections", collection->name, "menu.txt");
std::ifstream includeStream(file.c_str());
std::vector<Item *> menuItems;
if (!includeStream.good())
{
Logger::write(Logger::ZONE_INFO, "Menu", "File does not exist: \"" + file + "\"");
return false;
}
Logger::write(Logger::ZONE_INFO, "Menu", "Found: \"" + file + "\"");
std::string line;
while(std::getline(includeStream, line))
{
line = Utils::filterComments(line);
if(!line.empty())
{
std::string title = line;
Item *item = new Item();
item->title = title;
item->fullTitle = title;
item->name = title;
item->leaf = false;
item->collectionInfo = collection;
menuItems.push_back(item);
}
}
std::sort(collection->items.begin(), collection->items.end(), VectorSort);
// todo: sorting should occur within the collection itself, not externally
if(sort)
{
// sort the menu if requested
std::sort( menuItems.begin(), menuItems.end(), VectorSort);
}
//todo: sorting
collection->items.insert(collection->items.begin(), menuItems.begin(), menuItems.end());
return true;
}
bool MenuParser::buildLegacyXmlMenu(CollectionInfo *collection, bool sort)
{
bool retVal = false;
//todo: magic string
@ -50,8 +109,6 @@ bool MenuParser::buildMenuItems(CollectionInfo *collection, bool sort, Collectio
rapidxml::xml_node<> * rootNode;
std::vector<Item *> menuItems;
Logger::write(Logger::ZONE_INFO, "Menu", "Checking if menu exists at \"" + menuFilename + "\"");
try
{
std::ifstream file(menuFilename.c_str());
@ -59,6 +116,8 @@ bool MenuParser::buildMenuItems(CollectionInfo *collection, bool sort, Collectio
// gracefully exit if there is no menu file for the pa
if(file.good())
{
Logger::write(Logger::ZONE_INFO, "Menu", "Found: \"" + menuFilename + "\"");
Logger::write(Logger::ZONE_INFO, "Menu", "Using legacy menu.xml file. Consider using the new menu.txt format");
std::vector<char> buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
buffer.push_back('\0');
@ -70,7 +129,6 @@ bool MenuParser::buildMenuItems(CollectionInfo *collection, bool sort, Collectio
for (rapidxml::xml_node<> * itemNode = rootNode->first_node("item"); itemNode; itemNode = itemNode->next_sibling())
{
rapidxml::xml_attribute<> *collectionAttribute = itemNode->first_attribute("collection");
rapidxml::xml_attribute<> *importAttribute = itemNode->first_attribute("import");
if(!collectionAttribute)
{
@ -78,35 +136,16 @@ bool MenuParser::buildMenuItems(CollectionInfo *collection, bool sort, Collectio
Logger::write(Logger::ZONE_ERROR, "Menu", "Menu item tag is missing collection attribute");
break;
}
//todo: too much nesting! Ack!
std::string import;
if(importAttribute)
{
import = importAttribute->value();
}
//todo, check for empty string
std::string title = collectionAttribute->value();
Item *item = new Item();
item->title = title;
item->fullTitle = title;
item->name = collectionAttribute->value();
item->leaf = false;
item->collectionInfo = collection;
if(import != "true")
{
//todo, check for empty string
std::string title = collectionAttribute->value();
Item *item = new Item();
item->title = title;
item->fullTitle = title;
item->name = collectionAttribute->value();
item->leaf = false;
item->collectionInfo = collection;
menuItems.push_back(item);
}
else
{
std::string subcollectionName = collectionAttribute->value();
Logger::write(Logger::ZONE_INFO, "Menu", "Loading collection into menu: " + collection->name);
CollectionInfo *subcollection = builder.buildCollection(subcollectionName, collection->name);
collection->addSubcollection(subcollection);
}
menuItems.push_back(item);
}
@ -132,5 +171,4 @@ bool MenuParser::buildMenuItems(CollectionInfo *collection, bool sort, Collectio
}
return retVal;
}

View File

@ -23,6 +23,10 @@ class MenuParser
public:
MenuParser();
virtual ~MenuParser();
bool buildMenuItems(CollectionInfo *cdb, bool sort, CollectionInfoBuilder &builder);
bool buildMenuItems(CollectionInfo *cdb, bool sort);
private:
bool buildTextMenu(CollectionInfo *collection, bool sort);
bool buildLegacyXmlMenu(CollectionInfo *collection, bool sort);
};

View File

@ -32,6 +32,15 @@
#include <vector>
#include <string>
#include <sstream>
#include <dirent.h>
#ifdef __linux
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <cstring>
#endif
#ifdef WIN32
#include <Windows.h>
#include <SDL2/SDL_syswm.h>
@ -285,8 +294,7 @@ void RetroFE::run()
CollectionInfo *info = getCollection(firstCollection);
MenuParser mp;
CollectionInfoBuilder cib(config_, *metadb_);
mp.buildMenuItems(info, menuSort, cib);
mp.buildMenuItems(info, menuSort);
currentPage_->pushCollection(info);
}
@ -469,8 +477,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
CollectionInfo *info = getCollection(nextPageItem_->name);
MenuParser mp;
CollectionInfoBuilder cib(config_, *metadb_);
mp.buildMenuItems(info, menuSort, cib);
mp.buildMenuItems(info, menuSort);
page->pushCollection(info);
if(rememberMenu && lastMenuOffsets_.find(nextPageItem_->name) != lastMenuOffsets_.end())
@ -550,6 +557,34 @@ CollectionInfo *RetroFE::getCollection(std::string collectionName)
CollectionInfoBuilder cib(config_, *metadb_);
CollectionInfo *collection = cib.buildCollection(collectionName);
DIR *dp;
struct dirent *dirp;
std::string path = Utils::combinePath(Configuration::absolutePath, "collections", collectionName);
dp = opendir(path.c_str());
while((dirp = readdir(dp)) != NULL)
{
std::string file = dirp->d_name;
size_t position = file.find_last_of(".");
std::string basename = (std::string::npos == position)? file : file.substr(0, position);
std::string comparator = ".sub";
int start = file.length() - comparator.length();
if(start >= 0)
{
if(file.compare(start, comparator.length(), comparator) == 0)
{
Logger::write(Logger::ZONE_INFO, "RetroFE", "Loading subcollection into menu: " + basename);
CollectionInfo *subcollection = cib.buildCollection(basename, collectionName);
collection->addSubcollection(subcollection);
}
}
}
return collection;
}