Crazy Eddie's GUI System
0.8.4
|
00001 /*********************************************************************** 00002 created: Fri Jul 17 2009 00003 author: Paul D Turner <paul@cegui.org.uk> 00004 *************************************************************************/ 00005 /*************************************************************************** 00006 * Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team 00007 * 00008 * Permission is hereby granted, free of charge, to any person obtaining 00009 * a copy of this software and associated documentation files (the 00010 * "Software"), to deal in the Software without restriction, including 00011 * without limitation the rights to use, copy, modify, merge, publish, 00012 * distribute, sublicense, and/or sell copies of the Software, and to 00013 * permit persons to whom the Software is furnished to do so, subject to 00014 * the following conditions: 00015 * 00016 * The above copyright notice and this permission notice shall be 00017 * included in all copies or substantial portions of the Software. 00018 * 00019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00020 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00021 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00022 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 00023 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00024 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00025 * OTHER DEALINGS IN THE SOFTWARE. 00026 ***************************************************************************/ 00027 #ifndef _CEGUINamedXMLResourceManager_h_ 00028 #define _CEGUINamedXMLResourceManager_h_ 00029 00030 #include "CEGUI/EventSet.h" 00031 #include "CEGUI/String.h" 00032 #include "CEGUI/Exceptions.h" 00033 #include "CEGUI/Logger.h" 00034 #include "CEGUI/InputEvent.h" 00035 #include "CEGUI/System.h" 00036 #include <map> 00037 00038 // Start of CEGUI namespace section 00039 namespace CEGUI 00040 { 00042 enum XMLResourceExistsAction 00043 { 00045 XREA_RETURN, 00047 XREA_REPLACE, 00049 XREA_THROW 00050 }; 00051 00052 //----------------------------------------------------------------------------// 00053 00055 class CEGUIEXPORT ResourceEventSet : public EventSet 00056 { 00057 public: 00059 static const String EventNamespace; 00066 static const String EventResourceCreated; 00073 static const String EventResourceDestroyed; 00080 static const String EventResourceReplaced; 00081 }; 00082 00083 //----------------------------------------------------------------------------// 00084 00107 template<typename T, typename U> 00108 class NamedXMLResourceManager : public ResourceEventSet 00109 { 00110 public: 00120 NamedXMLResourceManager(const String& resource_type); 00121 00123 virtual ~NamedXMLResourceManager(); 00124 00142 T& createFromContainer(const RawDataContainer& source, 00143 XMLResourceExistsAction action = XREA_RETURN); 00144 00167 T& createFromFile(const String& xml_filename, const String& resource_group = "", 00168 XMLResourceExistsAction action = XREA_RETURN); 00169 00187 T& createFromString(const String& source, 00188 XMLResourceExistsAction action = XREA_RETURN); 00189 00198 void destroy(const String& object_name); 00199 00209 void destroy(const T& object); 00210 00212 void destroyAll(); 00213 00224 T& get(const String& object_name) const; 00225 00227 bool isDefined(const String& object_name) const; 00228 00230 void createAll(const String& pattern, const String& resource_group); 00231 00232 protected: 00233 // singleton allocator fits here, resource managers are very likely to be singletons 00235 typedef std::map<String, T*, StringFastLessCompare 00236 CEGUI_MAP_ALLOC(String, T*)> ObjectRegistry; 00238 void destroyObject(typename ObjectRegistry::iterator ob); 00240 T& doExistingObjectAction(const String object_name, T* object, 00241 const XMLResourceExistsAction action); 00243 virtual void doPostObjectAdditionAction(T& object); 00245 const String d_resourceType; 00247 ObjectRegistry d_objects; 00248 }; 00249 00250 //----------------------------------------------------------------------------// 00251 template<typename T, typename U> 00252 NamedXMLResourceManager<T, U>::NamedXMLResourceManager( 00253 const String& resource_type) : 00254 d_resourceType(resource_type) 00255 { 00256 } 00257 00258 //----------------------------------------------------------------------------// 00259 template<typename T, typename U> 00260 NamedXMLResourceManager<T, U>::~NamedXMLResourceManager() 00261 { 00262 } 00263 00264 //----------------------------------------------------------------------------// 00265 template<typename T, typename U> 00266 T& NamedXMLResourceManager<T, U>::createFromContainer(const RawDataContainer& source, 00267 XMLResourceExistsAction action) 00268 { 00269 U xml_loader; 00270 00271 xml_loader.handleContainer(source); 00272 return doExistingObjectAction(xml_loader.getObjectName(), 00273 &xml_loader.getObject(), action); 00274 } 00275 00276 //----------------------------------------------------------------------------// 00277 template<typename T, typename U> 00278 T& NamedXMLResourceManager<T, U>::createFromFile(const String& xml_filename, 00279 const String& resource_group, 00280 XMLResourceExistsAction action) 00281 { 00282 U xml_loader; 00283 00284 xml_loader.handleFile(xml_filename, resource_group); 00285 return doExistingObjectAction(xml_loader.getObjectName(), 00286 &xml_loader.getObject(), action); 00287 } 00288 00289 //----------------------------------------------------------------------------// 00290 template<typename T, typename U> 00291 T& NamedXMLResourceManager<T, U>::createFromString(const String& source, 00292 XMLResourceExistsAction action) 00293 { 00294 U xml_loader; 00295 00296 xml_loader.handleString(source); 00297 return doExistingObjectAction(xml_loader.getObjectName(), 00298 &xml_loader.getObject(), action); 00299 } 00300 00301 //----------------------------------------------------------------------------// 00302 template<typename T, typename U> 00303 void NamedXMLResourceManager<T, U>::destroy(const String& object_name) 00304 { 00305 typename ObjectRegistry::iterator i(d_objects.find(object_name)); 00306 00307 // exit if no such object. 00308 if (i == d_objects.end()) 00309 return; 00310 00311 destroyObject(i); 00312 } 00313 00314 //----------------------------------------------------------------------------// 00315 template<typename T, typename U> 00316 void NamedXMLResourceManager<T, U>::destroy(const T& object) 00317 { 00318 // don't want to force a 'getName' function on T here, so we'll look for the 00319 // object the hard way. 00320 typename ObjectRegistry::iterator i(d_objects.begin()); 00321 for (; i != d_objects.end(); ++i) 00322 if (i->second == &object) 00323 { 00324 destroyObject(i); 00325 return; 00326 } 00327 } 00328 00329 //----------------------------------------------------------------------------// 00330 template<typename T, typename U> 00331 void NamedXMLResourceManager<T, U>::destroyAll() 00332 { 00333 while (!d_objects.empty()) 00334 destroyObject(d_objects.begin()); 00335 } 00336 00337 //----------------------------------------------------------------------------// 00338 template<typename T, typename U> 00339 T& NamedXMLResourceManager<T, U>::get(const String& object_name) const 00340 { 00341 typename ObjectRegistry::const_iterator i(d_objects.find(object_name)); 00342 00343 if (i == d_objects.end()) 00344 CEGUI_THROW(UnknownObjectException( 00345 "No object of type '" + d_resourceType + "' named '" + object_name + 00346 "' is present in the collection.")); 00347 00348 return *i->second; 00349 } 00350 00351 //----------------------------------------------------------------------------// 00352 template<typename T, typename U> 00353 bool NamedXMLResourceManager<T, U>::isDefined(const String& object_name) const 00354 { 00355 return d_objects.find(object_name) != d_objects.end(); 00356 } 00357 00358 //----------------------------------------------------------------------------// 00359 template<typename T, typename U> 00360 void NamedXMLResourceManager<T, U>::destroyObject( 00361 typename ObjectRegistry::iterator ob) 00362 { 00363 char addr_buff[32]; 00364 sprintf(addr_buff, "(%p)", static_cast<void*>(ob->second)); 00365 Logger::getSingleton().logEvent("Object of type '" + d_resourceType + 00366 "' named '" + ob->first + "' has been destroyed. " + 00367 addr_buff, Informative); 00368 00369 // Set up event args for event notification 00370 ResourceEventArgs args(d_resourceType, ob->first); 00371 00372 CEGUI_DELETE_AO ob->second; 00373 d_objects.erase(ob); 00374 00375 // fire event signalling an object has been destroyed 00376 fireEvent(EventResourceDestroyed, args, EventNamespace); 00377 } 00378 00379 //----------------------------------------------------------------------------// 00380 template<typename T, typename U> 00381 T& NamedXMLResourceManager<T, U>::doExistingObjectAction( 00382 const String object_name, 00383 T* object, 00384 const XMLResourceExistsAction action) 00385 { 00386 String event_name; 00387 00388 if (isDefined(object_name)) 00389 { 00390 switch (action) 00391 { 00392 case XREA_RETURN: 00393 Logger::getSingleton().logEvent("---- Returning existing instance " 00394 "of " + d_resourceType + " named '" + object_name + "'."); 00395 // delete any new object we already had created 00396 CEGUI_DELETE_AO object; 00397 // return existing instance of object. 00398 return *d_objects[object_name]; 00399 00400 case XREA_REPLACE: 00401 Logger::getSingleton().logEvent("---- Replacing existing instance " 00402 "of " + d_resourceType + " named '" + object_name + 00403 "' (DANGER!)."); 00404 destroy(object_name); 00405 event_name = EventResourceReplaced; 00406 break; 00407 00408 case XREA_THROW: 00409 CEGUI_DELETE_AO object; 00410 CEGUI_THROW(AlreadyExistsException( 00411 "an object of type '" + d_resourceType + "' named '" + 00412 object_name + "' already exists in the collection.")); 00413 00414 default: 00415 CEGUI_DELETE_AO object; 00416 CEGUI_THROW(InvalidRequestException( 00417 "Invalid CEGUI::XMLResourceExistsAction was specified.")); 00418 } 00419 } 00420 else 00421 event_name = EventResourceCreated; 00422 00423 d_objects[object_name] = object; 00424 doPostObjectAdditionAction(*object); 00425 00426 // fire event about this resource change 00427 ResourceEventArgs args(d_resourceType, object_name); 00428 fireEvent(event_name, args, EventNamespace); 00429 00430 return *object; 00431 } 00432 00433 //----------------------------------------------------------------------------// 00434 template<typename T, typename U> 00435 void NamedXMLResourceManager<T, U>::doPostObjectAdditionAction(T& /*object*/) 00436 { 00437 // do nothing by default. 00438 } 00439 00440 //----------------------------------------------------------------------------// 00441 template<typename T, typename U> 00442 void NamedXMLResourceManager<T, U>::createAll(const String& pattern, 00443 const String& resource_group) 00444 { 00445 std::vector<String> names; 00446 const size_t num = System::getSingleton().getResourceProvider()-> 00447 getResourceGroupFileNames(names, pattern, resource_group); 00448 00449 for (size_t i = 0; i < num; ++i) 00450 createFromFile(names[i], resource_group); 00451 } 00452 00453 //----------------------------------------------------------------------------// 00454 00455 } // End of CEGUI namespace section 00456 00457 #endif // end of guard _CEGUINamedXMLResourceManager_h_