MyGUI  3.0.3
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 
00064         for (VectorResource::iterator item = mRemovedResoures.begin(); item != mRemovedResoures.end(); ++ item)
00065             delete (*item);
00066         mRemovedResoures.clear();
00067 
00068         unregisterLoadXmlDelegate(XML_TYPE);
00069         unregisterLoadXmlDelegate(XML_TYPE_LIST);
00070 
00071         mMapLoadXmlDelegate.clear();
00072 
00073         MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully shutdown");
00074         mIsInitialise = false;
00075     }
00076 
00077     bool ResourceManager::load(const std::string& _file)
00078     {
00079         return _loadImplement(_file, false, "", INSTANCE_TYPE_NAME);
00080     }
00081 
00082     void ResourceManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
00083     {
00084         FactoryManager& factory = FactoryManager::getInstance();
00085 
00086         VectorGuid vector_guid;
00087         // берем детей и крутимся, основной цикл
00088         xml::ElementEnumerator root = _node->getElementEnumerator();
00089         while (root.next(XML_TYPE))
00090         {
00091             // парсим атрибуты
00092             std::string id, type, name;
00093             root->findAttribute("type", type);
00094             root->findAttribute("name", name);
00095             root->findAttribute("id", id);
00096 
00097             if (name.empty())
00098                 continue;
00099 
00100             Guid guid(id);
00101             if (!guid.empty())
00102             {
00103                 if (mResourcesID.find(guid) != mResourcesID.end())
00104                 {
00105                     MYGUI_LOG(Warning, "dublicate resource id " << guid.print());
00106                 }
00107             }
00108 
00109             MapResource::iterator item = mResources.find(name);
00110             if (item != mResources.end())
00111             {
00112                 MYGUI_LOG(Warning, "dublicate resource name '" << name << "'");
00113 
00114                 // ресурсами могут пользоваться
00115                 mRemovedResoures.push_back((*item).second);
00116                 mResources.erase(item);
00117             }
00118 
00119             vector_guid.push_back(guid);
00120 
00121             IObject* object = factory.createObject(XML_TYPE, type);
00122             if (object == nullptr)
00123             {
00124                 MYGUI_LOG(Error, "resource type '" << type << "' not found");
00125                 continue;
00126             }
00127 
00128             IResourcePtr resource = object->castType<IResource>();
00129             resource->deserialization(root.current(), _version);
00130 
00131             if (!guid.empty()) mResourcesID[guid] = resource;
00132             mResources[name] = resource;
00133         }
00134 
00135         if (!vector_guid.empty())
00136         {
00137             mListFileGuid[_file] = vector_guid;
00138         }
00139 
00140     }
00141 
00142     std::string ResourceManager::getFileNameByID(const Guid& _id)
00143     {
00144         for (MapVectorString::iterator item=mListFileGuid.begin(); item!=mListFileGuid.end(); ++item)
00145         {
00146             for (VectorGuid::iterator item2=item->second.begin(); item2!=item->second.end(); ++item2)
00147             {
00148                 if (*item2 == _id)
00149                 {
00150                     return item->first;
00151                 }
00152             }
00153         }
00154         return "";
00155     }
00156 
00157     void ResourceManager::_loadList(xml::ElementPtr _node, const std::string& _file, Version _version)
00158     {
00159         // берем детей и крутимся, основной цикл
00160         xml::ElementEnumerator node = _node->getElementEnumerator();
00161         while (node.next(XML_TYPE_LIST))
00162         {
00163             std::string source;
00164             if (!node->findAttribute("file", source)) continue;
00165             MYGUI_LOG(Info, "Load ini file '" << source << "'");
00166             _loadImplement(source, false, "", INSTANCE_TYPE_NAME);
00167         }
00168     }
00169 
00170     ResourceManager::LoadXmlDelegate& ResourceManager::registerLoadXmlDelegate(const std::string& _key)
00171     {
00172         MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(_key);
00173         MYGUI_ASSERT(iter == mMapLoadXmlDelegate.end(), "name delegate is exist");
00174         return (mMapLoadXmlDelegate[_key] = LoadXmlDelegate());
00175     }
00176 
00177     void ResourceManager::unregisterLoadXmlDelegate(const std::string& _key)
00178     {
00179         MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(_key);
00180         if (iter != mMapLoadXmlDelegate.end()) mMapLoadXmlDelegate.erase(iter);
00181     }
00182 
00183     bool ResourceManager::_loadImplement(const std::string& _file, bool _match, const std::string& _type, const std::string& _instance)
00184     {
00185         IDataStream* data = DataManager::getInstance().getData(_file);
00186         if (data == nullptr)
00187         {
00188             MYGUI_LOG(Error, _instance << " : '" << _file << "', not found");
00189             return false;
00190         }
00191 
00192         xml::Document doc;
00193         if (!doc.open(data))
00194         {
00195             MYGUI_LOG(Error, _instance << " : '" << _file << "', " << doc.getLastError());
00196 
00197             // FIXME
00198             delete data;
00199 
00200             return false;
00201         }
00202 
00203         // FIXME
00204         delete data;
00205 
00206         xml::ElementPtr root = doc.getRoot();
00207         if ( (nullptr == root) || (root->getName() != "MyGUI") )
00208         {
00209             MYGUI_LOG(Error, _instance << " : '" << _file << "', tag 'MyGUI' not found");
00210             return false;
00211         }
00212 
00213         std::string type;
00214         if (root->findAttribute("type", type))
00215         {
00216             Version version = Version::parse(root->findAttribute("version"));
00217             MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(type);
00218             if (iter != mMapLoadXmlDelegate.end())
00219             {
00220                 if ((!_match) || (type == _type)) (*iter).second(root, _file, version);
00221                 else
00222                 {
00223                     MYGUI_LOG(Error, _instance << " : '" << _file << "', type '" << _type << "' not found");
00224                     return false;
00225                 }
00226             }
00227             else
00228             {
00229                 MYGUI_LOG(Error, _instance << " : '" << _file << "', delegate for type '" << type << "'not found");
00230                 return false;
00231             }
00232         }
00233         // предпологаем что будут вложенные
00234         else if (!_match)
00235         {
00236             xml::ElementEnumerator node = root->getElementEnumerator();
00237             while (node.next("MyGUI"))
00238             {
00239                 if (node->findAttribute("type", type))
00240                 {
00241                     Version version = Version::parse(root->findAttribute("version"));
00242                     MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(type);
00243                     if (iter != mMapLoadXmlDelegate.end())
00244                     {
00245                         (*iter).second(node.current(), _file, version);
00246                     }
00247                     else
00248                     {
00249                         MYGUI_LOG(Error, _instance << " : '" << _file << "', delegate for type '" << type << "'not found");
00250                     }
00251                 }
00252                 else
00253                 {
00254                     MYGUI_LOG(Error, _instance << " : '" << _file << "', tag 'type' not found");
00255                 }
00256             }
00257         }
00258 
00259         return true;
00260     }
00261 
00262     IResourcePtr ResourceManager::getByID(const Guid& _id, bool _throw)
00263     {
00264         MapResourceID::iterator iter = mResourcesID.find(_id);
00265         if (iter == mResourcesID.end())
00266         {
00267             if (_throw) MYGUI_EXCEPT("resource '" << _id.print() << "' not found");
00268             MYGUI_LOG(Warning, "resource '" << _id.print() << "' not found");
00269             return nullptr;
00270         }
00271         return iter->second;
00272     }
00273 
00274     void ResourceManager::addResource(IResourcePtr _item)
00275     {
00276         if (!_item->getResourceName().empty())
00277         {
00278             MapResource::iterator item = mResources.find(_item->getResourceName());
00279             if (item != mResources.end())
00280             {
00281                 MYGUI_LOG(Warning, "dublicate resource name '" << _item->getResourceName() << "'");
00282 
00283                 // ресурсами могут пользоваться
00284                 mRemovedResoures.push_back((*item).second);
00285                 mResources.erase(item);
00286             }
00287 
00288             mResources[_item->getResourceName()] = _item;
00289         }
00290         else
00291         {
00292             delete _item;
00293             return;
00294         }
00295 
00296 
00297         if (!_item->getResourceID().empty())
00298             mResourcesID[_item->getResourceID()] = _item;
00299     }
00300 
00301     /*void ResourceManager::removeResource(IResourcePtr _item)
00302     {
00303         if (_item == nullptr) return;
00304 
00305         if (!_item->getResourceName().empty())
00306         {
00307             MapResource::iterator item = mResources.find(_item->getResourceName());
00308             if (item != mResources.end())
00309                 mResources.erase(item);
00310         }
00311 
00312         if (!_item->getResourceID().empty())
00313         {
00314             MapResourceID::iterator id = mResourcesID.find(_item->getResourceID());
00315             if (id != mResourcesID.end())
00316                 mResourcesID.erase(id);
00317         }
00318     }*/
00319 
00320 } // namespace MyGUI