]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - include/event.h
Fix a bunch of really obvious unnecessary includes.
[user/henk/code/inspircd.git] / include / event.h
index 1bcb0a5edaf17066d2f533a36d957ccfe663cdda..baa24d7d08798b9f5c9a370dac3bae2af1f64510 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * InspIRCd -- Internet Relay Chat Daemon
  *
- *   Copyright (C) 2015 Attila Molnar <attilamolnar@hush.com>
+ *   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
  * redistribute it and/or modify it under the terms of the GNU General Public
@@ -19,6 +20,8 @@
 
 #pragma once
 
+#include "base.h"
+
 namespace Events
 {
        class ModuleEventListener;
@@ -36,10 +39,15 @@ class Events::ModuleEventProvider : public ServiceProvider, private dynamic_refe
  public:
        struct Comp
        {
-               bool operator()(ModuleEventListener* one, ModuleEventListener* two) const;
+               bool operator()(ModuleEventListener* lhs, ModuleEventListener* rhs) const;
        };
 
-       typedef insp::flat_multiset<ModuleEventListener*, Comp> 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)
@@ -52,12 +60,31 @@ class Events::ModuleEventProvider : public ServiceProvider, private dynamic_refe
                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
         */
        const SubscriberList& GetSubscribers() const { return prov->subscribers; }
 
-       friend class ModuleEventListener;
+       /** Subscribes a listener to this event.
+        * @param subscriber The listener to subscribe.
+        */
+       void Subscribe(ModuleEventListener* subscriber)
+       {
+               subscribers.insert(subscriber);
+               OnSubscribe(subscriber);
+       }
+
+       /** Unsubscribes a listener from this event.
+        * @param subscriber The listener to unsubscribe.
+        */
+       void Unsubscribe(ModuleEventListener* subscriber)
+       {
+               subscribers.erase(subscriber);
+               OnUnsubscribe(subscriber);
+       }
 
  private:
        void OnCapture() CXX11_OVERRIDE
@@ -67,6 +94,16 @@ class Events::ModuleEventProvider : public ServiceProvider, private dynamic_refe
                        subscribers.clear();
        }
 
+       /** Called when a listener subscribes to this event.
+        * @param subscriber The listener which subscribed.
+        */
+       virtual void OnSubscribe(ModuleEventListener* subscriber) { }
+
+       /** Called when a listener unsubscribes from this event.
+        * @param subscriber The listener which unsubscribed.
+        */
+       virtual void OnUnsubscribe(ModuleEventListener* subscriber) { }
+
        /** Reference to the active provider for this event. In case multiple event providers
         * exist for the same event, only one of them contains the list of subscribers.
         * To handle the case when we are not the ones with the list, we get it from the provider
@@ -95,7 +132,7 @@ class Events::ModuleEventListener : private dynamic_reference_base::CaptureHook
         */
        void OnCapture() CXX11_OVERRIDE
        {
-               prov->subscribers.insert(this);
+               prov->Subscribe(this);
        }
 
  public:
@@ -119,15 +156,28 @@ class Events::ModuleEventListener : private dynamic_reference_base::CaptureHook
        ~ModuleEventListener()
        {
                if (prov)
-                       prov->subscribers.erase(this);
+                       prov->Unsubscribe(this);
        }
 
-       friend struct ModuleEventProvider::Comp;
+       /** Retrieves the module which created this listener. */
+       const Module* GetModule() const { return prov.creator; }
+
+       /** 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);
 }
 
 /**
@@ -136,11 +186,16 @@ inline bool Events::ModuleEventProvider::Comp::operator()(Events::ModuleEventLis
  * 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); \
-               _t->func params ; \
+               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);
 
@@ -153,12 +208,18 @@ inline bool Events::ModuleEventProvider::Comp::operator()(Events::ModuleEventLis
  */
 #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); \
-               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);