diff options
120 files changed, 440 insertions, 672 deletions
diff --git a/include/modules.h b/include/modules.h index 3f99a9114..5463c2ad6 100644 --- a/include/modules.h +++ b/include/modules.h @@ -56,49 +56,56 @@ /** * This #define allows us to call a method in all * loaded modules in a readable simple way, e.g.: - * 'FOREACH_MOD(I_OnConnect,OnConnect(user));' + * + * FOREACH_MOD(OnUserConnect, (user, exempt)); */ -#define FOREACH_MOD(y, x) \ +#define FOREACH_MOD(ename, args) \ if (true) \ { \ - std::vector<Module *>::iterator safei; \ - for (std::vector<Module *>::iterator _i = ModuleManager::EventHandlers[y].begin(); _i != ModuleManager::EventHandlers[y].end(); ) \ + static std::vector<Module *> &_modules = ModuleManager::GetEventHandlers(#ename); \ + for (std::vector<Module *>::iterator _i = _modules.begin(); _i != _modules.end();) \ { \ - safei = _i; \ - ++safei; \ try \ { \ - (*_i)->x ; \ + (*_i)->ename args; \ } \ catch (const ModuleException &modexcept) \ { \ Log() << "Exception caught: " << modexcept.GetReason(); \ } \ - _i = safei; \ + catch (const NotImplementedException &) \ + { \ + Log(LOG_DEBUG_2) << "Detaching event " << #ename << " from " << (*_i)->name; \ + _i = _modules.erase(_i); \ + continue; \ + } \ + ++_i; \ } \ } \ else \ static_cast<void>(0) /** - * 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. + * This define is similar to the one above but returns a result. + * The first module to return a result other than EVENT_CONTINUE is the value to be accepted, + * and any modules after are ignored. This is used like: + * + * EventReturn MOD_RESULT; + * FOREACH_RESULT(OnUserConnect, MOD_RESULT, (user, exempt)); */ -#define FOREACH_RESULT(y, x) \ +#define FOREACH_RESULT(ename, ret, args) \ if (true) \ { \ - std::vector<Module *>::iterator safei; \ - MOD_RESULT = EVENT_CONTINUE; \ - for (std::vector<Module *>::iterator _i = ModuleManager::EventHandlers[y].begin(); _i != ModuleManager::EventHandlers[y].end(); ) \ + ret = EVENT_CONTINUE; \ + static std::vector<Module *> &_modules = ModuleManager::GetEventHandlers(#ename); \ + for (std::vector<Module *>::iterator _i = _modules.begin(); _i != _modules.end();) \ { \ - safei = _i; \ - ++safei; \ try \ { \ - EventReturn res = (*_i)->x ; \ - if (res != EVENT_CONTINUE) { \ - MOD_RESULT = res; \ + EventReturn res = (*_i)->ename args; \ + if (res != EVENT_CONTINUE) \ + { \ + ret = res; \ break; \ } \ } \ @@ -106,12 +113,19 @@ if (true) \ { \ Log() << "Exception caught: " << modexcept.GetReason(); \ } \ - _i = safei; \ + catch (const NotImplementedException &) \ + { \ + Log(LOG_DEBUG_2) << "Detaching event " << #ename << " from " << (*_i)->name; \ + _i = _modules.erase(_i); \ + continue; \ + } \ + ++_i; \ } \ } \ else \ static_cast<void>(0) + /** Possible return types from events. */ enum EventReturn @@ -195,6 +209,7 @@ class ModuleVersion int GetPatch() const; }; +class NotImplementedException : public CoreException { }; /** Every module in Anope is actually a class. */ @@ -281,7 +296,7 @@ class CoreExport Module : public Extensible * @param cu The user, channel, and status of the user being kicked * @param kickmsg The reason for the kick. */ - virtual void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) { } + virtual void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) { throw NotImplementedException(); } /** Called when a user has been kicked from a channel. * @param source The kicker @@ -290,13 +305,13 @@ class CoreExport Module : public Extensible * @param status The status the kicked user had on the channel before they were kicked * @param kickmsg The reason for the kick. */ - virtual void OnUserKicked(MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) { } + virtual void OnUserKicked(MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) { throw NotImplementedException(); } /** Called when Services' configuration is being (re)loaded. * @param conf The config that is being built now and will replace the global Config object * @throws A ConfigException to abort the config (re)loading process. */ - virtual void OnReload(Configuration::Conf *conf) { } + virtual void OnReload(Configuration::Conf *conf) { throw NotImplementedException(); } /** Called before a bot is assigned to a channel. * @param sender The user assigning the bot @@ -304,48 +319,48 @@ class CoreExport Module : public Extensible |
