MyGUI
3.2.1
|
00001 /* 00002 * This source file is part of MyGUI. For the latest info, see http://mygui.info/ 00003 * Distributed under the MIT License 00004 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT) 00005 */ 00006 00007 #include "MyGUI_Precompiled.h" 00008 #include "MyGUI_ResourceManager.h" 00009 #include "MyGUI_XmlDocument.h" 00010 #include "MyGUI_IResource.h" 00011 #include "MyGUI_DataManager.h" 00012 #include "MyGUI_FactoryManager.h" 00013 #include "MyGUI_DataStreamHolder.h" 00014 #include "MyGUI_ResourceImageSet.h" 00015 00016 namespace MyGUI 00017 { 00018 00019 template <> ResourceManager* Singleton<ResourceManager>::msInstance = nullptr; 00020 template <> const char* Singleton<ResourceManager>::mClassTypeName = "ResourceManager"; 00021 00022 ResourceManager::ResourceManager() : 00023 mIsInitialise(false), 00024 mCategoryName("Resource"), 00025 mXmlListTagName("List") 00026 { 00027 } 00028 00029 void ResourceManager::initialise() 00030 { 00031 MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice"); 00032 MYGUI_LOG(Info, "* Initialise: " << getClassTypeName()); 00033 00034 registerLoadXmlDelegate(mCategoryName) = newDelegate(this, &ResourceManager::loadFromXmlNode); 00035 registerLoadXmlDelegate(mXmlListTagName) = newDelegate(this, &ResourceManager::_loadList); 00036 00037 // регестрируем дефолтные ресурсы 00038 FactoryManager::getInstance().registerFactory<ResourceImageSet>(mCategoryName); 00039 00040 MYGUI_LOG(Info, getClassTypeName() << " successfully initialized"); 00041 mIsInitialise = true; 00042 } 00043 00044 void ResourceManager::shutdown() 00045 { 00046 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised"); 00047 MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName()); 00048 00049 FactoryManager::getInstance().unregisterFactory<ResourceImageSet>(mCategoryName); 00050 00051 clear(); 00052 unregisterLoadXmlDelegate(mCategoryName); 00053 unregisterLoadXmlDelegate(mXmlListTagName); 00054 00055 mMapLoadXmlDelegate.clear(); 00056 00057 MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown"); 00058 mIsInitialise = false; 00059 } 00060 00061 bool ResourceManager::load(const std::string& _file) 00062 { 00063 return _loadImplement(_file, false, "", getClassTypeName()); 00064 } 00065 00066 void ResourceManager::loadFromXmlNode(xml::ElementPtr _node, const std::string& _file, Version _version) 00067 { 00068 FactoryManager& factory = FactoryManager::getInstance(); 00069 00070 // берем детей и крутимся, основной цикл 00071 xml::ElementEnumerator root = _node->getElementEnumerator(); 00072 while (root.next(mCategoryName)) 00073 { 00074 // парсим атрибуты 00075 std::string type, name; 00076 root->findAttribute("type", type); 00077 root->findAttribute("name", name); 00078 00079 if (name.empty()) 00080 continue; 00081 00082 IObject* object = factory.createObject(mCategoryName, type); 00083 if (object == nullptr) 00084 { 00085 MYGUI_LOG(Error, "resource type '" << type << "' not found"); 00086 continue; 00087 } 00088 00089 MapResource::iterator item = mResources.find(name); 00090 if (item != mResources.end()) 00091 { 00092 MYGUI_LOG(Warning, "duplicate resource name '" << name << "'"); 00093 00094 // ресурсами могут пользоваться 00095 mRemovedResoures.push_back((*item).second); 00096 mResources.erase(item); 00097 } 00098 00099 IResourcePtr resource = object->castType<IResource>(); 00100 resource->deserialization(root.current(), _version); 00101 00102 mResources[name] = resource; 00103 } 00104 } 00105 00106 void ResourceManager::_loadList(xml::ElementPtr _node, const std::string& _file, Version _version) 00107 { 00108 // берем детей и крутимся, основной цикл 00109 xml::ElementEnumerator node = _node->getElementEnumerator(); 00110 while (node.next(mXmlListTagName)) 00111 { 00112 std::string source; 00113 if (!node->findAttribute("file", source)) continue; 00114 MYGUI_LOG(Info, "Load ini file '" << source << "'"); 00115 _loadImplement(source, false, "", getClassTypeName()); 00116 } 00117 } 00118 00119 ResourceManager::LoadXmlDelegate& ResourceManager::registerLoadXmlDelegate(const std::string& _key) 00120 { 00121 MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(_key); 00122 MYGUI_ASSERT(iter == mMapLoadXmlDelegate.end(), "name delegate is exist"); 00123 return (mMapLoadXmlDelegate[_key] = LoadXmlDelegate()); 00124 } 00125 00126 void ResourceManager::unregisterLoadXmlDelegate(const std::string& _key) 00127 { 00128 MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(_key); 00129 if (iter != mMapLoadXmlDelegate.end()) mMapLoadXmlDelegate.erase(iter); 00130 } 00131 00132 bool ResourceManager::_loadImplement(const std::string& _file, bool _match, const std::string& _type, const std::string& _instance) 00133 { 00134 DataStreamHolder data = DataManager::getInstance().getData(_file); 00135 if (data.getData() == nullptr) 00136 { 00137 MYGUI_LOG(Error, _instance << " : '" << _file << "', not found"); 00138 return false; 00139 } 00140 00141 xml::Document doc; 00142 if (!doc.open(data.getData())) 00143 { 00144 MYGUI_LOG(Error, _instance << " : '" << _file << "', " << doc.getLastError()); 00145 return false; 00146 } 00147 00148 xml::ElementPtr root = doc.getRoot(); 00149 if ( (nullptr == root) || (root->getName() != "MyGUI") ) 00150 { 00151 MYGUI_LOG(Error, _instance << " : '" << _file << "', tag 'MyGUI' not found"); 00152 return false; 00153 } 00154 00155 std::string type; 00156 if (root->findAttribute("type", type)) 00157 { 00158 Version version = Version::parse(root->findAttribute("version")); 00159 MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(type); 00160 if (iter != mMapLoadXmlDelegate.end()) 00161 { 00162 if ((!_match) || (type == _type)) 00163 (*iter).second(root, _file, version); 00164 else 00165 { 00166 MYGUI_LOG(Error, _instance << " : '" << _file << "', type '" << _type << "' not found"); 00167 return false; 00168 } 00169 } 00170 else 00171 { 00172 MYGUI_LOG(Error, _instance << " : '" << _file << "', delegate for type '" << type << "'not found"); 00173 return false; 00174 } 00175 } 00176 // предпологаем что будут вложенные 00177 else if (!_match) 00178 { 00179 xml::ElementEnumerator node = root->getElementEnumerator(); 00180 while (node.next("MyGUI")) 00181 { 00182 if (node->findAttribute("type", type)) 00183 { 00184 Version version = Version::parse(root->findAttribute("version")); 00185 MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(type); 00186 if (iter != mMapLoadXmlDelegate.end()) 00187 { 00188 (*iter).second(node.current(), _file, version); 00189 } 00190 else 00191 { 00192 MYGUI_LOG(Error, _instance << " : '" << _file << "', delegate for type '" << type << "'not found"); 00193 } 00194 } 00195 else 00196 { 00197 MYGUI_LOG(Error, _instance << " : '" << _file << "', tag 'type' not found"); 00198 } 00199 } 00200 } 00201 00202 return true; 00203 } 00204 00205 void ResourceManager::addResource(IResourcePtr _item) 00206 { 00207 if (!_item->getResourceName().empty()) 00208 mResources[_item->getResourceName()] = _item; 00209 } 00210 00211 void ResourceManager::removeResource(IResourcePtr _item) 00212 { 00213 if (_item == nullptr) 00214 return; 00215 00216 if (!_item->getResourceName().empty()) 00217 { 00218 MapResource::iterator item = mResources.find(_item->getResourceName()); 00219 if (item != mResources.end()) 00220 mResources.erase(item); 00221 } 00222 } 00223 00224 bool ResourceManager::isExist(const std::string& _name) const 00225 { 00226 return mResources.find(_name) != mResources.end(); 00227 } 00228 00229 IResource* ResourceManager::findByName(const std::string& _name) const 00230 { 00231 MapResource::const_iterator item = mResources.find(_name); 00232 return (item == mResources.end()) ? nullptr : item->second; 00233 } 00234 00235 IResource* ResourceManager::getByName(const std::string& _name, bool _throw) const 00236 { 00237 IResource* result = findByName(_name); 00238 MYGUI_ASSERT(result || !_throw, "Resource '" << _name << "' not found"); 00239 return result; 00240 } 00241 00242 bool ResourceManager::removeByName(const std::string& _name) 00243 { 00244 MapResource::const_iterator item = mResources.find(_name); 00245 if (item != mResources.end()) 00246 { 00247 delete item->second; 00248 mResources.erase(item->first); 00249 return true; 00250 } 00251 return false; 00252 } 00253 00254 void ResourceManager::clear() 00255 { 00256 for (MapResource::iterator item = mResources.begin(); item != mResources.end(); ++ item) 00257 delete item->second; 00258 mResources.clear(); 00259 00260 for (VectorResource::iterator item = mRemovedResoures.begin(); item != mRemovedResoures.end(); ++ item) 00261 delete (*item); 00262 mRemovedResoures.clear(); 00263 } 00264 00265 ResourceManager::EnumeratorPtr ResourceManager::getEnumerator() const 00266 { 00267 return EnumeratorPtr(mResources); 00268 } 00269 00270 size_t ResourceManager::getCount() const 00271 { 00272 return mResources.size(); 00273 } 00274 00275 const std::string& ResourceManager::getCategoryName() const 00276 { 00277 return mCategoryName; 00278 } 00279 00280 } // namespace MyGUI