Templates -- Meow  1.1.2
不能,也不應該先編譯成obj-file的templates
ObjSelector.h
Go to the documentation of this file.
1 #ifndef oo_ObjSelector_H__
2 #define oo_ObjSelector_H__
3 
4 #include "ObjBase.h"
5 
6 #include <utility>
7 #include <vector>
8 #include <string>
9 #include <map>
10 
11 #include <cstdlib>
12 #include <cstdio>
13 
14 namespace meow {
15 
21 template<size_t id>
22 class ObjSelector {
23 private:
24  struct Info {
25  ObjSelector* parent_;
26  ObjBase const* pointer_;
27  bool autoDelete_;
28  //
29  Info(ObjSelector* parent,
30  ObjBase const* ptr,
31  bool autoDelete) {
32  parent_ = parent;
33  pointer_ = ptr;
34  autoDelete_ = autoDelete;
35  }
36  ~Info() {
37  if (autoDelete_) {
38  delete pointer_;
39  }
40  if (parent_ != NULL) {
41  parent_->me_.second = NULL;
42  }
43  }
44  };
45  friend struct Info;
46 
47  typedef typename std::map<std::string, Info*> Funcs;
48  typedef typename std::map<std::string, Info*>::iterator FuncsIterator;
49 
50  static Funcs& funcs() {
51  static Funcs f;
52  return f;
53  }
54  static Info* add(std::string name,
55  ObjSelector* parent,
56  ObjBase* ptr,
57  bool autoDelete) {
58  Info* info = new Info(parent, ptr, autoDelete);
59  del(name);
60  funcs()[name] = info;
61  return info;
62  }
63 
64  std::pair<std::string, Info*> me_;
65 public:
69  static void add(std::string name, ObjBase* obj, bool autoDelete) {
70  add(name, NULL, obj, autoDelete);
71  }
72 
76  static void add(ObjBase* obj, bool autoDelete) {
77  add(obj->type(), NULL, obj, autoDelete);
78  }
79 
83  static void del(std::string name) {
84  if (funcs().find(name) != funcs().end()) {
85  delete funcs()[name];
86  funcs().erase(name);
87  }
88  }
89 
93  static ObjBase const* get(std::string name) {
94  if (funcs().find(name) == funcs().end()) return NULL;
95  return funcs()[name]->pointer_;
96  }
97 
101  static ObjBase* create(std::string name) {
102  ObjBase const* ptr = get(name);
103  if(ptr == NULL) return NULL;
104  return ptr->create();
105  }
106 
110  static bool exist(ObjBase* obj) {
111  for (FuncsIterator it = funcs().begin(); it != funcs().end(); it++) {
112  if (it->second->pointer_ == obj ||
113  (it->second->pointer_ != NULL &&
114  it->second->pointer_->type() == obj->type())) {
115  return true;
116  }
117  }
118  return false;
119  }
120 
124  static std::string name(ObjBase* obj) {
125  for (FuncsIterator it = funcs().begin(); it != funcs().end(); it++) {
126  if (it->second->pointer_ == obj ||
127  (it->second->pointer_ != NULL &&
128  it->second->pointer_->type() == obj->type())) {
129  return it->first;
130  }
131  }
132  return std::string();
133  }
134 
138  static std::vector<std::string> names() {
139  std::vector<std::string> ret;
140  for (FuncsIterator it = funcs().begin(); it != funcs().end(); it++)
141  ret.push_back(it->first);
142  return ret;
143  }
144 
148  ObjSelector(std::string name, ObjBase* obj, bool autoDelete) {
149  me_.first = name;
150  me_.second = add(me_.first, this, obj, autoDelete);
151  }
152 
156  ObjSelector(ObjBase* obj, bool autoDelete) {
157  me_.first = obj->type();
158  me_.second = add(me_.first, this, obj, autoDelete);
159  }
160 
163  if (me_.second != NULL) {
164  del(me_.first);
165  }
166  }
167 
171  static bool write(FILE* f, bool binary, ObjBase* obj, unsigned int fg) {
172  if (!exist(obj)) return false;
173  char const* nme = name(obj).c_str();
174  size_t len = strlen(nme);
175  if (binary) {
176  if (fwrite(&len, sizeof(size_t ), 1, f) < 1) return false;
177  if (fwrite(nme , sizeof(char ), len, f) < len) return false;
178  if (fwrite(&fg , sizeof(unsigned int), 1, f) < 1) return false;
179  } else {
180  if (fprintf(f, "%s %u\n", nme, fg) < 2) return false;
181  }
182  return obj->write(f, binary, fg);
183  }
184 
188  static ObjBase* read(FILE* f, bool binary) {
189  static char name[2048];
190  size_t len;
191  unsigned int fg;
192  if (binary) {
193  if (fread(&len, sizeof(size_t ), 1, f) < 1) return NULL;
194  if (fread(name, sizeof(char ), len, f) < len) return NULL;
195  if (fread(&fg , sizeof(unsigned int), 1, f) < 1) return NULL;
196  name[len] = '\0';
197  } else {
198  if (fscanf(f, "%s %u", name, &fg) < 2) return NULL;
199  }
200  ObjBase* ret = create(std::string(name));
201  if (ret != NULL && ret->read(f, binary, fg) == false) {
202  delete ret;
203  ret = NULL;
204  }
205  return ret;
206  }
207 };
208 
209 static const size_t kGlobalSeletorID = 0;
210 
211 }
212 
213 #endif // oo_ObjSelector_H__