diff options
Diffstat (limited to 'include/extensible.h')
-rw-r--r-- | include/extensible.h | 210 |
1 files changed, 57 insertions, 153 deletions
diff --git a/include/extensible.h b/include/extensible.h index f3fb6c96a..1cac39859 100644 --- a/include/extensible.h +++ b/include/extensible.h @@ -1,16 +1,25 @@ /* + * Anope IRC Services * - * (C) 2003-2017 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2009-2017 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope is free software; you can + * redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software + * Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see see <http://www.gnu.org/licenses/>. */ -#ifndef EXTENSIBLE_H -#define EXTENSIBLE_H +#pragma once #include "anope.h" -#include "serialize.h" #include "service.h" #include "logger.h" @@ -22,47 +31,37 @@ class CoreExport ExtensibleBase : public Service std::map<Extensible *, void *> items; ExtensibleBase(Module *m, const Anope::string &n); - ~ExtensibleBase(); + ExtensibleBase(Module *m, const Anope::string &t, const Anope::string &n); public: - virtual void Unset(Extensible *obj) = 0; - - /* called when an object we are keep track of is serializing */ - virtual void ExtensibleSerialize(const Extensible *, const Serializable *, Serialize::Data &) const { } - virtual void ExtensibleUnserialize(Extensible *, Serializable *, Serialize::Data &) { } + virtual void Unset(Extensible *obj) anope_abstract; + + static constexpr const char *NAME = "Extensible"; }; class CoreExport Extensible { public: - std::set<ExtensibleBase *> extension_items; + std::vector<ExtensibleBase *> extension_items; virtual ~Extensible(); - void UnsetExtensibles(); - - template<typename T> T* GetExt(const Anope::string &name) const; - bool HasExt(const Anope::string &name) const; + template<typename T> T* GetExt(const Anope::string &name); + bool HasExtOK(const Anope::string &name); template<typename T> T* Extend(const Anope::string &name, const T &what); - template<typename T> T* Extend(const Anope::string &name); - template<typename T> T* Require(const Anope::string &name); - template<typename T> void Shrink(const Anope::string &name); - static void ExtensibleSerialize(const Extensible *, const Serializable *, Serialize::Data &data); - static void ExtensibleUnserialize(Extensible *, Serializable *, Serialize::Data &data); + template<typename T> void Shrink(const Anope::string &name); }; template<typename T> -class BaseExtensibleItem : public ExtensibleBase +class ExtensibleItem : public ExtensibleBase { - protected: - virtual T *Create(Extensible *) = 0; - public: - BaseExtensibleItem(Module *m, const Anope::string &n) : ExtensibleBase(m, n) { } + ExtensibleItem(Module *m, const Anope::string &n) : ExtensibleBase(m, n) { } + ExtensibleItem(Module *m, const Anope::string &t, const Anope::string &n) : ExtensibleBase(m, t, n) { } - ~BaseExtensibleItem() + ~ExtensibleItem() { while (!items.empty()) { @@ -70,48 +69,49 @@ class BaseExtensibleItem : public ExtensibleBase Extensible *obj = it->first; T *value = static_cast<T *>(it->second); - obj->extension_items.erase(this); + auto it2 = std::find(obj->extension_items.begin(), obj->extension_items.end(), this); + if (it2 != obj->extension_items.end()) + obj->extension_items.erase(it2); items.erase(it); + delete value; } } T* Set(Extensible *obj, const T &value) { - T* t = Set(obj); - if (t) - *t = value; - return t; - } - - T* Set(Extensible *obj) - { - T* t = Create(obj); + T* t = new T(value); Unset(obj); + items[obj] = t; - obj->extension_items.insert(this); + obj->extension_items.push_back(this); + return t; } - void Unset(Extensible *obj) anope_override + void Unset(Extensible *obj) override { T *value = Get(obj); + items.erase(obj); - obj->extension_items.erase(this); + auto it = std::find(obj->extension_items.begin(), obj->extension_items.end(), this); + if (it != obj->extension_items.end()) + obj->extension_items.erase(it); + delete value; } - T* Get(const Extensible *obj) const + T* Get(Extensible *obj) { - std::map<Extensible *, void *>::const_iterator it = items.find(const_cast<Extensible *>(obj)); + std::map<Extensible *, void *>::const_iterator it = items.find(obj); if (it != items.end()) return static_cast<T *>(it->second); - return NULL; + return nullptr; } - bool HasExt(const Extensible *obj) const + bool HasExt(Extensible *obj) { - return items.find(const_cast<Extensible *>(obj)) != items.end(); + return items.find(obj) != items.end(); } T* Require(Extensible *obj) @@ -120,144 +120,48 @@ class BaseExtensibleItem : public ExtensibleBase if (t) return t; - return Set(obj); - } -}; - -template<typename T> -class ExtensibleItem : public BaseExtensibleItem<T> -{ - protected: - T* Create(Extensible *obj) anope_override - { - return new T(obj); - } - public: - ExtensibleItem(Module *m, const Anope::string &n) : BaseExtensibleItem<T>(m, n) { } -}; - -template<typename T> -class PrimitiveExtensibleItem : public BaseExtensibleItem<T> -{ - protected: - T* Create(Extensible *obj) anope_override - { - return new T(); - } - public: - PrimitiveExtensibleItem(Module *m, const Anope::string &n) : BaseExtensibleItem<T>(m, n) { } -}; - -template<> -class PrimitiveExtensibleItem<bool> : public BaseExtensibleItem<bool> -{ - protected: - bool* Create(Extensible *) anope_override - { - return NULL; + return Set(obj, T()); } - public: - PrimitiveExtensibleItem(Module *m, const Anope::string &n) : BaseExtensibleItem<bool>(m, n) { } }; template<typename T> -class SerializableExtensibleItem : public PrimitiveExtensibleItem<T> +struct ExtensibleRef : ServiceReference<ExtensibleItem<T>> { - public: - SerializableExtensibleItem(Module *m, const Anope::string &n) : PrimitiveExtensibleItem<T>(m, n) { } - - void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override - { - T* t = this->Get(e); - data[this->name] << *t; - } - - void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override - { - T t; - if (data[this->name] >> t) - this->Set(e, t); - else - this->Unset(e); - } -}; - -template<> -class SerializableExtensibleItem<bool> : public PrimitiveExtensibleItem<bool> -{ - public: - SerializableExtensibleItem(Module *m, const Anope::string &n) : PrimitiveExtensibleItem<bool>(m, n) { } - - void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override - { - data[this->name] << true; - } - - void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override - { - bool b = false; - data[this->name] >> b; - if (b) - this->Set(e); - else - this->Unset(e); - } + ExtensibleRef(const Anope::string &n) : ServiceReference<ExtensibleItem<T>>(n) { } }; template<typename T> -struct ExtensibleRef : ServiceReference<BaseExtensibleItem<T> > -{ - ExtensibleRef(const Anope::string &n) : ServiceReference<BaseExtensibleItem<T> >("Extensible", n) { } -}; - -template<typename T> -T* Extensible::GetExt(const Anope::string &name) const +T* Extensible::GetExt(const Anope::string &name) { ExtensibleRef<T> ref(name); if (ref) return ref->Get(this); - Log(LOG_DEBUG) << "GetExt for nonexistent type " << name << " on " << static_cast<const void *>(this); + Anope::Logger.Debug("GetExt for nonexistent type {0} on {1}", name, static_cast<void *>(this)); return NULL; } template<typename T> T* Extensible::Extend(const Anope::string &name, const T &what) { - T* t = Extend<T>(name); - if (t) - *t = what; - return t; -} - -template<typename T> -T* Extensible::Extend(const Anope::string &name) -{ ExtensibleRef<T> ref(name); if (ref) - return ref->Set(this); + { + ref->Set(this, what); + return ref->Get(this); + } - Log(LOG_DEBUG) << "Extend for nonexistent type " << name << " on " << static_cast<void *>(this); + Anope::Logger.Debug("Extend for nonexistent type {0} on {1}", name, static_cast<void *>(this)); return NULL; } template<typename T> -T* Extensible::Require(const Anope::string &name) -{ - if (HasExt(name)) - return GetExt<T>(name); - else - return Extend<T>(name); -} - -template<typename T> void Extensible::Shrink(const Anope::string &name) { ExtensibleRef<T> ref(name); if (ref) ref->Unset(this); else - Log(LOG_DEBUG) << "Shrink for nonexistent type " << name << " on " << static_cast<void *>(this); + Anope::Logger.Debug("Shrink for nonexistent type {0} on {1}", name, static_cast<void *>(this)); } -#endif // EXTENSIBLE_H |