From ada65a3bafd3ae6738a80972cf0d2f31ad19a7ae Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 22 Aug 2010 00:34:02 -0400 Subject: Added a classbase for the major classes, makes dynamic_reference invalidation really work. This also cleans up a bit of the code in the modestacker. --- include/extensible.h | 2 +- include/modes.h | 68 ++++--------------------------------- include/modules.h | 95 ++++++++++++++++++++++++++++++++++------------------ include/opertype.h | 2 +- include/servers.h | 2 +- include/services.h | 15 +++++++++ 6 files changed, 87 insertions(+), 97 deletions(-) (limited to 'include') diff --git a/include/extensible.h b/include/extensible.h index ffdd395ee..884ca8ecb 100644 --- a/include/extensible.h +++ b/include/extensible.h @@ -57,7 +57,7 @@ template class ExtensibleItemPointerArray : public ExtensibleItemBas T *GetItem() const { return Item; } }; -class CoreExport Extensible +class CoreExport Extensible : public virtual Base { private: typedef std::map extensible_map; diff --git a/include/modes.h b/include/modes.h index 4d0706a9a..e938a65c6 100644 --- a/include/modes.h +++ b/include/modes.h @@ -74,7 +74,7 @@ enum ModeClass /** This class is the basis of all modes in Anope */ -class CoreExport Mode +class CoreExport Mode : public virtual Base { public: /* Class of mode this is */ @@ -350,9 +350,9 @@ class StackerInfo { public: /* Modes to be added */ - std::list > AddModes; + std::list > AddModes; /* Modes to be deleted */ - std::list > DelModes; + std::list > DelModes; /* The type of object this stacker info is for */ StackerType Type; /* Bot this is sent from */ @@ -363,7 +363,7 @@ class StackerInfo * @param Set true if setting, false if unsetting * @param Param The param for the mode */ - void AddMode(void *Mode, bool Set, const Anope::string &Param); + void AddMode(Base *Mode, bool Set, const Anope::string &Param); }; /** This is mode manager @@ -376,13 +376,13 @@ class CoreExport ModeManager { protected: /* List of pairs of user/channels and their stacker info */ - static std::list > StackerObjects; + static std::list > StackerObjects; /** Get the stacker info for an item, if one doesnt exist it is created * @param Item The user/channel etc * @return The stacker info */ - static StackerInfo *GetInfo(void *Item); + static StackerInfo *GetInfo(Base *Item); /** Build a list of mode strings to send to the IRCd from the mode stacker * @param info The stacker info for a channel or user @@ -390,24 +390,6 @@ class CoreExport ModeManager */ static std::list BuildModeStrings(StackerInfo *info); - /** Add a mode to the stacker, internal use only - * @param bi The client to set the modes from - * @param u The user - * @param um The user mode - * @param Set Adding or removing? - * @param Param A param, if there is one - */ - static void StackerAddInternal(BotInfo *bi, User *u, UserMode *um, bool Set, const Anope::string &Param); - - /** Add a mode to the stacker, internal use only - * @param bi The client to set the modes from - * @param c The channel - * @param cm The channel mode - * @param Set Adding or removing? - * @param Param A param, if there is one - */ - static void StackerAddInternal(BotInfo *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param); - /** Really add a mode to the stacker, internal use only * @param bi The client to set the modes from * @param Object The object, user/channel @@ -416,7 +398,7 @@ class CoreExport ModeManager * @param Param A param, if there is one * @param Type The type this is, user or channel */ - static void StackerAddInternal(BotInfo *bi, void *Object, void *Mode, bool Set, const Anope::string &Param, StackerType Type); + static void StackerAddInternal(BotInfo *bi, Base *Object, Base *Mode, bool Set, const Anope::string &Param, StackerType Type); public: /* List of all modes Anope knows about */ @@ -489,24 +471,6 @@ class CoreExport ModeManager */ static void StackerAdd(BotInfo *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param = ""); - /** Add a mode to the stacker to be set on a channel - * @param bi The client to set the modes from - * @param c The channel - * @param Name The channel mode name - * @param Set true for setting, false for removing - * @param Param The param, if there is one - */ - static void StackerAdd(BotInfo *bi, Channel *c, ChannelModeName Name, bool Set, const Anope::string &Param = ""); - - /** Add a mode to the stacker to be set on a channel - * @param bi The client to set the modes from - * @param c The channel - * @param Mode The mode char - * @param Set true for setting, false for removing - * @param Param The param, if there is one - */ - static void StackerAdd(BotInfo *bi, Channel *c, const char Mode, bool Set, const Anope::string &Param = ""); - /** Add a mode to the stacker to be set on a user * @param bi The client to set the modes from * @param u The user @@ -516,24 +480,6 @@ class CoreExport ModeManager */ static void StackerAdd(BotInfo *bi, User *u, UserMode *um, bool Set, const Anope::string &Param = ""); - /** Add a mode to the stacker to be set on a user - * @param bi The client to set the modes from - * @param u The user - * @param Name The user mode name - * @param Set true for setting, false for removing - * @param Param The param, if there is one - */ - static void StackerAdd(BotInfo *bi, User *u, UserModeName Name, bool Set, const Anope::string &Param = ""); - - /** Add a mode to the stacker to be set on a user - * @param bi The client to set the modes from - * @param u The user - * @param Mode The mode to be set - * @param Set true for setting, false for removing - * @param Param The param, if there is one - */ - static void StackerAdd(BotInfo *bi, User *u, const char Mode, bool Set, const Anope::string &Param = ""); - /** Process all of the modes in the stacker and send them to the IRCd to be set on channels/users */ static void ProcessModes(); diff --git a/include/modules.h b/include/modules.h index 51581438c..0d279c6c0 100644 --- a/include/modules.h +++ b/include/modules.h @@ -64,7 +64,7 @@ if (true) \ { \ (*_i)->x ; \ } \ - catch (const CoreException &modexcept) \ + catch (const ModuleException &modexcept) \ { \ Alog() << "Exception caught: " << modexcept.GetReason(); \ } \ @@ -96,7 +96,7 @@ if (true) \ break; \ } \ } \ - catch (const CoreException &modexcept) \ + catch (const ModuleException &modexcept) \ { \ Alog() << "Exception caught: " << modexcept.GetReason(); \ } \ @@ -201,7 +201,7 @@ class CallBack; /** Every module in Anope is actually a class. */ -class CoreExport Module +class CoreExport Module : public virtual Base { private: bool permanent; @@ -1249,7 +1249,7 @@ class CallBack : public Timer } }; -class Service +class Service : public virtual Base { public: Module *owner; @@ -1260,55 +1260,66 @@ class Service virtual ~Service(); }; -class dynamic_reference_base +class dynamic_reference_base : public virtual Base { + protected: + bool invalid; public: - dynamic_reference_base(); - - virtual ~dynamic_reference_base(); + dynamic_reference_base() : invalid(false) { } + virtual ~dynamic_reference_base() { } + inline void Invalidate() { this->invalid = true; } }; -extern std::list dyn_references; - template class dynamic_reference : public dynamic_reference_base { protected: T *ref; public: - dynamic_reference() : dynamic_reference_base(), ref(NULL) { } - - dynamic_reference(T *obj) : dynamic_reference_base(), ref(obj) { } - - virtual ~dynamic_reference() { } - - virtual operator bool() + dynamic_reference(T *obj) : ref(obj) { - return this->ref; + if (ref) + ref->AddReference(this); } - virtual inline T *operator->() + virtual ~dynamic_reference() { - return this->ref; + if (this->invalid) + { + this->invalid = false; + this->ref = NULL; + } + else if (ref) + ref->DelReference(this); } - void Invalidate() + virtual operator bool() { - this->ref = NULL; + if (this->invalid) + { + this->invalid = false; + this->ref = NULL; + } + return this->ref; } - static void Invalidate(T *obj) + virtual inline void operator=(T *newref) { - for (std::list::iterator it = dyn_references.begin(), it_end = dyn_references.end(); it != it_end;) + if (this->invalid) { - dynamic_reference *d = static_cast *>(*it); - ++it; - - if (d && d->ref == obj) - { - d->Invalidate(); - } + this->invalid = false; + this->ref = NULL; } + else if (this->ref) + this->ref->DelReference(this); + this->ref = newref; + if (this->ref) + this->ref->AddReference(this); + } + + virtual inline T *operator->() + { + return this->ref; } }; @@ -1319,25 +1330,43 @@ class service_reference : public dynamic_reference Anope::string name; public: - service_reference(Module *o, const Anope::string &n) : dynamic_reference(), owner(o), name(n) + service_reference(Module *o, const Anope::string &n) : dynamic_reference(static_cast(ModuleManager::GetService(this->name))), owner(o), name(n) { } - ~service_reference() + virtual ~service_reference() { } operator bool() { + if (this->invalid) + { + this->invalid = false; + this->ref = NULL; + } if (!this->ref) + { this->ref = static_cast(ModuleManager::GetService(this->name)); + if (this->ref) + this->ref->AddReference(this); + } return this->ref; } inline T *operator->() { + if (this->invalid) + { + this->invalid = false; + this->ref = NULL; + } if (!this->ref) + { this->ref = static_cast(ModuleManager::GetService(this->name)); + if (this->ref) + this->ref->AddReference(this); + } return this->ref; } }; diff --git a/include/opertype.h b/include/opertype.h index 40607b39f..faf074bf8 100644 --- a/include/opertype.h +++ b/include/opertype.h @@ -10,7 +10,7 @@ #include "hashcomp.h" -class CoreExport OperType +class CoreExport OperType : public virtual Base { private: /** The name of this opertype, e.g. "sra". diff --git a/include/servers.h b/include/servers.h index cbf017df8..4abe168db 100644 --- a/include/servers.h +++ b/include/servers.h @@ -74,7 +74,7 @@ enum ServerFlag /** Class representing a server */ -class CoreExport Server : public Flags +class CoreExport Server : public virtual Base, public Flags { private: /* Server name */ diff --git a/include/services.h b/include/services.h index ca02d087e..2cda56a31 100644 --- a/include/services.h +++ b/include/services.h @@ -193,6 +193,21 @@ extern "C" void __pfnBkCheck() {} #include "anope.h" +class dynamic_reference_base; + +/** The base class that most classes in Anope inherit from + */ +class CoreExport Base +{ + /* References to this base class */ + std::set References; + public: + Base(); + virtual ~Base(); + void AddReference(dynamic_reference_base *r); + void DelReference(dynamic_reference_base *r); +}; + /** This class can be used on its own to represent an exception, or derived to represent a module-specific exception. * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not -- cgit