00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00198 delete data;
00199
00200 return false;
00201 }
00202
00203
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
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 }