MyGUI 3.4.3
MyGUI_ResourceManager.cpp
Go to the documentation of this file.
1/*
2 * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3 * Distributed under the MIT License
4 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5 */
6
7#include "MyGUI_Precompiled.h"
9#include "MyGUI_XmlDocument.h"
10#include "MyGUI_IResource.h"
11#include "MyGUI_DataManager.h"
15
16namespace MyGUI
17{
18
20
22 mCategoryName("Resource"),
23 mXmlListTagName("List"),
24 mSingletonHolder(this)
25 {
26 }
27
29 {
30 MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
31 MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
32
34 registerLoadXmlDelegate(mXmlListTagName) = newDelegate(this, &ResourceManager::_loadList);
35
36 // регестрируем дефолтные ресурсы
38
39 MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
40 mIsInitialise = true;
41 }
42
44 {
45 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
46 MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
47
49
50 clear();
51 unregisterLoadXmlDelegate(mCategoryName);
52 unregisterLoadXmlDelegate(mXmlListTagName);
53
54 mMapLoadXmlDelegate.clear();
55
56 MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
57 mIsInitialise = false;
58 }
59
60 bool ResourceManager::load(const std::string& _file)
61 {
62 return _loadImplement(_file, false, {}, getClassTypeName());
63 }
64
65 void ResourceManager::loadFromXmlNode(xml::ElementPtr _node, std::string_view /*unused*/, Version _version)
66 {
68
69 // берем детей и крутимся, основной цикл
71 while (root.next(mCategoryName))
72 {
73 // парсим атрибуты
74 std::string type;
75 std::string name;
76 root->findAttribute("type", type);
77 root->findAttribute("name", name);
78
79 if (name.empty())
80 continue;
81
82 IObject* object = factory.createObject(mCategoryName, type);
83 if (object == nullptr)
84 {
85 MYGUI_LOG(Error, "resource type '" << type << "' not found");
86 continue;
87 }
88
89 MapResource::iterator item = mResources.find(name);
90 if (item != mResources.end())
91 {
92 MYGUI_LOG(Warning, "duplicate resource name '" << name << "'");
93
94 // ресурсами могут пользоваться
95 mRemovedResources.push_back((*item).second);
96 mResources.erase(item);
97 }
98
99 IResourcePtr resource = object->castType<IResource>();
100 resource->deserialization(root.current(), _version);
101
102 mResources[name] = resource;
103 }
104 }
105
106 void ResourceManager::_loadList(xml::ElementPtr _node, std::string_view /*unused*/, Version _version)
107 {
108 // берем детей и крутимся, основной цикл
110 while (node.next(mXmlListTagName))
111 {
112 std::string source;
113 if (!node->findAttribute("file", source))
114 continue;
115 MYGUI_LOG(Info, "Load ini file '" << source << "'");
116 _loadImplement(source, false, {}, getClassTypeName());
117 }
118 }
119
121 {
122 MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(_key);
123 MYGUI_ASSERT(iter == mMapLoadXmlDelegate.end(), "name delegate is exist");
124 return mMapLoadXmlDelegate.emplace(_key, LoadXmlDelegate()).first->second;
125 }
126
128 {
129 MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(_key);
130 if (iter != mMapLoadXmlDelegate.end())
131 mMapLoadXmlDelegate.erase(iter);
132 }
133
134 bool ResourceManager::_loadImplement(
135 const std::string& _file,
136 bool _match,
137 std::string_view _type,
138 std::string_view _instance)
139 {
141 if (data.getData() == nullptr)
142 {
143 MYGUI_LOG(Error, _instance << " : '" << _file << "', not found");
144 return false;
145 }
146
147 xml::Document doc;
148 if (!doc.open(data.getData()))
149 {
150 MYGUI_LOG(Error, _instance << " : '" << _file << "', " << doc.getLastError());
151 return false;
152 }
153
154 xml::ElementPtr root = doc.getRoot();
155 if ((nullptr == root) || (root->getName() != "MyGUI"))
156 {
157 MYGUI_LOG(Error, _instance << " : '" << _file << "', tag 'MyGUI' not found");
158 return false;
159 }
160
161 std::string type;
162 if (root->findAttribute("type", type))
163 {
164 Version version = Version::parse(root->findAttribute("version"));
165 MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(type);
166 if (iter != mMapLoadXmlDelegate.end())
167 {
168 if ((!_match) || (type == _type))
169 (*iter).second(root, _file, version);
170 else
171 {
172 MYGUI_LOG(Error, _instance << " : '" << _file << "', type '" << _type << "' not found");
173 return false;
174 }
175 }
176 else
177 {
178 MYGUI_LOG(Error, _instance << " : '" << _file << "', delegate for type '" << type << "'not found");
179 return false;
180 }
181 }
182 // предпологаем что будут вложенные
183 else if (!_match)
184 {
185 xml::ElementEnumerator node = root->getElementEnumerator();
186 while (node.next("MyGUI"))
187 {
188 if (node->findAttribute("type", type))
189 {
190 Version version = Version::parse(root->findAttribute("version"));
191 MapLoadXmlDelegate::iterator iter = mMapLoadXmlDelegate.find(type);
192 if (iter != mMapLoadXmlDelegate.end())
193 {
194 (*iter).second(node.current(), _file, version);
195 }
196 else
197 {
198 MYGUI_LOG(
199 Error,
200 _instance << " : '" << _file << "', delegate for type '" << type << "'not found");
201 }
202 }
203 else
204 {
205 MYGUI_LOG(Error, _instance << " : '" << _file << "', tag 'type' not found");
206 }
207 }
208 }
209
210 return true;
211 }
212
214 {
215 if (!_item->getResourceName().empty())
216 mResources[_item->getResourceName()] = _item;
217 }
218
220 {
221 if (_item == nullptr)
222 return;
223
224 if (!_item->getResourceName().empty())
225 {
226 MapResource::iterator item = mResources.find(_item->getResourceName());
227 if (item != mResources.end())
228 mResources.erase(item);
229 }
230 }
231
232 bool ResourceManager::isExist(std::string_view _name) const
233 {
234 return mResources.find(_name) != mResources.end();
235 }
236
237 IResource* ResourceManager::findByName(std::string_view _name) const
238 {
239 MapResource::const_iterator item = mResources.find(_name);
240 return (item == mResources.end()) ? nullptr : item->second;
241 }
242
243 IResource* ResourceManager::getByName(std::string_view _name, bool _throw) const
244 {
245 IResource* result = findByName(_name);
246 MYGUI_ASSERT(result || !_throw, "Resource '" << _name << "' not found");
247 return result;
248 }
249
250 bool ResourceManager::removeByName(std::string_view _name)
251 {
252 MapResource::const_iterator item = mResources.find(_name);
253 if (item != mResources.end())
254 {
255 delete item->second;
256 mResources.erase(item->first);
257 return true;
258 }
259 return false;
260 }
261
263 {
264 for (auto& resource : mResources)
265 delete resource.second;
266 mResources.clear();
267
268 for (auto& removedResource : mRemovedResources)
269 delete removedResource;
270 mRemovedResources.clear();
271 }
272
277
279 {
280 return mResources.size();
281 }
282
283 const std::string& ResourceManager::getCategoryName() const
284 {
285 return mCategoryName;
286 }
287
288} // namespace MyGUI
#define MYGUI_ASSERT(exp, dest)
#define MYGUI_LOG(level, text)
#define MYGUI_SINGLETON_DEFINITION(ClassName)
virtual IDataStream * getData(const std::string &_name) const =0
static DataManager & getInstance()
void registerFactory(std::string_view _category, std::string_view _type, Delegate::IDelegate *_delegate)
static FactoryManager & getInstance()
void unregisterFactory(std::string_view _category, std::string_view _type)
IObject * createObject(std::string_view _category, std::string_view _type)
Type * castType(bool _throw=true)
void deserialization(xml::ElementPtr _node, Version) override
const std::string & getResourceName() const
void unregisterLoadXmlDelegate(std::string_view _key)
const std::string & getCategoryName() const
bool isExist(std::string_view _name) const
void removeResource(IResourcePtr _item)
LoadXmlDelegate & registerLoadXmlDelegate(std::string_view _key)
void loadFromXmlNode(xml::ElementPtr _node, std::string_view _file, Version _version)
IResource * getByName(std::string_view _name, bool _throw=true) const
static std::string_view getClassTypeName()
EnumeratorPtr getEnumerator() const
Enumerator< MapResource > EnumeratorPtr
bool load(const std::string &_file)
IResource * findByName(std::string_view _name) const
bool removeByName(std::string_view _name)
EventPairConvertStringView< delegates::Delegate< xml::ElementPtr, const std::string &, Version >, delegates::Delegate< xml::ElementPtr, std::string_view, Version > > LoadXmlDelegate
void addResource(IResourcePtr _item)
static Version parse(std::string_view _value)
bool findAttribute(std::string_view _name, std::string &_value)
ElementEnumerator getElementEnumerator()
Element * ElementPtr
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))