Crazy Eddie's GUI System 0.8.7
NamedXMLResourceManager.h
1/***********************************************************************
2 created: Fri Jul 17 2009
3 author: Paul D Turner <paul@cegui.org.uk>
4*************************************************************************/
5/***************************************************************************
6 * Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 ***************************************************************************/
27#ifndef _CEGUINamedXMLResourceManager_h_
28#define _CEGUINamedXMLResourceManager_h_
29
30#include "CEGUI/EventSet.h"
31#include "CEGUI/String.h"
32#include "CEGUI/Exceptions.h"
33#include "CEGUI/Logger.h"
34#include "CEGUI/InputEvent.h"
35#include "CEGUI/System.h"
36#include <map>
37
38// Start of CEGUI namespace section
39namespace CEGUI
40{
43{
50};
51
52//----------------------------------------------------------------------------//
53
55class CEGUIEXPORT ResourceEventSet : public EventSet
56{
57public:
59 static const String EventNamespace;
81};
82
83//----------------------------------------------------------------------------//
84
107template<typename T, typename U>
109{
110public:
120 NamedXMLResourceManager(const String& resource_type);
121
124
144
167 T& createFromFile(const String& xml_filename, const String& resource_group = "",
169
187 T& createFromString(const String& source,
189
198 void destroy(const String& object_name);
199
209 void destroy(const T& object);
210
213
224 T& get(const String& object_name) const;
225
227 bool isDefined(const String& object_name) const;
228
230 void createAll(const String& pattern, const String& resource_group);
231
232protected:
233 // singleton allocator fits here, resource managers are very likely to be singletons
235 typedef std::map<String, T*, StringFastLessCompare
236 CEGUI_MAP_ALLOC(String, T*)> ObjectRegistry;
238 void destroyObject(typename ObjectRegistry::iterator ob);
240 T& doExistingObjectAction(const String object_name, T* object,
241 const XMLResourceExistsAction action);
243 virtual void doPostObjectAdditionAction(T& object);
248};
249
250//----------------------------------------------------------------------------//
251template<typename T, typename U>
253 const String& resource_type) :
254 d_resourceType(resource_type)
255{
256}
257
258//----------------------------------------------------------------------------//
259template<typename T, typename U>
261{
262}
263
264//----------------------------------------------------------------------------//
265template<typename T, typename U>
268{
269 U xml_loader;
270
271 xml_loader.handleContainer(source);
272 return doExistingObjectAction(xml_loader.getObjectName(),
273 &xml_loader.getObject(), action);
274}
275
276//----------------------------------------------------------------------------//
277template<typename T, typename U>
279 const String& resource_group,
281{
282 U xml_loader;
283
284 xml_loader.handleFile(xml_filename, resource_group);
285 return doExistingObjectAction(xml_loader.getObjectName(),
286 &xml_loader.getObject(), action);
287}
288
289//----------------------------------------------------------------------------//
290template<typename T, typename U>
293{
294 U xml_loader;
295
296 xml_loader.handleString(source);
297 return doExistingObjectAction(xml_loader.getObjectName(),
298 &xml_loader.getObject(), action);
299}
300
301//----------------------------------------------------------------------------//
302template<typename T, typename U>
304{
305 typename ObjectRegistry::iterator i(d_objects.find(object_name));
306
307 // exit if no such object.
308 if (i == d_objects.end())
309 return;
310
311 destroyObject(i);
312}
313
314//----------------------------------------------------------------------------//
315template<typename T, typename U>
317{
318 // don't want to force a 'getName' function on T here, so we'll look for the
319 // object the hard way.
320 typename ObjectRegistry::iterator i(d_objects.begin());
321 for (; i != d_objects.end(); ++i)
322 if (i->second == &object)
323 {
324 destroyObject(i);
325 return;
326 }
327}
328
329//----------------------------------------------------------------------------//
330template<typename T, typename U>
332{
333 while (!d_objects.empty())
334 destroyObject(d_objects.begin());
335}
336
337//----------------------------------------------------------------------------//
338template<typename T, typename U>
339T& NamedXMLResourceManager<T, U>::get(const String& object_name) const
340{
341 typename ObjectRegistry::const_iterator i(d_objects.find(object_name));
342
343 if (i == d_objects.end())
344 CEGUI_THROW(UnknownObjectException(
345 "No object of type '" + d_resourceType + "' named '" + object_name +
346 "' is present in the collection."));
347
348 return *i->second;
349}
350
351//----------------------------------------------------------------------------//
352template<typename T, typename U>
354{
355 return d_objects.find(object_name) != d_objects.end();
356}
357
358//----------------------------------------------------------------------------//
359template<typename T, typename U>
361 typename ObjectRegistry::iterator ob)
362{
363 char addr_buff[32];
364 sprintf(addr_buff, "(%p)", static_cast<void*>(ob->second));
365 Logger::getSingleton().logEvent("Object of type '" + d_resourceType +
366 "' named '" + ob->first + "' has been destroyed. " +
367 addr_buff, Informative);
368
369 // Set up event args for event notification
370 ResourceEventArgs args(d_resourceType, ob->first);
371
372 CEGUI_DELETE_AO ob->second;
373 d_objects.erase(ob);
374
375 // fire event signalling an object has been destroyed
376 fireEvent(EventResourceDestroyed, args, EventNamespace);
377}
378
379//----------------------------------------------------------------------------//
380template<typename T, typename U>
382 const String object_name,
383 T* object,
384 const XMLResourceExistsAction action)
385{
386 String event_name;
387
388 if (isDefined(object_name))
389 {
390 switch (action)
391 {
392 case XREA_RETURN:
393 Logger::getSingleton().logEvent("---- Returning existing instance "
394 "of " + d_resourceType + " named '" + object_name + "'.");
395 // delete any new object we already had created
396 CEGUI_DELETE_AO object;
397 // return existing instance of object.
398 return *d_objects[object_name];
399
400 case XREA_REPLACE:
401 Logger::getSingleton().logEvent("---- Replacing existing instance "
402 "of " + d_resourceType + " named '" + object_name +
403 "' (DANGER!).");
404 destroy(object_name);
405 event_name = EventResourceReplaced;
406 break;
407
408 case XREA_THROW:
409 CEGUI_DELETE_AO object;
410 CEGUI_THROW(AlreadyExistsException(
411 "an object of type '" + d_resourceType + "' named '" +
412 object_name + "' already exists in the collection."));
413
414 default:
415 CEGUI_DELETE_AO object;
416 CEGUI_THROW(InvalidRequestException(
417 "Invalid CEGUI::XMLResourceExistsAction was specified."));
418 }
419 }
420 else
421 event_name = EventResourceCreated;
422
423 d_objects[object_name] = object;
424 doPostObjectAdditionAction(*object);
425
426 // fire event about this resource change
427 ResourceEventArgs args(d_resourceType, object_name);
428 fireEvent(event_name, args, EventNamespace);
429
430 return *object;
431}
432
433//----------------------------------------------------------------------------//
434template<typename T, typename U>
436{
437 // do nothing by default.
438}
439
440//----------------------------------------------------------------------------//
441template<typename T, typename U>
443 const String& resource_group)
444{
445 std::vector<String> names;
446 const size_t num = System::getSingleton().getResourceProvider()->
447 getResourceGroupFileNames(names, pattern, resource_group);
448
449 for (size_t i = 0; i < num; ++i)
450 createFromFile(names[i], resource_group);
451}
452
453//----------------------------------------------------------------------------//
454
455} // End of CEGUI namespace section
456
457#endif // end of guard _CEGUINamedXMLResourceManager_h_
Exception class used when an attempt is made create a named object of a particular type when an objec...
Definition: Exceptions.h:484
Interface providing event signaling and handling.
Definition: EventSet.h:167
Exception class used when some impossible request was made of the system.
Definition: Exceptions.h:305
Templatised manager class that loads and manages named XML based resources.
Definition: NamedXMLResourceManager.h:109
virtual void doPostObjectAdditionAction(T &object)
Function called each time a new object is added to the collection.
Definition: NamedXMLResourceManager.h:435
T & get(const String &object_name) const
Return a reference to the object named object_name.
Definition: NamedXMLResourceManager.h:339
T & createFromContainer(const RawDataContainer &source, XMLResourceExistsAction action=XREA_RETURN)
Creates a new T object from a RawDataContainer and adds it to the collection.
Definition: NamedXMLResourceManager.h:266
void destroyObject(typename ObjectRegistry::iterator ob)
implementation of object destruction.
Definition: NamedXMLResourceManager.h:360
void destroy(const String &object_name)
Destroy the object named object_name, or do nothing if such an object does not exist in the collectio...
Definition: NamedXMLResourceManager.h:303
NamedXMLResourceManager(const String &resource_type)
Constructor.
Definition: NamedXMLResourceManager.h:252
T & createFromFile(const String &xml_filename, const String &resource_group="", XMLResourceExistsAction action=XREA_RETURN)
Creates a new T object from an XML file and adds it to the collection.
Definition: NamedXMLResourceManager.h:278
const String d_resourceType
String holding the text for the resource type managed.
Definition: NamedXMLResourceManager.h:245
std::map< String, T *, StringFastLessCompare CEGUI_MAP_ALLOC(String, T *)> ObjectRegistry
type of collection used to store and manage objects
Definition: NamedXMLResourceManager.h:236
T & createFromString(const String &source, XMLResourceExistsAction action=XREA_RETURN)
Creates a new T object from a string and adds it to the collection.
Definition: NamedXMLResourceManager.h:291
void createAll(const String &pattern, const String &resource_group)
Create a new T object from files with names matching pattern in resource_group.
Definition: NamedXMLResourceManager.h:442
ObjectRegistry d_objects
the collection of objects
Definition: NamedXMLResourceManager.h:247
void destroyAll()
Destroy all objects.
Definition: NamedXMLResourceManager.h:331
virtual ~NamedXMLResourceManager()
Destructor.
Definition: NamedXMLResourceManager.h:260
bool isDefined(const String &object_name) const
Return whether an object named object_name exists.
Definition: NamedXMLResourceManager.h:353
T & doExistingObjectAction(const String object_name, T *object, const XMLResourceExistsAction action)
function to enforce XMLResourceExistsAction policy.
Definition: NamedXMLResourceManager.h:381
void destroy(const T &object)
Destroy the object object, or do nothing if such an object does not exist in the collection.
Definition: NamedXMLResourceManager.h:316
Class used as the databuffer for loading files throughout the library.
Definition: DataContainer.h:44
EventArgs based class that is used for notifications regarding resources.
Definition: InputEvent.h:366
implementation class to gather EventSet parts for all template instances.
Definition: NamedXMLResourceManager.h:56
static const String EventNamespace
Namespace name for all resource managers.
Definition: NamedXMLResourceManager.h:59
static const String EventResourceCreated
Definition: NamedXMLResourceManager.h:66
static const String EventResourceReplaced
Definition: NamedXMLResourceManager.h:80
static const String EventResourceDestroyed
Definition: NamedXMLResourceManager.h:73
String class used within the GUI system.
Definition: String.h:64
ResourceProvider * getResourceProvider(void) const
Return a pointer to the ResourceProvider being used within the GUI system.
static System & getSingleton(void)
Return singleton System object.
Exception class used when a request was made for an unknown object.
Definition: Exceptions.h:247
Main namespace for Crazy Eddie's GUI Library.
Definition: arch_overview.dox:1
XMLResourceExistsAction
Possible actions when loading an XML resource that already exists.
Definition: NamedXMLResourceManager.h:43
@ XREA_THROW
Throw an AlreadyExistsException.
Definition: NamedXMLResourceManager.h:49
@ XREA_RETURN
Do not load the resource, return the existing instance.
Definition: NamedXMLResourceManager.h:45
@ XREA_REPLACE
Destroy the existing instance and replace with the newly loaded one.
Definition: NamedXMLResourceManager.h:47
@ Informative
Useful tracing (object creations etc) information will be logged.
Definition: Logger.h:61
Functor that can be used as comparator in a std::map with String keys. It's faster than using the def...
Definition: String.h:5580