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