/*
* InspIRCd -- Internet Relay Chat Daemon
*
- * Copyright (C) 2018-2019 Sadie Powell <sadie@witchery.services>
+ * Copyright (C) 2018-2020 Sadie Powell <sadie@witchery.services>
* Copyright (C) 2015, 2018 Attila Molnar <attilamolnar@hush.com>
*
* This file is part of InspIRCd. InspIRCd is free software: you can
#pragma once
+#include "base.h"
+
namespace Events
{
class ModuleEventListener;
public:
struct Comp
{
- bool operator()(ModuleEventListener* one, ModuleEventListener* two) const;
+ bool operator()(ModuleEventListener* lhs, ModuleEventListener* rhs) const;
};
- typedef insp::flat_multiset<ModuleEventListener*, Comp, std::less<ModuleEventListener*> > SubscriberList;
+ struct ElementComp
+ {
+ bool operator()(ModuleEventListener* lhs, ModuleEventListener* rhs) const;
+ };
+
+ typedef insp::flat_multiset<ModuleEventListener*, Comp, ElementComp> SubscriberList;
/** Constructor
* @param mod Module providing the event(s)
prov.SetCaptureHook(this);
}
+ /** Retrieves the module which created this listener. */
+ const Module* GetModule() const { return prov.creator; }
+
/** Get list of objects subscribed to this event
* @return List of subscribed objects
*/
/** Retrieves the module which created this listener. */
const Module* GetModule() const { return prov.creator; }
- friend struct ModuleEventProvider::Comp;
+ /** Retrieves the priority of this event. */
+ unsigned int GetPriority() const { return eventpriority; }
};
-inline bool Events::ModuleEventProvider::Comp::operator()(Events::ModuleEventListener* one, Events::ModuleEventListener* two) const
+inline bool Events::ModuleEventProvider::Comp::operator()(Events::ModuleEventListener* lhs, Events::ModuleEventListener* rhs) const
+{
+ return (lhs->GetPriority() < rhs->GetPriority());
+}
+
+inline bool Events::ModuleEventProvider::ElementComp::operator()(Events::ModuleEventListener* lhs, Events::ModuleEventListener* rhs) const
{
- return (one->eventpriority < two->eventpriority);
+ if (lhs->GetPriority() < rhs->GetPriority())
+ return true;
+ if (lhs->GetPriority() > rhs->GetPriority())
+ return false;
+ return std::less<ModuleEventListener*>()(lhs, rhs);
}
/**
* FOREACH_MOD_CUSTOM(accountevprov, AccountEventListener, OnAccountChange, MOD_RESULT, (user, newaccount))
*/
#define FOREACH_MOD_CUSTOM(prov, listenerclass, func, params) do { \
- const ::Events::ModuleEventProvider::SubscriberList& _handlers = (prov).GetSubscribers(); \
- for (::Events::ModuleEventProvider::SubscriberList::const_iterator _i = _handlers.begin(); _i != _handlers.end(); ++_i) \
+ if (!(prov).GetModule() || !(prov).GetModule()->dying) \
{ \
- listenerclass* _t = static_cast<listenerclass*>(*_i); \
- const Module* _m = _t->GetModule(); \
- if (_m && !_m->dying) \
+ const ::Events::ModuleEventProvider::SubscriberList& _handlers = (prov).GetSubscribers(); \
+ for (::Events::ModuleEventProvider::SubscriberList::const_iterator _i = _handlers.begin(); _i != _handlers.end(); ++_i) \
+ { \
+ listenerclass* _t = static_cast<listenerclass*>(*_i); \
+ const Module* _m = _t->GetModule(); \
+ if (_m && !_m->dying) \
_t->func params ; \
+ } \
} \
} while (0);
*/
#define FIRST_MOD_RESULT_CUSTOM(prov, listenerclass, func, result, params) do { \
result = MOD_RES_PASSTHRU; \
- const ::Events::ModuleEventProvider::SubscriberList& _handlers = (prov).GetSubscribers(); \
- for (::Events::ModuleEventProvider::SubscriberList::const_iterator _i = _handlers.begin(); _i != _handlers.end(); ++_i) \
+ if (!(prov).GetModule() || !(prov).GetModule()->dying) \
{ \
- listenerclass* _t = static_cast<listenerclass*>(*_i); \
- const Module* _m = _t->GetModule(); \
- if (!_m || _m->dying) \
- continue; \
- result = _t->func params ; \
- if (result != MOD_RES_PASSTHRU) \
- break; \
+ const ::Events::ModuleEventProvider::SubscriberList& _handlers = (prov).GetSubscribers(); \
+ for (::Events::ModuleEventProvider::SubscriberList::const_iterator _i = _handlers.begin(); _i != _handlers.end(); ++_i) \
+ { \
+ listenerclass* _t = static_cast<listenerclass*>(*_i); \
+ const Module* _m = _t->GetModule(); \
+ if (!_m || _m->dying) \
+ continue; \
+ result = _t->func params ; \
+ if (result != MOD_RES_PASSTHRU) \
+ break; \
+ } \
} \
} while (0);