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 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
00185 delete data;
00186
00187 return false;
00188 }
00189
00190
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 }