anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

extensible.h (5972B)

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