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