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