Templates -- Meow  204.13.18
A C++ template contains kinds of interesting classes and functions
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 
37  ~Info() {
38  if (autoDelete_) {
39  delete pointer_;
40  }
41  if (parent_ != NULL) {
42  parent_->me_.second = NULL;
43  }
44  }
45  };
46  friend struct Info;
47 
48  typedef typename std::map<std::string, Info*> Infos;
49  typedef typename std::map<std::string, Info*>::iterator InfosIterator;
50 
51  static Infos& funcs() {
52  static Infos f;
53  return f;
54  }
55  static Info* add(std::string name,
56  ObjSelector* parent,
57  ObjBase* ptr,
58  bool autoDelete) {
59  Info* info = new Info(parent, ptr, autoDelete);
60  del(name);
61  funcs()[name] = info;
62  return info;
63  }
64 
65  std::pair<std::string, Info*> me_;
66 public:
70  static void add(std::string name, ObjBase* obj, bool autoDelete) {
71  add(name, NULL, obj, autoDelete);
72  }
73 
77  static void add(ObjBase* obj, bool autoDelete) {
78  add(obj->type(), NULL, obj, autoDelete);
79  }
80 
84  static void del(std::string name) {
85  if (funcs().find(name) != funcs().end()) {
86  delete funcs()[name];
87  funcs().erase(name);
88  }
89  }
90 
94  static ObjBase const* get(std::string name) {
95  if (funcs().find(name) == funcs().end()) return NULL;
96  return funcs()[name]->pointer_;
97  }
98 
102  static ObjBase* create(std::string name) {
103  ObjBase const* ptr = get(name);
104  if(ptr == NULL) return NULL;
105  return ptr->create();
106  }
107 
111  static bool exist(ObjBase* obj) {
112  for (InfosIterator it = funcs().begin(); it != funcs().end(); it++) {
113  if (it->second->pointer_ == obj ||
114  (it->second->pointer_ != NULL &&
115  it->second->pointer_->type() == obj->type())) {
116  return true;
117  }
118  }
119  return false;
120  }
121 
125  static std::string name(ObjBase* obj) {
126  for (InfosIterator it = funcs().begin(); it != funcs().end(); it++) {
127  if (it->second->pointer_ == obj ||
128  (it->second->pointer_ != NULL &&
129  it->second->pointer_->type() == obj->type())) {
130  return it->first;
131  }
132  }
133  return std::string();
134  }
135 
139  static std::vector<std::string> names() {
140  std::vector<std::string> ret;
141  for (InfosIterator it = funcs().begin(); it != funcs().end(); it++)
142  ret.push_back(it->first);
143  return ret;
144  }
145 
149  ObjSelector(std::string name, ObjBase* obj, bool autoDelete) {
150  me_.first = name;
151  me_.second = add(me_.first, this, obj, autoDelete);
152  }
153 
157  ObjSelector(ObjBase* obj, bool autoDelete) {
158  me_.first = obj->type();
159  me_.second = add(me_.first, this, obj, autoDelete);
160  }
161 
164  if (me_.second != NULL) {
165  del(me_.first);
166  }
167  }
168 
172  static bool write(FILE* f, bool binary, ObjBase* obj, unsigned int fg) {
173  if (!exist(obj)) return false;
174  char const* nme = name(obj).c_str();
175  size_t len = strlen(nme);
176  if (binary) {
177  if (fwrite(&len, sizeof(size_t ), 1, f) < 1) return false;
178  if (fwrite(nme , sizeof(char ), len, f) < len) return false;
179  if (fwrite(&fg , sizeof(unsigned int), 1, f) < 1) return false;
180  } else {
181  if (fprintf(f, "%s %u\n", nme, fg) < 2) return false;
182  }
183  return obj->write(f, binary, fg);
184  }
185 
189  static ObjBase* read(FILE* f, bool binary) {
190  static char name[2048];
191  size_t len;
192  unsigned int fg;
193  if (binary) {
194  if (fread(&len, sizeof(size_t ), 1, f) < 1) return NULL;
195  if (fread(name, sizeof(char ), len, f) < len) return NULL;
196  if (fread(&fg , sizeof(unsigned int), 1, f) < 1) return NULL;
197  name[len] = '\0';
198  } else {
199  if (fscanf(f, "%s %u", name, &fg) < 2) return NULL;
200  }
201  ObjBase* ret = create(std::string(name));
202  if (ret != NULL && ret->read(f, binary, fg) == false) {
203  delete ret;
204  ret = NULL;
205  }
206  return ret;
207  }
208 };
209 
210 static const size_t kGlobalSeletorID = 0;
211 
212 } // meow
213 
214 #endif // oo_ObjSelector_H__
friend struct Info
Definition: ObjSelector.h:46
static void add(ObjBase *obj, bool autoDelete)
新增(註冊) 一個Class (必須要繼承自 ObjBase) 並且默認type為name
Definition: ObjSelector.h:77
static ObjBase * read(FILE *f, bool binary)
從檔案中讀取一個物件(該物件必須要有註冊過)
Definition: ObjSelector.h:189
ObjSelector(ObjBase *obj, bool autoDelete)
宣告一個ObjSelector實體, 並且註冊一個 ObjBase
Definition: ObjSelector.h:157
static bool exist(ObjBase *obj)
利用type檢查是否有註冊過同種類的Class
Definition: ObjSelector.h:111
利用register的概念, 達到runtime用string選擇要new的class
Definition: ObjSelector.h:22
virtual ObjBase * create() const
回傳一個new出來的物件, 預設implement為直接回傳 NULL
Definition: ObjBase.h:52
一切物件的Base, 並要求每個物件都要有read, write, create, ... 等功能
Definition: ObjBase.h:15
ObjSelector(std::string name, ObjBase *obj, bool autoDelete)
宣告一個ObjSelector實體, 並且註冊一個 ObjBase
Definition: ObjSelector.h:149
static ObjBase * create(std::string name)
回傳一個之前註冊過得Class new出來的實體
Definition: ObjSelector.h:102
~ObjSelector()
解構子
Definition: ObjSelector.h:163
static std::string name(ObjBase *obj)
利用type尋找name
Definition: ObjSelector.h:125
static void add(std::string name, ObjBase *obj, bool autoDelete)
新增(註冊) 一個Class (必須要繼承自 ObjBase) 並且給定其Name
Definition: ObjSelector.h:70
virtual bool read(FILE *f, bool bin, unsigned int fg)
將物件從檔案讀出, 預設implement為直接回傳 false
Definition: ObjBase.h:45
static bool write(FILE *f, bool binary, ObjBase *obj, unsigned int fg)
將一個物件寫到檔案裡(該物件必須要有註冊過)
Definition: ObjSelector.h:172
static std::vector< std::string > names()
回傳所有註冊過的name
Definition: ObjSelector.h:139
static const size_t kGlobalSeletorID
Definition: ObjSelector.h:210
static void del(std::string name)
依照name刪除之前註冊過得Class
Definition: ObjSelector.h:84
virtual bool write(FILE *f, bool bin, unsigned int fg) const
將物件寫入檔案, 預設implement為直接回傳 false
Definition: ObjBase.h:33
virtual std::string type() const
用std::string回傳這個class的type name
Definition: ObjBase.h:77