Anope IRC Services  Version 2.0
extensible.h
Go to the documentation of this file.
1 /*
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  */
9 
10 #ifndef EXTENSIBLE_H
11 #define EXTENSIBLE_H
12 
13 #include "anope.h"
14 #include "serialize.h"
15 #include "service.h"
16 #include "logger.h"
17 
18 class Extensible;
19 
21 {
22  protected:
23  std::map<Extensible *, void *> items;
24 
25  ExtensibleBase(Module *m, const Anope::string &n);
26  ~ExtensibleBase();
27 
28  public:
29  virtual void Unset(Extensible *obj) = 0;
30 
31  /* called when an object we are keep track of is serializing */
32  virtual void ExtensibleSerialize(const Extensible *, const Serializable *, Serialize::Data &) const { }
34 };
35 
37 {
38  public:
39  std::set<ExtensibleBase *> extension_items;
40 
41  virtual ~Extensible();
42 
43  template<typename T> T* GetExt(const Anope::string &name) const;
44  bool HasExt(const Anope::string &name) const;
45 
46  template<typename T> T* Extend(const Anope::string &name, const T &what);
47  template<typename T> T* Extend(const Anope::string &name);
48  template<typename T> T* Require(const Anope::string &name);
49  template<typename T> void Shrink(const Anope::string &name);
50 
51  static void ExtensibleSerialize(const Extensible *, const Serializable *, Serialize::Data &data);
52  static void ExtensibleUnserialize(Extensible *, Serializable *, Serialize::Data &data);
53 };
54 
55 template<typename T>
57 {
58  protected:
59  virtual T *Create(Extensible *) = 0;
60 
61  public:
63 
65  {
66  while (!items.empty())
67  {
68  std::map<Extensible *, void *>::iterator it = items.begin();
69  Extensible *obj = it->first;
70  T *value = static_cast<T *>(it->second);
71 
72  obj->extension_items.erase(this);
73  items.erase(it);
74  delete value;
75  }
76  }
77 
78  T* Set(Extensible *obj, const T &value)
79  {
80  T* t = Set(obj);
81  if (t)
82  *t = value;
83  return t;
84  }
85 
86  T* Set(Extensible *obj)
87  {
88  T* t = Create(obj);
89  Unset(obj);
90  items[obj] = t;
91  obj->extension_items.insert(this);
92  return t;
93  }
94 
96  {
97  T *value = Get(obj);
98  items.erase(obj);
99  obj->extension_items.erase(this);
100  delete value;
101  }
102 
103  T* Get(const Extensible *obj) const
104  {
105  std::map<Extensible *, void *>::const_iterator it = items.find(const_cast<Extensible *>(obj));
106  if (it != items.end())
107  return static_cast<T *>(it->second);
108  return NULL;
109  }
110 
111  bool HasExt(const Extensible *obj) const
112  {
113  return items.find(const_cast<Extensible *>(obj)) != items.end();
114  }
115 
117  {
118  T* t = Get(obj);
119  if (t)
120  return t;
121 
122  return Set(obj);
123  }
124 };
125 
126 template<typename T>
128 {
129  protected:
131  {
132  return new T(obj);
133  }
134  public:
136 };
137 
138 template<typename T>
140 {
141  protected:
143  {
144  return new T();
145  }
146  public:
148 };
149 
150 template<>
151 class PrimitiveExtensibleItem<bool> : public BaseExtensibleItem<bool>
152 {
153  protected:
155  {
156  return NULL;
157  }
158  public:
160 };
161 
162 template<typename T>
164 {
165  public:
167 
169  {
170  T* t = this->Get(e);
171  data[this->name] << *t;
172  }
173 
175  {
176  T t;
177  if (data[this->name] >> t)
178  this->Set(e, t);
179  else
180  this->Unset(e);
181  }
182 };
183 
184 template<>
186 {
187  public:
189 
191  {
192  data[this->name] << true;
193  }
194 
196  {
197  bool b = false;
198  data[this->name] >> b;
199  if (b)
200  this->Set(e);
201  else
202  this->Unset(e);
203  }
204 };
205 
206 template<typename T>
207 struct ExtensibleRef : ServiceReference<BaseExtensibleItem<T> >
208 {
209  ExtensibleRef(const Anope::string &n) : ServiceReference<BaseExtensibleItem<T> >("Extensible", n) { }
210 };
211 
212 template<typename T>
214 {
215  ExtensibleRef<T> ref(name);
216  if (ref)
217  return ref->Get(this);
218 
219  Log(LOG_DEBUG) << "GetExt for nonexistent type " << name << " on " << static_cast<const void *>(this);
220  return NULL;
221 }
222 
223 template<typename T>
224 T* Extensible::Extend(const Anope::string &name, const T &what)
225 {
226  T* t = Extend<T>(name);
227  if (t)
228  *t = what;
229  return t;
230 }
231 
232 template<typename T>
234 {
235  ExtensibleRef<T> ref(name);
236  if (ref)
237  return ref->Set(this);
238 
239  Log(LOG_DEBUG) << "Extend for nonexistent type " << name << " on " << static_cast<void *>(this);
240  return NULL;
241 }
242 
243 template<typename T>
245 {
246  if (HasExt(name))
247  return GetExt<T>(name);
248  else
249  return Extend<T>(name);
250 }
251 
252 template<typename T>
254 {
255  ExtensibleRef<T> ref(name);
256  if (ref)
257  ref->Unset(this);
258  else
259  Log(LOG_DEBUG) << "Shrink for nonexistent type " << name << " on " << static_cast<void *>(this);
260 }
261 
262 #endif // EXTENSIBLE_H
void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
Definition: extensible.h:168
T * Set(Extensible *obj)
Definition: extensible.h:86
ExtensibleRef(const Anope::string &n)
Definition: extensible.h:209
virtual void ExtensibleUnserialize(Extensible *, Serializable *, Serialize::Data &)
Definition: extensible.h:33
T * Extend(const Anope::string &name, const T &what)
Definition: extensible.h:224
bool * Create(Extensible *) anope_override
Definition: extensible.h:154
T * Create(Extensible *obj) anope_override
Definition: extensible.h:130
void Unset(Extensible *obj) anope_override
Definition: extensible.h:95
T * Require(const Anope::string &name)
Definition: extensible.h:244
T * Require(Extensible *obj)
Definition: extensible.h:116
void Shrink(const Anope::string &name)
Definition: extensible.h:253
virtual void ExtensibleSerialize(const Extensible *, const Serializable *, Serialize::Data &) const
Definition: extensible.h:32
T * Set(Extensible *obj, const T &value)
Definition: extensible.h:78
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
Definition: extensible.h:174
T * Create(Extensible *obj) anope_override
Definition: extensible.h:142
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
Definition: extensible.h:195
std::map< Extensible *, void * > items
Definition: extensible.h:23
std::set< ExtensibleBase * > extension_items
Definition: extensible.h:39
#define anope_override
Definition: services.h:56
SerializableExtensibleItem(Module *m, const Anope::string &n)
Definition: extensible.h:166
void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
Definition: extensible.h:190
#define CoreExport
Definition: services.h:62
PrimitiveExtensibleItem(Module *m, const Anope::string &n)
Definition: extensible.h:159
BaseExtensibleItem(Module *m, const Anope::string &n)
Definition: extensible.h:62
Anope::string name
Definition: service.h:88
PrimitiveExtensibleItem(Module *m, const Anope::string &n)
Definition: extensible.h:147
virtual T * Create(Extensible *)=0
T * Get(const Extensible *obj) const
Definition: extensible.h:103
Anope::string name
Definition: access.cpp:22
Definition: logger.h:53
SerializableExtensibleItem(Module *m, const Anope::string &n)
Definition: extensible.h:188
T * GetExt(const Anope::string &name) const
Definition: extensible.h:213
bool HasExt(const Extensible *obj) const
Definition: extensible.h:111
ExtensibleItem(Module *m, const Anope::string &n)
Definition: extensible.h:135
bool HasExt(const Anope::string &name) const
Definition: extensible.cpp:31