UGDK
src/ugdk/base/genericcontainer.h
Go to the documentation of this file.
00001 #ifndef UGDK_BASE_GENERICCONTAINER_H_
00002 #define UGDK_BASE_GENERICCONTAINER_H_
00003 
00004 #include <string>
00005 #include <map>
00006 #include <ugdk/base/resourcecontainer.h>
00007 
00008 #ifdef DEBUG
00009 #include <cstdio>
00010 #include <typeinfo>
00011 #define TOSTRING(X) typeid(X).name()
00012 #endif
00013 
00014 namespace ugdk {
00015 namespace base {
00016 
00017 template <class T, class Loader_T = T (*) (const std::string&)>
00018 class GenericContainer : public virtual ResourceContainer<T> {
00019   private:
00020     typedef std::map<std::string, T>   DataMap;
00021     typedef typename DataMap::iterator DataIterator;
00022     DataMap database_;
00023     Loader_T loader_;
00024 
00025   public:
00026     GenericContainer() : loader_(T::LoadFromFile) {}
00027     GenericContainer(Loader_T loader) : loader_(loader) {}
00028     virtual ~GenericContainer() {}
00029 
00030     void Insert(const std::string& tag, T val) {
00031         DataIterator it = database_.find(tag);
00032         if(it == database_.end()) {
00033             database_[tag] = val;
00034         } else {
00035             #ifdef DEBUG
00036                 fprintf(stderr, "UGDK::GenericContainer<%s> Error - Tag '%s' already exists.\n", TOSTRING(T), tag.c_str());
00037             #endif
00038         }
00039     }
00040 
00041     void Replace(const std::string& tag, T val) {
00042         database_[tag] = val;
00043     }
00044 
00045     bool Exists(const std::string& tag) const {
00046         return database_.count(tag) > 0;
00047     }
00048 
00049     T& Find(const std::string& tag) {
00050         return database_[tag];
00051     }
00052     
00054     virtual T& Load(const std::string& filepath, const std::string& tag) {
00055         if(!Exists(tag)) Insert(tag, loader_(filepath));
00056         return Find(tag);
00057     }
00058 };
00059 
00060 template <class T>
00061 class GenericContainer<T*, T* (*) (const std::string&)> : public virtual ResourceContainer<T*> {
00062   private:
00063     typedef std::map<std::string, T*>   DataMap;
00064     typedef typename DataMap::iterator  DataIterator;
00065     typedef T* (*Loader_T) (const std::string&);
00066 
00067     DataMap database_;
00068     Loader_T loader_;
00069 
00070   public:
00071     GenericContainer() : loader_(T::LoadFromFile) {}
00072     GenericContainer(Loader_T loader) : loader_(loader) {}
00073     virtual ~GenericContainer() {
00074         DataIterator it;
00075         for(it = database_.begin(); it != database_.end(); ++it) {
00076             delete it->second;
00077         }
00078     }
00079 
00080     void Insert(const std::string& tag, T* val) {
00081         DataIterator it = database_.find(tag);
00082         if(it == database_.end() || it->second == NULL) {
00083             database_[tag] = val;
00084         } else {
00085             #ifdef DEBUG
00086                 fprintf(stderr, "UGDK::GenericContainer<%s> Error - Tag '%s' already exists.\n", TOSTRING(T), tag.c_str());
00087             #endif
00088         }
00089     }
00090 
00091     void Replace(const std::string& tag, T* val) {
00092         DataIterator it = database_.find(tag);
00093         if(it == database_.end() || it->second == NULL) {
00094             database_[tag] = val;
00095         } else {
00096             delete it->second;
00097             it->second = val;
00098         }
00099     }
00100     
00101     bool Exists(const std::string& tag) const {
00102         typename DataMap::const_iterator it = database_.find(tag);
00103         return (it != database_.end() && it->second);
00104     }
00105 
00106     T* Find(const std::string& tag) {
00107         return database_[tag];
00108     }
00109     
00111     virtual T* Load(const std::string& filepath, const std::string& tag) {
00112         if(Exists(tag)) return Find(tag);
00113         T* obj = loader_(filepath);
00114         Insert(tag, obj);
00115         return obj;
00116     }
00117 };
00118 
00119 } // namespace base
00120 } // namespace ugdk
00121 
00122 #endif // UGDK_BASE_GENERICCONTAINER_H_
00123 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines