diff options
author | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2007-11-04 15:29:49 +0000 |
---|---|---|
committer | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2007-11-04 15:29:49 +0000 |
commit | bf44023d115745d4a6a1ce06ff291ffb73480efb (patch) | |
tree | 36cd5194e73b3fb3187d8895849ecf0f65ec3944 | |
parent | c0abad99489eb0ce0a52d98f9d6f76790a6a2db4 (diff) |
Development/Hooking in full swing now: WARNING, this will break ALL modules for the time being until complete!
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@8497 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | include/modules.h | 117 | ||||
-rw-r--r-- | src/modules.cpp | 35 |
2 files changed, 107 insertions, 45 deletions
diff --git a/include/modules.h b/include/modules.h index ab95bca26..4adab2378 100644 --- a/include/modules.h +++ b/include/modules.h @@ -123,19 +123,20 @@ typedef std::map<std::string, std::pair<int, modulelist> > interfacelist; * loaded modules in a readable simple way, e.g.: * 'FOREACH_MOD(I_OnConnect,OnConnect(user));' */ -#define FOREACH_MOD(y,x) if (ServerInstance->Config->global_implementation[y] > 0) { \ - for (int _i = 0; _i <= ServerInstance->Modules->GetCount(); _i++) { \ - if (ServerInstance->Config->implement_lists[_i][y]) \ +#define FOREACH_MOD(y,x) if (!ServerInstance->Modules->EventHandlers[y].empty()) \ +{ \ + for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ++_i) \ + { \ try \ { \ - ServerInstance->Modules->modules[_i]->x ; \ + (*_i)->x ; \ } \ catch (CoreException& modexcept) \ { \ ServerInstance->Log(DEFAULT,"Exception caught: %s",modexcept.GetReason()); \ } \ } \ - } +} /** * This #define allows us to call a method in all @@ -143,12 +144,13 @@ typedef std::map<std::string, std::pair<int, modulelist> > interfacelist; * an instance pointer to the macro. e.g.: * 'FOREACH_MOD_I(Instance, OnConnect, OnConnect(user));' */ -#define FOREACH_MOD_I(z,y,x) if (z->Config->global_implementation[y] > 0) { \ - for (int _i = 0; _i <= z->Modules->GetCount(); _i++) { \ - if (z->Config->implement_lists[_i][y]) \ +#define FOREACH_MOD_I(z,y,x) if (!z->Modules->EventHandlers[y].empty()) \ +{ \ + for (EventHandlerIter _i = z->Modules->EventHandlers[y].begin(); _i != z->Modules->EventHandlers[y].end(); ++_i) \ + { \ try \ { \ - z->Modules->modules[_i]->x ; \ + (*_i)->x ; \ } \ catch (CoreException& modexcept) \ { \ @@ -156,55 +158,55 @@ typedef std::map<std::string, std::pair<int, modulelist> > interfacelist; } \ } \ } + /** * This define is similar to the one above but returns a result in MOD_RESULT. * The first module to return a nonzero result is the value to be accepted, * and any modules after are ignored. */ -#define FOREACH_RESULT(y,x) { if (ServerInstance->Config->global_implementation[y] > 0) { \ - MOD_RESULT = 0; \ - for (int _i = 0; _i <= ServerInstance->Modules->GetCount(); _i++) { \ - if (ServerInstance->Config->implement_lists[_i][y]) { \ - try \ - { \ - int res = ServerInstance->Modules->modules[_i]->x ; \ - if (res != 0) { \ - MOD_RESULT = res; \ - break; \ - } \ - } \ - catch (CoreException& modexcept) \ - { \ - ServerInstance->Log(DEFAULT,"Exception caught: %s",modexcept.GetReason()); \ - } \ +#define FOREACH_RESULT(y,x) if (!ServerInstance->Modules->EventHandlers[y].empty()) \ +{ \ + MOD_RESULT = 0; \ + for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ++_i) \ + { \ + try \ + { \ + int res = (*_i)->x ; \ + if (res != 0) { \ + MOD_RESULT = res; \ + break; \ } \ } \ + catch (CoreException& modexcept) \ + { \ + ServerInstance->Log(DEFAULT,"Exception caught: %s",modexcept.GetReason()); \ + } \ } \ - } +} + /** * This define is similar to the one above but returns a result in MOD_RESULT. * The first module to return a nonzero result is the value to be accepted, * and any modules after are ignored. */ -#define FOREACH_RESULT_I(z,y,x) { if (z->Config->global_implementation[y] > 0) { \ - MOD_RESULT = 0; \ - for (int _i = 0; _i <= z->Modules->GetCount(); _i++) { \ - if (z->Config->implement_lists[_i][y]) { \ - try \ - { \ - int res = z->Modules->modules[_i]->x ; \ - if (res != 0) { \ - MOD_RESULT = res; \ - break; \ - } \ - } \ - catch (CoreException& modexcept) \ - { \ - z->Log(DEBUG,"Exception caught: %s",modexcept.GetReason()); \ - } \ +#define FOREACH_RESULT_I(z,y,x) if (!z->Modules->EventHandlers[y].empty()) \ +{ \ + MOD_RESULT = 0; \ + for (EventHandlerIter _i = z->Modules->EventHandlers[y].begin(); _i != z->Modules->EventHandlers[y].end(); ++_i) \ + { \ + try \ + { \ + int res = (*_i)->x ; \ + if (res != 0) { \ + MOD_RESULT = res; \ + break; \ } \ } \ + catch (CoreException& modexcept) \ + { \ + z->Log(DEBUG,"Exception caught: %s",modexcept.GetReason()); \ + } \ } \ } @@ -1555,6 +1557,10 @@ typedef std::vector<Module*> ModuleList; */ typedef std::vector<ircd_module*> ModuleHandleList; +typedef std::list<Module*> IntModuleList; +typedef std::vector<IntModuleList> EventHandlerList; +typedef IntModuleList::iterator EventHandlerIter; + /** ModuleManager takes care of all things module-related * in the core. */ @@ -1583,7 +1589,7 @@ class CoreExport ModuleManager : public classbase public: - std::vector<std::list<Module*> > EventHandlers; + EventHandlerList EventHandlers; /** A list of ircd_module* module handles * Note that this list is always exactly 255 in size. @@ -1602,6 +1608,31 @@ class CoreExport ModuleManager : public classbase ModuleManager(InspIRCd* Ins); ~ModuleManager(); + + /** Attach an event to a module + * @param i Event type to attach + * @param mod Module to attach event to + * @return True if the event was attached + */ + bool Attach(Implementation i, Module* mod); + + /** Detatch an event from a module + * @param i Event type to detach + * @param mod Module to detach event from + * @param Detach true if the event was detached + */ + bool Detach(Implementation i, Module* mod); + + /** Attach an array of events to a module + * @param i Event types (array) to attach + * @param mod Module to attach events to + */ + void Attach(Implementation* i, Module* mod, size_t sz); + + /** Detach all events from a module (used on unload) + * @param mod Module to detach from + */ + void DetachAll(Module* mod); /** Returns text describing the last module error * @return The last error message to occur diff --git a/src/modules.cpp b/src/modules.cpp index d9fca88cd..601aeabef 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -191,8 +191,7 @@ void Module::OnBufferFlushed(User*) { } void Module::OnText(User*, void*, int, const std::string&, char, CUList&) { } -ModuleManager::ModuleManager(InspIRCd* Ins) -: ModCount(0), Instance(Ins) +ModuleManager::ModuleManager(InspIRCd* Ins) : ModCount(0), Instance(Ins) { for (int n = I_BEGIN + 1; n != I_END; ++n) EventHandlers.push_back(std::list<Module*>()); @@ -202,6 +201,38 @@ ModuleManager::~ModuleManager() { } +bool ModuleManager::Attach(Implementation i, Module* mod) +{ + if (std::find(EventHandlers[i].begin(), EventHandlers[i].end(), mod) != EventHandlers[i].end()) + return false; + + EventHandlers[i].push_back(mod); + return true; +} + +bool ModuleManager::Detach(Implementation i, Module* mod) +{ + EventHandlerIter x = std::find(EventHandlers[i].begin(), EventHandlers[i].end(), mod); + + if (x == EventHandlers[i].end()) + return false; + + EventHandlers[i].erase(x); + return true; +} + +void ModuleManager::Attach(Implementation* i, Module* mod, size_t sz) +{ + for (size_t n = 0; n < sz; ++n) + Attach(i[n], mod); +} + +void ModuleManager::DetachAll(Module* mod) +{ + for (size_t n = I_BEGIN + 1; n != I_END; ++n) + Detach((Implementation)n, mod); +} + const char* ModuleManager::LastError() { return MODERR; |