MyGUI
3.2.0
|
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