From 8fdc7ece6436ff8cdd5d47713c6e202d4c59d79c Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Thu, 6 Aug 2015 13:17:40 -0500 Subject: [PATCH] Supporting favorites --- RetroFE/Source/Collection/CollectionInfo.cpp | 12 +++ RetroFE/Source/Collection/CollectionInfo.h | 2 +- .../Collection/CollectionInfoBuilder.cpp | 12 ++- RetroFE/Source/Collection/MenuParser.cpp | 3 - .../Graphics/Component/ScrollingList.cpp | 44 +++++---- .../Source/Graphics/Component/ScrollingList.h | 4 +- RetroFE/Source/Graphics/Page.cpp | 95 +++++++++++++------ RetroFE/Source/Graphics/Page.h | 17 +++- 8 files changed, 129 insertions(+), 60 deletions(-) diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index d74955b..85ac94c 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -51,6 +51,18 @@ CollectionInfo::~CollectionInfo() } + Playlists_T::iterator pit = playlists.begin(); + + while(pit != playlists.end()) + { + if(pit->second != &items) + { + delete pit->second; + } + playlists.erase(pit); + pit = playlists.begin(); + } + std::vector::iterator it = items.begin(); while(it != items.end()) { diff --git a/RetroFE/Source/Collection/CollectionInfo.h b/RetroFE/Source/Collection/CollectionInfo.h index d4086da..b6450ec 100644 --- a/RetroFE/Source/Collection/CollectionInfo.h +++ b/RetroFE/Source/Collection/CollectionInfo.h @@ -37,7 +37,7 @@ public: std::string launcher; std::vector items; - typedef std::map > Playlists_T; + typedef std::map *> Playlists_T; Playlists_T playlists; private: diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp index 595b70c..475a18b 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp @@ -279,6 +279,8 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me std::vector::iterator extensionsIt; info->extensionList(extensions); + info->playlists["all"] = &info->items; + info->playlists["favorites"] = new std::vector(); dp = opendir(path.c_str()); @@ -300,10 +302,11 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me } } } - for(std::map::iterator it = favoritesFilter.begin(); it != favoritesFilter.end(); it++) - { - info->playlists["favorites"].push_back(it->second); - } + // add the favorites list + for(std::map::iterator it = favoritesFilter.begin(); it != favoritesFilter.end(); it++) + { + info->playlists["favorites"]->push_back(it->second); + } while((dirp = readdir(dp)) != NULL) { @@ -334,7 +337,6 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me i->collectionInfo = info; info->items.push_back(i); - info->playlists["include"].push_back(i); } } } diff --git a/RetroFE/Source/Collection/MenuParser.cpp b/RetroFE/Source/Collection/MenuParser.cpp index 5e62290..766dc75 100644 --- a/RetroFE/Source/Collection/MenuParser.cpp +++ b/RetroFE/Source/Collection/MenuParser.cpp @@ -149,9 +149,6 @@ bool MenuParser::buildLegacyXmlMenu(CollectionInfo *collection, bool sort) } - 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 diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index b622429..d140618 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -124,15 +124,12 @@ ScrollingList::~ScrollingList() } -void ScrollingList::setItems(CollectionInfo *info) +void ScrollingList::setItems(std::vector *items) { deallocateSpritePoints(); - collection_ = info; - items_ = &collection_->items; - + items_ = items; itemIndex_ = 0; - componentIndex_ = 0; allocateSpritePoints(); @@ -175,7 +172,10 @@ void ScrollingList::deallocateSpritePoints() void ScrollingList::allocateSpritePoints() { - for(unsigned int i = 0; items_ && i < scrollPoints_->size(); ++i) + if(!items_ || items_->size() == 0) return; + if(!scrollPoints_) return; + + for(unsigned int i = 0; i < scrollPoints_->size(); ++i) { componentIndex_ = 0; unsigned int index = loopIncrement(itemIndex_, i, items_->size()); @@ -210,10 +210,11 @@ void ScrollingList::setPoints(std::vector *scrollPoints, std::vector // empty out the list as we will resize it components_.clear(); - if(scrollPoints && scrollPoints_->size() > components_.size()) - { - components_.resize(scrollPoints_->size(), NULL); - } + int size = 0; + + if(scrollPoints) size = scrollPoints_->size(); + components_.resize(size); + allocateSpritePoints(); } @@ -378,12 +379,13 @@ void ScrollingList::update(float dt) bool scrollRequested = false; bool scrollStopped = false; - // validate all scroll points are done tweening to the next position - for(unsigned int i = 0; i < components_.size(); i++) - { - Component *c = components_.at(i); + if(components_.size() == 0) return; + if(!items_ || items_->size() == 0) return; - if(c && c->isMenuScrolling()) + // validate all scroll points are done tweening to the next position + for(std::vector::iterator c = components_.begin(); c != components_.end(); c++) + { + if(*c && (*c)->isMenuScrolling()) { readyToScroll = false; break; @@ -630,6 +632,8 @@ void ScrollingList::draw() void ScrollingList::draw(unsigned int layer) { + if(components_.size() == 0) return; + for(unsigned int i = 0; i < components_.size(); ++i) { Component *c = components_.at(i); @@ -666,7 +670,15 @@ void ScrollingList::removeComponentForNotifications(MenuNotifierInterface *c) bool ScrollingList::isIdle() { - return (Component::isIdle() && currentScrollState_ == ScrollStateIdle); + if(!Component::isIdle() || currentScrollState_ != ScrollStateIdle) return false; + + for(unsigned int i = 0; i < components_.size(); ++i) + { + Component *c = components_.at(i); + if(c && !c->isIdle()) return false; + } + + return true; } diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index 2522aa8..9680317 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -56,7 +56,7 @@ public: bool allocateTexture(unsigned int index, Item *i); void deallocateTexture(unsigned int index); - void setItems(CollectionInfo *info); + void setItems(std::vector *items); void destroyItems(); void setPoints(std::vector *scrollPoints, std::vector *tweenPoints); void setScrollDirection(ScrollDirection direction); @@ -123,11 +123,11 @@ private: Font *fontInst_; std::string layoutKey_; std::string imageType_; - CollectionInfo *collection_; std::vector *items_; std::vector components_; + }; diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index d16b578..9054507 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -23,13 +23,13 @@ #include "Component/ScrollingList.h" #include "../Sound/Sound.h" #include "ComponentItemBindingBuilder.h" +#include #include Page::Page(Configuration &config) : config_(config) , activeMenu_(NULL) , menuDepth_(0) - , items_(NULL) , scrollActive_(false) , selectedItem_(NULL) , textStatusComponent_(NULL) @@ -410,7 +410,6 @@ void Page::letterScroll(ScrollDirection direction) bool Page::pushCollection(CollectionInfo *collection) { - collections_.push_back(collection); int menuExitIndex = -1; int menuEnterIndex = -1; @@ -425,6 +424,7 @@ bool Page::pushCollection(CollectionInfo *collection) menuExitIndex = menuDepth_ - 1; } + // grow the menu as needed if(menus_.size() >= menuDepth_ && activeMenu_) { ScrollingList *newList = new ScrollingList(*activeMenu_); @@ -432,12 +432,21 @@ bool Page::pushCollection(CollectionInfo *collection) pushMenu(newList); } + activeMenu_ = menus_[menuDepth_]; activeMenu_->collectionName = collection->name; - activeMenu_->destroyItems(); - activeMenu_->setItems(collection); + activeMenu_->setItems(&collection->items); activeMenu_->triggerMenuEnterEvent(); - playlist_ = collection->playlists.begin(); + + // build the collection info instance + MenuInfo_S info; + info.collection = collection; + info.menu = activeMenu_; + info.playlist = collection->playlists.begin(); + info.queueDelete = false; + collections_.push_back(info); + + playlist_ = info.playlist; if(menuDepth_ < menus_.size()) { @@ -469,18 +478,19 @@ bool Page::popCollection() { int menuExitIndex = -1; int menuEnterIndex = -1; - CollectionInfo *collection = NULL; - if(menuDepth_ <= 1) - { - return false; - } - if(collections_.size() <= 1) - { - return false; - } + if(!activeMenu_) return false; + if(menuDepth_ <= 1) return false; + if(collections_.size() <= 1) return false; + + // queue the collection for deletion + MenuInfo_S &info = collections_.back(); + info.queueDelete = true; + + // get the next collection off of the stack collections_.pop_back(); - collection = collections_.back(); + info = collections_.back(); + playlist_ = info.playlist; if(activeMenu_) { @@ -500,7 +510,7 @@ bool Page::popCollection() { for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) { - (*it)->collectionName = collection->name; + (*it)->collectionName = info.collection->name; if(menuEnterIndex >= 0) { @@ -514,18 +524,25 @@ bool Page::popCollection() } } - return true; } void Page::nextPlaylist() { - CollectionInfo *collection = collections_.back(); - playlist_++; - if(playlist_ == collection->playlists.end()) playlist_ = collection->playlists.begin(); + MenuInfo_S &info = collections_.back(); + unsigned int numlists = info.collection->playlists.size(); - activeMenu_->destroyItems(); - activeMenu_->setItems(collection); + for(unsigned int i = 0; i <= numlists; ++i) + { + playlist_++; + // wrap + if(playlist_ == info.collection->playlists.end()) playlist_ = info.collection->playlists.begin(); + + // find the first playlist + if(playlist_->second->size() != 0) break; + } + + activeMenu_->setItems(playlist_->second); activeMenu_->triggerMenuEnterEvent(); } @@ -555,7 +572,28 @@ void Page::update(float dt) { for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) { - (*it)->update(dt); + if(*it) (*it)->update(dt); + } + } + + // many nodes still have handles on the collection info. We need to delete + // them once everything is done using them + std::list::iterator del = collections_.begin(); + + while(del != collections_.end()) + { + MenuInfo_S &info = *del; + if(info.queueDelete && info.menu && info.menu->isIdle()) + { + std::list::iterator next = del; + ++next; + + if(info.collection) delete info.collection; + collections_.erase(del); + } + else + { + ++del; } } } @@ -566,7 +604,7 @@ void Page::draw() { for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) { - (*it)->draw(); + if(*it) (*it)->draw(); } for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++) @@ -580,14 +618,11 @@ void Page::draw() std::string Page::getCollectionName() { - CollectionInfo *info = collections_.back(); + if(collections_.size() == 0) return ""; - if(info) - { - return info->name; - } + MenuInfo_S &info = collections_.back(); + return info.collection->name; - return ""; } void Page::freeGraphicsMemory() diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 2591d5e..cbf6406 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -84,17 +84,28 @@ private: void highlight(); std::string collectionName_; Configuration &config_; + + struct MenuInfo_S + { + CollectionInfo *collection; + ScrollingList *menu; + CollectionInfo::Playlists_T::iterator playlist; + bool queueDelete; + }; + typedef std::vector MenuVector_T; - typedef std::vector CollectionInfo_T; + typedef std::list CollectionVector_T; ScrollingList *activeMenu_; unsigned int menuDepth_; MenuVector_T menus_; - CollectionInfo_T collections_; + CollectionVector_T collections_; static const unsigned int NUM_LAYERS = 8; std::vector LayerComponents[NUM_LAYERS]; - std::vector *items_; + std::list deleteMenuList_; + std::list deleteCollectionList_; + bool scrollActive_; Item *selectedItem_;