From 74ac6060ccb68e6ae80dbcb44d11f07a17e26034 Mon Sep 17 00:00:00 2001 From: that Date: Wed, 4 Mar 2015 22:39:34 +0100 Subject: gui: type safe resources part 2 - separate collections for fonts, images, animations - no more ugly casts - fix crash if main ui.xml did not define any resources but include did - don't stop loading resources if one "type" attribute is missing Change-Id: I70c1c9ca66ca65d9fba1ba3eded34f3d8a07488e --- gui/pages.cpp | 29 +++++++-------------- gui/pages.hpp | 5 ++-- gui/resources.cpp | 78 ++++++++++++++++++++++++++++++++++++------------------- gui/resources.hpp | 16 +++++------- 4 files changed, 69 insertions(+), 59 deletions(-) (limited to 'gui') diff --git a/gui/pages.cpp b/gui/pages.cpp index 18ddf9c33..cd5e340d6 100644 --- a/gui/pages.cpp +++ b/gui/pages.cpp @@ -208,8 +208,7 @@ FontResource* LoadAttrFont(xml_node<>* element, const char* attrname) if (name.empty()) return NULL; else - return (FontResource*) PageManager::FindResource(name); - // TODO: make resource lookup type-safe + return PageManager::GetResources()->FindFont(name); } ImageResource* LoadAttrImage(xml_node<>* element, const char* attrname) @@ -218,8 +217,7 @@ ImageResource* LoadAttrImage(xml_node<>* element, const char* attrname) if (name.empty()) return NULL; else - return (ImageResource*) PageManager::FindResource(name); - // TODO: make resource lookup type-safe + return PageManager::GetResources()->FindImage(name); } AnimationResource* LoadAttrAnimation(xml_node<>* element, const char* attrname) @@ -228,8 +226,7 @@ AnimationResource* LoadAttrAnimation(xml_node<>* element, const char* attrname) if (name.empty()) return NULL; else - return (AnimationResource*) PageManager::FindResource(name); - // TODO: make resource lookup type-safe + return PageManager::GetResources()->FindAnimation(name); } bool LoadPlacement(xml_node<>* node, int* x, int* y, int* w /* = NULL */, int* h /* = NULL */, RenderObject::Placement* placement /* = NULL */) @@ -649,7 +646,7 @@ int Page::NotifyVarChange(std::string varName, std::string value) PageSet::PageSet(char* xmlFile) { - mResources = NULL; + mResources = new ResourceManager; mCurrentPage = NULL; mOverlayPage = NULL; @@ -742,7 +739,7 @@ int PageSet::Load(ZipArchive* package) LOGINFO("Loading resources...\n"); child = parent->first_node("resources"); if (child) - mResources = new ResourceManager(child, package); + mResources->LoadResources(child, package); LOGINFO("Loading variables...\n"); child = parent->first_node("variables"); @@ -937,9 +934,9 @@ int PageSet::SetOverlay(Page* page) return 0; } -Resource* PageSet::FindResource(std::string name) +const ResourceManager* PageSet::GetResources() { - return mResources ? mResources->FindResource(name) : NULL; + return mResources; } Page* PageSet::FindPage(std::string name) @@ -1307,17 +1304,9 @@ int PageManager::ChangeOverlay(std::string name) } } -Resource* PageManager::FindResource(std::string name) +const ResourceManager* PageManager::GetResources() { - return (mCurrentSet ? mCurrentSet->FindResource(name) : NULL); -} - -Resource* PageManager::FindResource(std::string package, std::string name) -{ - PageSet* tmp; - - tmp = FindPackage(name); - return (tmp ? tmp->FindResource(name) : NULL); + return (mCurrentSet ? mCurrentSet->GetResources() : NULL); } int PageManager::SwitchToConsole(void) diff --git a/gui/pages.hpp b/gui/pages.hpp index 8eec9a951..50155d0e9 100644 --- a/gui/pages.hpp +++ b/gui/pages.hpp @@ -88,7 +88,7 @@ public: Page* FindPage(std::string name); int SetPage(std::string page); int SetOverlay(Page* page); - Resource* FindResource(std::string name); + const ResourceManager* GetResources(); // Helper routine for identifing if we're the current page int IsCurrentPage(Page* page); @@ -131,8 +131,7 @@ public: // Used for actions and pages static int ChangePage(std::string name); static int ChangeOverlay(std::string name); - static Resource* FindResource(std::string name); - static Resource* FindResource(std::string package, std::string name); + static const ResourceManager* GetResources(); // Used for console-only mode static int SwitchToConsole(void); diff --git a/gui/resources.cpp b/gui/resources.cpp index e0016fc7b..1e2e7f9c6 100644 --- a/gui/resources.cpp +++ b/gui/resources.cpp @@ -258,21 +258,32 @@ AnimationResource::~AnimationResource() mSurfaces.clear(); } -Resource* ResourceManager::FindResource(std::string name) +FontResource* ResourceManager::FindFont(const std::string& name) const { - std::vector::iterator iter; + for (std::vector::const_iterator it = mFonts.begin(); it != mFonts.end(); ++it) + if (name == (*it)->GetName()) + return *it; + return NULL; +} - for (iter = mResources.begin(); iter != mResources.end(); iter++) - { - if (name == (*iter)->GetName()) - return (*iter); - } +ImageResource* ResourceManager::FindImage(const std::string& name) const +{ + for (std::vector::const_iterator it = mImages.begin(); it != mImages.end(); ++it) + if (name == (*it)->GetName()) + return *it; return NULL; } -ResourceManager::ResourceManager(xml_node<>* resList, ZipArchive* pZip) +AnimationResource* ResourceManager::FindAnimation(const std::string& name) const +{ + for (std::vector::const_iterator it = mAnimations.begin(); it != mAnimations.end(); ++it) + if (name == (*it)->GetName()) + return *it; + return NULL; +} + +ResourceManager::ResourceManager() { - LoadResources(resList, pZip); } void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip) @@ -285,14 +296,18 @@ void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip) while (child != NULL) { xml_attribute<>* attr = child->first_attribute("type"); - if (!attr) - break; - Resource* res = NULL; - std::string type = attr->value(); + bool error = false; + std::string type = attr ? attr->value() : "*unspecified*"; if (type == "font") { - res = new FontResource(child, pZip); + FontResource* res = new FontResource(child, pZip); + if (res->GetResource()) + mFonts.push_back(res); + else { + error = true; + delete res; + } } else if (type == "image") { @@ -300,7 +315,13 @@ void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip) xml_attribute<>* retain_aspect_ratio = child->first_attribute("retainaspect"); if (retain_aspect_ratio) retain = 1; // the value does not matter, if retainaspect is present, we assume that we want to retain it - res = new ImageResource(child, pZip, retain); + ImageResource* res = new ImageResource(child, pZip, retain); + if (res->GetResource()) + mImages.push_back(res); + else { + error = true; + delete res; + } } else if (type == "animation") { @@ -308,14 +329,21 @@ void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip) xml_attribute<>* retain_aspect_ratio = child->first_attribute("retainaspect"); if (retain_aspect_ratio) retain = 1; // the value does not matter, if retainaspect is present, we assume that we want to retain it - res = new AnimationResource(child, pZip, retain); + AnimationResource* res = new AnimationResource(child, pZip, retain); + if (res->GetResourceCount()) + mAnimations.push_back(res); + else { + error = true; + delete res; + } } else { LOGERR("Resource type (%s) not supported.\n", type.c_str()); + error = true; } - if (res == NULL || !res->loadedOK()) + if (error) { std::string res_name; if (child->first_attribute("name")) @@ -327,12 +355,6 @@ void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip) LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str()); } else LOGERR("Resource type (%s) failed to load\n", type.c_str()); - - delete res; - } - else - { - mResources.push_back(res); } child = child->next_sibling("resource"); @@ -341,10 +363,12 @@ void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip) ResourceManager::~ResourceManager() { - std::vector::iterator iter; + for (std::vector::iterator it = mFonts.begin(); it != mFonts.end(); ++it) + delete *it; - for (iter = mResources.begin(); iter != mResources.end(); iter++) - delete *iter; + for (std::vector::iterator it = mImages.begin(); it != mImages.end(); ++it) + delete *it; - mResources.clear(); + for (std::vector::iterator it = mAnimations.begin(); it != mAnimations.end(); ++it) + delete *it; } diff --git a/gui/resources.hpp b/gui/resources.hpp index 69d24279f..83fc7a537 100644 --- a/gui/resources.hpp +++ b/gui/resources.hpp @@ -18,7 +18,6 @@ public: public: std::string GetName() { return mName; } - virtual bool loadedOK() = 0; private: std::string mName; @@ -47,8 +46,6 @@ public: void* GetResource() { return this ? mFont : NULL; } int GetHeight() { return gr_getMaxFontHeight(this ? mFont : NULL); } - virtual bool loadedOK() { return mFont != NULL; } - protected: void* mFont; Type m_type; @@ -65,8 +62,6 @@ public: int GetWidth() { return gr_get_width(this ? mSurface : NULL); } int GetHeight() { return gr_get_height(this ? mSurface : NULL); } - virtual bool loadedOK() { return mSurface != NULL; } - protected: gr_surface mSurface; }; @@ -83,7 +78,6 @@ public: int GetWidth() { return gr_get_width(this ? GetResource() : NULL); } int GetHeight() { return gr_get_height(this ? GetResource() : NULL); } int GetResourceCount() { return mSurfaces.size(); } - virtual bool loadedOK() { return !mSurfaces.empty(); } protected: std::vector mSurfaces; @@ -92,15 +86,19 @@ protected: class ResourceManager { public: - ResourceManager(xml_node<>* resList, ZipArchive* pZip); + ResourceManager(); virtual ~ResourceManager(); void LoadResources(xml_node<>* resList, ZipArchive* pZip); public: - Resource* FindResource(std::string name); + FontResource* FindFont(const std::string& name) const; + ImageResource* FindImage(const std::string& name) const; + AnimationResource* FindAnimation(const std::string& name) const; private: - std::vector mResources; + std::vector mFonts; + std::vector mImages; + std::vector mAnimations; }; #endif // _RESOURCE_HEADER -- cgit v1.2.3