InspIRCd  3.0
event.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2015 Attila Molnar <[email protected]>
5  *
6  * This file is part of InspIRCd. InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 
20 #pragma once
21 
22 namespace Events
23 {
24  class ModuleEventListener;
25  class ModuleEventProvider;
26 }
27 
35 {
36  public:
37  struct Comp
38  {
39  bool operator()(ModuleEventListener* one, ModuleEventListener* two) const;
40  };
41 
43 
48  ModuleEventProvider(Module* mod, const std::string& eventid)
49  : ServiceProvider(mod, eventid, SERVICE_DATA)
50  , prov(mod, eventid)
51  {
52  prov.SetCaptureHook(this);
53  }
54 
58  const SubscriberList& GetSubscribers() const { return prov->subscribers; }
59 
63  void Subscribe(ModuleEventListener* subscriber)
64  {
65  subscribers.insert(subscriber);
66  OnSubscribe(subscriber);
67  }
68 
72  void Unsubscribe(ModuleEventListener* subscriber)
73  {
74  subscribers.erase(subscriber);
75  OnUnsubscribe(subscriber);
76  }
77 
78  private:
79  void OnCapture() CXX11_OVERRIDE
80  {
81  // If someone else holds the list from now on, clear mine. See below for more info.
82  if (*prov != this)
83  subscribers.clear();
84  }
85 
89  virtual void OnSubscribe(ModuleEventListener* subscriber) { }
90 
94  virtual void OnUnsubscribe(ModuleEventListener* subscriber) { }
95 
102 
106  SubscriberList subscribers;
107 };
108 
113 {
117 
118  const unsigned int eventpriority;
119 
122  void OnCapture() CXX11_OVERRIDE
123  {
124  prov->Subscribe(this);
125  }
126 
127  public:
128  static const unsigned int DefaultPriority = 100;
129 
135  ModuleEventListener(Module* mod, const std::string& eventid, unsigned int eventprio = DefaultPriority)
136  : prov(mod, eventid)
137  , eventpriority(eventprio)
138  {
139  prov.SetCaptureHook(this);
140  // If the dynamic_reference resolved at construction our capture handler wasn't called
141  if (prov)
142  ModuleEventListener::OnCapture();
143  }
144 
146  {
147  if (prov)
148  prov->Unsubscribe(this);
149  }
150 
152  const Module* GetModule() const { return prov.creator; }
153 
154  friend struct ModuleEventProvider::Comp;
155 };
156 
157 inline bool Events::ModuleEventProvider::Comp::operator()(Events::ModuleEventListener* one, Events::ModuleEventListener* two) const
158 {
159  return (one->eventpriority < two->eventpriority);
160 }
161 
167 #define FOREACH_MOD_CUSTOM(prov, listenerclass, func, params) do { \
168  const ::Events::ModuleEventProvider::SubscriberList& _handlers = (prov).GetSubscribers(); \
169  for (::Events::ModuleEventProvider::SubscriberList::const_iterator _i = _handlers.begin(); _i != _handlers.end(); ++_i) \
170  { \
171  listenerclass* _t = static_cast<listenerclass*>(*_i); \
172  const Module* _m = _t->GetModule(); \
173  if (_m && !_m->dying) \
174  _t->func params ; \
175  } \
176 } while (0);
177 
185 #define FIRST_MOD_RESULT_CUSTOM(prov, listenerclass, func, result, params) do { \
186  result = MOD_RES_PASSTHRU; \
187  const ::Events::ModuleEventProvider::SubscriberList& _handlers = (prov).GetSubscribers(); \
188  for (::Events::ModuleEventProvider::SubscriberList::const_iterator _i = _handlers.begin(); _i != _handlers.end(); ++_i) \
189  { \
190  listenerclass* _t = static_cast<listenerclass*>(*_i); \
191  const Module* _m = _t->GetModule(); \
192  if (!_m || _m->dying) \
193  continue; \
194  result = _t->func params ; \
195  if (result != MOD_RES_PASSTHRU) \
196  break; \
197  } \
198 } while (0);
dynamic_reference_base::SetCaptureHook
void SetCaptureHook(CaptureHook *h)
Definition: dynref.h:52
ServiceProvider
Definition: base.h:244
Events::ModuleEventListener::ModuleEventListener
ModuleEventListener(Module *mod, const std::string &eventid, unsigned int eventprio=DefaultPriority)
Definition: event.h:135
dynamic_reference_nocheck
Definition: dynref.h:95
Events::ModuleEventProvider::Unsubscribe
void Unsubscribe(ModuleEventListener *subscriber)
Definition: event.h:72
dynamic_reference_base::CaptureHook
Definition: dynref.h:28
Events::ModuleEventProvider::Comp
Definition: event.h:37
insp::flat_multiset
Definition: flat_map.h:244
Events::ModuleEventProvider
Definition: event.h:34
Events::ModuleEventListener
Definition: event.h:112
Module
Definition: modules.h:242
Events::ModuleEventProvider::GetSubscribers
const SubscriberList & GetSubscribers() const
Definition: event.h:58
Events::ModuleEventListener::GetModule
const Module * GetModule() const
Definition: event.h:152
Events::ModuleEventProvider::Subscribe
void Subscribe(ModuleEventListener *subscriber)
Definition: event.h:63
Events::ModuleEventProvider::ModuleEventProvider
ModuleEventProvider(Module *mod, const std::string &eventid)
Definition: event.h:48