MyGUI  3.2.1
MyGUI_ResourceManager.cpp
Go to the documentation of this file.
00001 /*
00002  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
00003  * Distributed under the MIT License
00004  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
00005  */
00006 
00007 #include "MyGUI_Precompiled.h"
00008 #include "MyGUI_ResourceManager.h"
00009 #include "MyGUI_XmlDocument.h"
00010 #include "MyGUI_IResource.h"
00011 #include "MyGUI_DataManager.h"
00012 #include "MyGUI_FactoryManager.h"
00013 #include "MyGUI_DataStreamHolder.h"
00014 #include "MyGUI_ResourceImageSet.h"
00015 
00016 namespace MyGUI
00017 {
00018 
00019     template <> ResourceManager* Singleton<ResourceManager>::msInstance = nullptr;
00020     template <> const char* Singleton<ResourceManager>::mClassTypeName = "ResourceManager";
00021 
00022     ResourceManager::ResourceManager() :
00023         mIsInitialise(false),
00024         mCategoryName("Resource"),
00025         mXmlListTagName("List")
00026     {
00027     }
00028 
00029     void ResourceManager::initialise()
00030     {
00031         MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
00032         MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
00033 
00034         registerLoadXmlDelegate(mCategoryName) = newDelegate(this, &ResourceManager::loadFromXmlNode);
00035         registerLoadXmlDelegate(mXmlListTagName) = newDelegate(this, &ResourceManager::_loadList);
00036 
00037         // регестрируем дефолтные ресурсы
00038         FactoryManager::getInstance().registerFactory<ResourceImageSet>(mCategoryName);
00039 
00040         MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
00041         mIsInitialise = true;
00042     }
00043 
00044     void ResourceManager::shutdown()
00045     {
00046         MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
00047         MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
00048 
00049         FactoryManager::getInstance().unregisterFactory<ResourceImageSet>(mCategoryName);
00050 
00051         clear();
00052         unregisterLoadXmlDelegate(mCategoryName);
00053         unregisterLoadXmlDelegate(mXmlListTagName);
00054 
00055         mMapLoadXmlDelegate.clear();
00056 
00057         MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
00058         mIsInitialise = false;
00059     }
00060 
00061     bool ResourceManager::load(const std::string& _file)
00062     {
00063         return _loadImplement(_file, false, "", getClassTypeName());
00064     }
00065 
00066     void ResourceManager::loadFromXmlNode(xml::ElementPtr _node, const std::string& _file, Version _version)
00067     {
00068         FactoryManager& factory = FactoryManager::getInstance();
00069 
00070         // берем детей и крутимся, основной цикл
00071         xml::ElementEnumerator root = _node->getElementEnumerator();
00072         while (root.next(mCategoryName))
00073         {
00074             // парсим атрибуты
00075             std::string type, name;
00076             root->findAttribute("type", type);
00077             root->findAttribute("name", name);
00078 
00079             if (name.empty())
00080                 continue;
00081 
00082             IObject* object = factory.createObject(mCategoryName, type);
00083             if (object == nullptr)
00084             {
00085                 MYGUI_LOG(Error, "resource type '" << type << "' not found");
00086                 continue;
00087             }
00088 
00089             MapResource::iterator item = mResources.find(name);
00090             if (item != mResources.end())
00091             {
00092                 MYGUI_LOG(Warning, "duplicate resource name '" << name << "'");
00093 
00094                 // ресурсами могут пользоваться
00095                 mRemovedResoures.push_back((*item).second);
00096                 mResources.erase(item);
00097             }
00098 
00099             IResourcePtr resource = object->castType<IResource>();
00100             resource->deserialization(root.current(), _version);
00101 
00102             mResources[name] = resource;
00103         }
00104     }
00105 
00106     void ResourceManager::_loadList(xml::ElementPtr _node, const std::string& _file, Version _version)
00107     {
00108         // берем детей и крутимся, основной цикл
00109         xml::ElementEnumerator node = _node->getElementEnumerator();
00110         while (node.next(mXmlListTagName))
00111         {
00112             std::string source;
00113             if (!node->findAttribute("file", source)) continue;
00114             MYGUI_LOG(Info, "Load ini file '" << source << "'");
00115             _loadImplement(source, false, "", getClassTypeName());
00116         }
00117     }
00118 
00119     ResourceManager::LoadXmlDelegate& ResourceManager::registerLoadXmlDelegate(const std::string& _key)
00120     {
00121         MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(_key);
00122         MYGUI_ASSERT(iter == mMapLoadXmlDelegate.end(), "name delegate is exist");
00123         return (mMapLoadXmlDelegate[_key] = LoadXmlDelegate());
00124     }
00125 
00126     void ResourceManager::unregisterLoadXmlDelegate(const std::string& _key)
00127     {
00128         MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(_key);
00129         if (iter != mMapLoadXmlDelegate.end()) mMapLoadXmlDelegate.erase(iter);
00130     }
00131 
00132     bool ResourceManager::_loadImplement(const std::string& _file, bool _match, const std::string& _type, const std::string& _instance)
00133     {
00134         DataStreamHolder data = DataManager::getInstance().getData(_file);
00135         if (data.getData() == nullptr)
00136         {
00137             MYGUI_LOG(Error, _instance << " : '" << _file << "', not found");
00138             return false;
00139         }
00140 
00141         xml::Document doc;
00142         if (!doc.open(data.getData()))
00143         {
00144             MYGUI_LOG(Error, _instance << " : '" << _file << "', " << doc.getLastError());
00145             return false;
00146         }
00147 
00148         xml::ElementPtr root = doc.getRoot();
00149         if ( (nullptr == root) || (root->getName() != "MyGUI") )
00150         {
00151             MYGUI_LOG(Error, _instance << " : '" << _file << "', tag 'MyGUI' not found");
00152             return false;
00153         }
00154 
00155         std::string type;
00156         if (root->findAttribute("type", type))
00157         {
00158             Version version = Version::parse(root->findAttribute("version"));
00159             MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(type);
00160             if (iter != mMapLoadXmlDelegate.end())
00161             {
00162                 if ((!_match) || (type == _type))
00163                     (*iter).second(root, _file, version);
00164                 else
00165                 {
00166                     MYGUI_LOG(Error, _instance << " : '" << _file << "', type '" << _type << "' not found");
00167                     return false;
00168                 }
00169             }
00170             else
00171             {
00172                 MYGUI_LOG(Error, _instance << " : '" << _file << "', delegate for type '" << type << "'not found");
00173                 return false;
00174             }
00175         }
00176         // предпологаем что будут вложенные
00177         else if (!_match)
00178         {
00179             xml::ElementEnumerator node = root->getElementEnumerator();
00180             while (node.next("MyGUI"))
00181             {
00182                 if (node->findAttribute("type", type))
00183                 {
00184                     Version version = Version::parse(root->findAttribute("version"));
00185                     MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(type);
00186                     if (iter != mMapLoadXmlDelegate.end())
00187                     {
00188                         (*iter).second(node.current(), _file, version);
00189                     }
00190                     else
00191                     {
00192                         MYGUI_LOG(Error, _instance << " : '" << _file << "', delegate for type '" << type << "'not found");
00193                     }
00194                 }
00195                 else
00196                 {
00197                     MYGUI_LOG(Error, _instance << " : '" << _file << "', tag 'type' not found");
00198                 }
00199             }
00200         }
00201 
00202         return true;
00203     }
00204 
00205     void ResourceManager::addResource(IResourcePtr _item)
00206     {
00207         if (!_item->getResourceName().empty())
00208             mResources[_item->getResourceName()] = _item;
00209     }
00210 
00211     void ResourceManager::removeResource(IResourcePtr _item)
00212     {
00213         if (_item == nullptr)
00214             return;
00215 
00216         if (!_item->getResourceName().empty())
00217         {
00218             MapResource::iterator item = mResources.find(_item->getResourceName());
00219             if (item != mResources.end())
00220                 mResources.erase(item);
00221         }
00222     }
00223 
00224     bool ResourceManager::isExist(const std::string& _name) const
00225     {
00226         return mResources.find(_name) != mResources.end();
00227     }
00228 
00229     IResource* ResourceManager::findByName(const std::string& _name) const
00230     {
00231         MapResource::const_iterator item = mResources.find(_name);
00232         return (item == mResources.end()) ? nullptr : item->second;
00233     }
00234 
00235     IResource* ResourceManager::getByName(const std::string& _name, bool _throw) const
00236     {
00237         IResource* result = findByName(_name);
00238         MYGUI_ASSERT(result || !_throw, "Resource '" << _name << "' not found");
00239         return result;
00240     }
00241 
00242     bool ResourceManager::removeByName(const std::string& _name)
00243     {
00244         MapResource::const_iterator item = mResources.find(_name);
00245         if (item != mResources.end())
00246         {
00247             delete item->second;
00248             mResources.erase(item->first);
00249             return true;
00250         }
00251         return false;
00252     }
00253 
00254     void ResourceManager::clear()
00255     {
00256         for (MapResource::iterator item = mResources.begin(); item != mResources.end(); ++ item)
00257             delete item->second;
00258         mResources.clear();
00259 
00260         for (VectorResource::iterator item = mRemovedResoures.begin(); item != mRemovedResoures.end(); ++ item)
00261             delete (*item);
00262         mRemovedResoures.clear();
00263     }
00264 
00265     ResourceManager::EnumeratorPtr ResourceManager::getEnumerator() const
00266     {
00267         return EnumeratorPtr(mResources);
00268     }
00269 
00270     size_t ResourceManager::getCount() const
00271     {
00272         return mResources.size();
00273     }
00274 
00275     const std::string& ResourceManager::getCategoryName() const
00276     {
00277         return mCategoryName;
00278     }
00279 
00280 } // namespace MyGUI