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