00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _CEGUINamedXMLResourceManager_h_
00029 #define _CEGUINamedXMLResourceManager_h_
00030
00031 #include "CEGUIEventSet.h"
00032 #include "CEGUIString.h"
00033 #include "CEGUIExceptions.h"
00034 #include "CEGUILogger.h"
00035 #include "CEGUIInputEvent.h"
00036 #include "CEGUISystem.h"
00037 #include <map>
00038
00039
00040 namespace CEGUI
00041 {
00043 enum XMLResourceExistsAction
00044 {
00046 XREA_RETURN,
00048 XREA_REPLACE,
00050 XREA_THROW
00051 };
00052
00053
00054
00056 class CEGUIEXPORT ResourceEventSet : public EventSet
00057 {
00058 public:
00060 static const String EventNamespace;
00067 static const String EventResourceCreated;
00074 static const String EventResourceDestroyed;
00081 static const String EventResourceReplaced;
00082 };
00083
00084
00085
00108 template<typename T, typename U>
00109 class NamedXMLResourceManager : public ResourceEventSet
00110 {
00111 public:
00121 NamedXMLResourceManager(const String& resource_type);
00122
00124 virtual ~NamedXMLResourceManager();
00125
00148 T& create(const String& xml_filename, const String& resource_group = "",
00149 XMLResourceExistsAction action = XREA_RETURN);
00150
00159 void destroy(const String& object_name);
00160
00170 void destroy(const T& object);
00171
00173 void destroyAll();
00174
00185 T& get(const String& object_name) const;
00186
00188 bool isDefined(const String& object_name) const;
00189
00191 void createAll(const String& pattern, const String& resource_group);
00192
00193 protected:
00195 typedef std::map<String, T*, String::FastLessCompare> ObjectRegistry;
00197 void destroyObject(typename ObjectRegistry::iterator ob);
00199 T& doExistingObjectAction(const String object_name, T* object,
00200 const XMLResourceExistsAction action);
00202 virtual void doPostObjectAdditionAction(T& object);
00204 const String d_resourceType;
00206 ObjectRegistry d_objects;
00207 };
00208
00209
00210 template<typename T, typename U>
00211 NamedXMLResourceManager<T, U>::NamedXMLResourceManager(
00212 const String& resource_type) :
00213 d_resourceType(resource_type)
00214 {
00215 }
00216
00217
00218 template<typename T, typename U>
00219 NamedXMLResourceManager<T, U>::~NamedXMLResourceManager()
00220 {
00221 }
00222
00223
00224 template<typename T, typename U>
00225 T& NamedXMLResourceManager<T, U>::create(const String& xml_filename,
00226 const String& resource_group,
00227 XMLResourceExistsAction action)
00228 {
00229 U xml_loader(xml_filename, resource_group);
00230 return doExistingObjectAction(xml_loader.getObjectName(),
00231 &xml_loader.getObject(), action);
00232 }
00233
00234
00235 template<typename T, typename U>
00236 void NamedXMLResourceManager<T, U>::destroy(const String& object_name)
00237 {
00238 typename ObjectRegistry::iterator i(d_objects.find(object_name));
00239
00240
00241 if (i == d_objects.end())
00242 return;
00243
00244 destroyObject(i);
00245 }
00246
00247
00248 template<typename T, typename U>
00249 void NamedXMLResourceManager<T, U>::destroy(const T& object)
00250 {
00251
00252
00253 typename ObjectRegistry::iterator i(d_objects.begin());
00254 for (; i != d_objects.end(); ++i)
00255 if (i->second == &object)
00256 {
00257 destroyObject(i);
00258 return;
00259 }
00260 }
00261
00262
00263 template<typename T, typename U>
00264 void NamedXMLResourceManager<T, U>::destroyAll()
00265 {
00266 while (!d_objects.empty())
00267 destroyObject(d_objects.begin());
00268 }
00269
00270
00271 template<typename T, typename U>
00272 T& NamedXMLResourceManager<T, U>::get(const String& object_name) const
00273 {
00274 typename ObjectRegistry::const_iterator i(d_objects.find(object_name));
00275
00276 if (i == d_objects.end())
00277 CEGUI_THROW(UnknownObjectException("NamedXMLResourceManager::get: "
00278 "No object of type '" + d_resourceType + "' named '" + object_name +
00279 "' is present in the collection."));
00280
00281 return *i->second;
00282 }
00283
00284
00285 template<typename T, typename U>
00286 bool NamedXMLResourceManager<T, U>::isDefined(const String& object_name) const
00287 {
00288 return d_objects.find(object_name) != d_objects.end();
00289 }
00290
00291
00292 template<typename T, typename U>
00293 void NamedXMLResourceManager<T, U>::destroyObject(
00294 typename ObjectRegistry::iterator ob)
00295 {
00296 char addr_buff[32];
00297 sprintf(addr_buff, "(%p)", static_cast<void*>(ob->second));
00298 Logger::getSingleton().logEvent("Object of type '" + d_resourceType +
00299 "' named '" + ob->first + "' has been destroyed. " +
00300 addr_buff, Informative);
00301
00302
00303 ResourceEventArgs args(d_resourceType, ob->first);
00304
00305 delete ob->second;
00306 d_objects.erase(ob);
00307
00308
00309 fireEvent(EventResourceDestroyed, args, EventNamespace);
00310 }
00311
00312
00313 template<typename T, typename U>
00314 T& NamedXMLResourceManager<T, U>::doExistingObjectAction(
00315 const String object_name,
00316 T* object,
00317 const XMLResourceExistsAction action)
00318 {
00319 String event_name;
00320
00321 if (isDefined(object_name))
00322 {
00323 switch (action)
00324 {
00325 case XREA_RETURN:
00326 Logger::getSingleton().logEvent("---- Returning existing instance "
00327 "of " + d_resourceType + " named '" + object_name + "'.");
00328
00329 delete object;
00330
00331 return *d_objects[object_name];
00332
00333 case XREA_REPLACE:
00334 Logger::getSingleton().logEvent("---- Replacing existing instance "
00335 "of " + d_resourceType + " named '" + object_name +
00336 "' (DANGER!).");
00337 destroy(object_name);
00338 event_name = EventResourceReplaced;
00339 break;
00340
00341 case XREA_THROW:
00342 delete object;
00343 CEGUI_THROW(AlreadyExistsException(
00344 "NamedXMLResourceManager::checkExistingObjectAction: "
00345 "an object of type '" + d_resourceType + "' named '" +
00346 object_name + "' already exists in the collection."));
00347
00348 default:
00349 delete object;
00350 CEGUI_THROW(InvalidRequestException(
00351 "NamedXMLResourceManager::checkExistingObjectAction: "
00352 "Invalid CEGUI::XMLResourceExistsAction was specified."));
00353 }
00354 }
00355 else
00356 event_name = EventResourceCreated;
00357
00358 d_objects[object_name] = object;
00359 doPostObjectAdditionAction(*object);
00360
00361
00362 ResourceEventArgs args(d_resourceType, object_name);
00363 fireEvent(event_name, args, EventNamespace);
00364
00365 return *object;
00366 }
00367
00368
00369 template<typename T, typename U>
00370 void NamedXMLResourceManager<T, U>::doPostObjectAdditionAction(T& )
00371 {
00372
00373 }
00374
00375
00376 template<typename T, typename U>
00377 void NamedXMLResourceManager<T, U>::createAll(const String& pattern,
00378 const String& resource_group)
00379 {
00380 std::vector<String> names;
00381 const size_t num = System::getSingleton().getResourceProvider()->
00382 getResourceGroupFileNames(names, pattern, resource_group);
00383
00384 for (size_t i = 0; i < num; ++i)
00385 create(names[i], resource_group);
00386 }
00387
00388
00389
00390 }
00391
00392 #endif // end of guard _CEGUINamedXMLResourceManager_h_