UGDK  0.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
genericcontainer.h
Go to the documentation of this file.
1 #ifndef UGDK_BASE_GENERICCONTAINER_H_
2 #define UGDK_BASE_GENERICCONTAINER_H_
3 
4 #include <string>
5 #include <map>
7 
8 #ifdef DEBUG
9 #include <cstdio>
10 #include <typeinfo>
11 #define TOSTRING(X) typeid(X).name()
12 #endif
13 
14 namespace ugdk {
15 namespace base {
16 
17 template <class T, class Loader_T = T (*) (const std::string&)>
18 class GenericContainer : public virtual ResourceContainer<T> {
19  private:
20  typedef std::map<std::string, T> DataMap;
21  typedef typename DataMap::iterator DataIterator;
22  DataMap database_;
23  Loader_T loader_;
24 
25  public:
26  GenericContainer() : loader_(T::LoadFromFile) {}
27  GenericContainer(Loader_T loader) : loader_(loader) {}
28  virtual ~GenericContainer() {}
29 
30  void Insert(const std::string& tag, T val) {
31  DataIterator it = database_.find(tag);
32  if(it == database_.end()) {
33  database_[tag] = val;
34  } else {
35  #ifdef DEBUG
36  fprintf(stderr, "UGDK::GenericContainer<%s> Error - Tag '%s' already exists.\n", TOSTRING(T), tag.c_str());
37  #endif
38  }
39  }
40 
41  void Replace(const std::string& tag, T val) {
42  database_[tag] = val;
43  }
44 
45  bool Exists(const std::string& tag) const {
46  return database_.count(tag) > 0;
47  }
48 
49  T& Find(const std::string& tag) {
50  return database_[tag];
51  }
52 
54  virtual T& Load(const std::string& filepath, const std::string& tag) {
55  if(!Exists(tag)) Insert(tag, loader_(filepath));
56  return Find(tag);
57  }
58 };
59 
60 template <class T>
61 class GenericContainer<T*, T* (*) (const std::string&)> : public virtual ResourceContainer<T*> {
62  private:
63  typedef std::map<std::string, T*> DataMap;
64  typedef typename DataMap::iterator DataIterator;
65  typedef T* (*Loader_T) (const std::string&);
66 
67  DataMap database_;
68  Loader_T loader_;
69 
70  public:
71  GenericContainer() : loader_(T::LoadFromFile) {}
72  GenericContainer(Loader_T loader) : loader_(loader) {}
73  virtual ~GenericContainer() {
74  DataIterator it;
75  for(it = database_.begin(); it != database_.end(); ++it) {
76  delete it->second;
77  }
78  }
79 
80  void Insert(const std::string& tag, T* val) {
81  DataIterator it = database_.find(tag);
82  if(it == database_.end() || it->second == NULL) {
83  database_[tag] = val;
84  } else {
85  #ifdef DEBUG
86  fprintf(stderr, "UGDK::GenericContainer<%s> Error - Tag '%s' already exists.\n", TOSTRING(T), tag.c_str());
87  #endif
88  }
89  }
90 
91  void Replace(const std::string& tag, T* val) {
92  DataIterator it = database_.find(tag);
93  if(it == database_.end() || it->second == NULL) {
94  database_[tag] = val;
95  } else {
96  delete it->second;
97  it->second = val;
98  }
99  }
100 
101  bool Exists(const std::string& tag) const {
102  typename DataMap::const_iterator it = database_.find(tag);
103  return (it != database_.end() && it->second);
104  }
105 
106  T* Find(const std::string& tag) {
107  return database_[tag];
108  }
109 
111  virtual T* Load(const std::string& filepath, const std::string& tag) {
112  if(Exists(tag)) return Find(tag);
113  T* obj = loader_(filepath);
114  Insert(tag, obj);
115  return obj;
116  }
117 };
118 
119 } // namespace base
120 } // namespace ugdk
121 
122 #endif // UGDK_BASE_GENERICCONTAINER_H_
123