Crazy Eddie's GUI System  0.8.3
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
NamedXMLResourceManager.h
1 /***********************************************************************
2  filename: CEGUINamedXMLResourceManager.h
3  created: Fri Jul 17 2009
4  author: Paul D Turner <paul@cegui.org.uk>
5 *************************************************************************/
6 /***************************************************************************
7  * Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining
10  * a copy of this software and associated documentation files (the
11  * "Software"), to deal in the Software without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sublicense, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26  * OTHER DEALINGS IN THE SOFTWARE.
27  ***************************************************************************/
28 #ifndef _CEGUINamedXMLResourceManager_h_
29 #define _CEGUINamedXMLResourceManager_h_
30 
31 #include "CEGUI/EventSet.h"
32 #include "CEGUI/String.h"
33 #include "CEGUI/Exceptions.h"
34 #include "CEGUI/Logger.h"
35 #include "CEGUI/InputEvent.h"
36 #include "CEGUI/System.h"
37 #include <map>
38 
39 // Start of CEGUI namespace section
40 namespace CEGUI
41 {
44 {
51 };
52 
53 //----------------------------------------------------------------------------//
54 
56 class CEGUIEXPORT ResourceEventSet : public EventSet
57 {
58 public:
60  static const String EventNamespace;
82 };
83 
84 //----------------------------------------------------------------------------//
85 
108 template<typename T, typename U>
110 {
111 public:
121  NamedXMLResourceManager(const String& resource_type);
122 
124  virtual ~NamedXMLResourceManager();
125 
143  T& createFromContainer(const RawDataContainer& source,
145 
168  T& createFromFile(const String& xml_filename, const String& resource_group = "",
170 
188  T& createFromString(const String& source,
190 
199  void destroy(const String& object_name);
200 
210  void destroy(const T& object);
211 
213  void destroyAll();
214 
225  T& get(const String& object_name) const;
226 
228  bool isDefined(const String& object_name) const;
229 
231  void createAll(const String& pattern, const String& resource_group);
232 
233 protected:
234  // singleton allocator fits here, resource managers are very likely to be singletons
236  typedef std::map<String, T*, StringFastLessCompare
237  CEGUI_MAP_ALLOC(String, T*)> ObjectRegistry;
239  void destroyObject(typename ObjectRegistry::iterator ob);
241  T& doExistingObjectAction(const String object_name, T* object,
242  const XMLResourceExistsAction action);
244  virtual void doPostObjectAdditionAction(T& object);
249 };
250 
251 //----------------------------------------------------------------------------//
252 template<typename T, typename U>
254  const String& resource_type) :
255  d_resourceType(resource_type)
256 {
257 }
258 
259 //----------------------------------------------------------------------------//
260 template<typename T, typename U>
262 {
263 }
264 
265 //----------------------------------------------------------------------------//
266 template<typename T, typename U>
269 {
270  U xml_loader;
271 
272  xml_loader.handleContainer(source);
273  return doExistingObjectAction(xml_loader.getObjectName(),
274  &xml_loader.getObject(), action);
275 }
276 
277 //----------------------------------------------------------------------------//
278 template<typename T, typename U>
280  const String& resource_group,
282 {
283  U xml_loader;
284 
285  xml_loader.handleFile(xml_filename, resource_group);
286  return doExistingObjectAction(xml_loader.getObjectName(),
287  &xml_loader.getObject(), action);
288 }
289 
290 //----------------------------------------------------------------------------//
291 template<typename T, typename U>
294 {
295  U xml_loader;
296 
297  xml_loader.handleString(source);
298  return doExistingObjectAction(xml_loader.getObjectName(),
299  &xml_loader.getObject(), action);
300 }
301 
302 //----------------------------------------------------------------------------//
303 template<typename T, typename U>
305 {
306  typename ObjectRegistry::iterator i(d_objects.find(object_name));
307 
308  // exit if no such object.
309  if (i == d_objects.end())
310  return;
311 
312  destroyObject(i);
313 }
314 
315 //----------------------------------------------------------------------------//
316 template<typename T, typename U>
318 {
319  // don't want to force a 'getName' function on T here, so we'll look for the
320  // object the hard way.
321  typename ObjectRegistry::iterator i(d_objects.begin());
322  for (; i != d_objects.end(); ++i)
323  if (i->second == &object)
324  {
325  destroyObject(i);
326  return;
327  }
328 }
329 
330 //----------------------------------------------------------------------------//
331 template<typename T, typename U>
333 {
334  while (!d_objects.empty())
335  destroyObject(d_objects.begin());
336 }
337 
338 //----------------------------------------------------------------------------//
339 template<typename T, typename U>
340 T& NamedXMLResourceManager<T, U>::get(const String& object_name) const
341 {
342  typename ObjectRegistry::const_iterator i(d_objects.find(object_name));
343 
344  if (i == d_objects.end())
345  CEGUI_THROW(UnknownObjectException(
346  "No object of type '" + d_resourceType + "' named '" + object_name +
347  "' is present in the collection."));
348 
349  return *i->second;
350 }
351 
352 //----------------------------------------------------------------------------//
353 template<typename T, typename U>
354 bool NamedXMLResourceManager<T, U>::isDefined(const String& object_name) const
355 {
356  return d_objects.find(object_name) != d_objects.end();
357 }
358 
359 //----------------------------------------------------------------------------//
360 template<typename T, typename U>
362  typename ObjectRegistry::iterator ob)
363 {
364  char addr_buff[32];
365  sprintf(addr_buff, "(%p)", static_cast<void*>(ob->second));
366  Logger::getSingleton().logEvent("Object of type '" + d_resourceType +
367  "' named '" + ob->first + "' has been destroyed. " +
368  addr_buff, Informative);
369 
370  // Set up event args for event notification
371  ResourceEventArgs args(d_resourceType, ob->first);
372 
373  CEGUI_DELETE_AO ob->second;
374  d_objects.erase(ob);
375 
376  // fire event signalling an object has been destroyed
377  fireEvent(EventResourceDestroyed, args, EventNamespace);
378 }
379 
380 //----------------------------------------------------------------------------//
381 template<typename T, typename U>
383  const String object_name,
384  T* object,
385  const XMLResourceExistsAction action)
386 {
387  String event_name;
388 
389  if (isDefined(object_name))
390  {
391  switch (action)
392  {
393  case XREA_RETURN:
394  Logger::getSingleton().logEvent("---- Returning existing instance "
395  "of " + d_resourceType + " named '" + object_name + "'.");
396  // delete any new object we already had created
397  CEGUI_DELETE_AO object;
398  // return existing instance of object.
399  return *d_objects[object_name];
400 
401  case XREA_REPLACE:
402  Logger::getSingleton().logEvent("---- Replacing existing instance "
403  "of " + d_resourceType + " named '" + object_name +
404  "' (DANGER!).");
405  destroy(object_name);
406  event_name = EventResourceReplaced;
407  break;
408 
409  case XREA_THROW:
410  CEGUI_DELETE_AO object;
411  CEGUI_THROW(AlreadyExistsException(
412  "an object of type '" + d_resourceType + "' named '" +
413  object_name + "' already exists in the collection."));
414 
415  default:
416  CEGUI_DELETE_AO object;
417  CEGUI_THROW(InvalidRequestException(
418  "Invalid CEGUI::XMLResourceExistsAction was specified."));
419  }
420  }
421  else
422  event_name = EventResourceCreated;
423 
424  d_objects[object_name] = object;
425  doPostObjectAdditionAction(*object);
426 
427  // fire event about this resource change
428  ResourceEventArgs args(d_resourceType, object_name);
429  fireEvent(event_name, args, EventNamespace);
430 
431  return *object;
432 }
433 
434 //----------------------------------------------------------------------------//
435 template<typename T, typename U>
437 {
438  // do nothing by default.
439 }
440 
441 //----------------------------------------------------------------------------//
442 template<typename T, typename U>
444  const String& resource_group)
445 {
446  std::vector<String> names;
447  const size_t num = System::getSingleton().getResourceProvider()->
448  getResourceGroupFileNames(names, pattern, resource_group);
449 
450  for (size_t i = 0; i < num; ++i)
451  createFromFile(names[i], resource_group);
452 }
453 
454 //----------------------------------------------------------------------------//
455 
456 } // End of CEGUI namespace section
457 
458 #endif // end of guard _CEGUINamedXMLResourceManager_h_