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 
60  friend class ModuleEventListener;
61 
62  private:
63  void OnCapture() CXX11_OVERRIDE
64  {
65  // If someone else holds the list from now on, clear mine. See below for more info.
66  if (*prov != this)
67  subscribers.clear();
68  }
69 
76 
80  SubscriberList subscribers;
81 };
82 
87 {
91 
92  const unsigned int eventpriority;
93 
96  void OnCapture() CXX11_OVERRIDE
97  {
98  prov->subscribers.insert(this);
99  }
100 
101  public:
102  static const unsigned int DefaultPriority = 100;
103 
109  ModuleEventListener(Module* mod, const std::string& eventid, unsigned int eventprio = DefaultPriority)
110  : prov(mod, eventid)
111  , eventpriority(eventprio)
112  {
113  prov.SetCaptureHook(this);
114  // If the dynamic_reference resolved at construction our capture handler wasn't called
115  if (prov)
116  ModuleEventListener::OnCapture();
117  }
118 
120  {
121  if (prov)
122  prov->subscribers.erase(this);
123  }
124 
125  friend struct ModuleEventProvider::Comp;
126 };
127 
128 inline bool Events::ModuleEventProvider::Comp::operator()(Events::ModuleEventListener* one, Events::ModuleEventListener* two) const
129 {
130  return (one->eventpriority < two->eventpriority);
131 }
132 
138 #define FOREACH_MOD_CUSTOM(prov, listenerclass, func, params) do { \
139  const ::Events::ModuleEventProvider::SubscriberList& _handlers = (prov).GetSubscribers(); \
140  for (::Events::ModuleEventProvider::SubscriberList::const_iterator _i = _handlers.begin(); _i != _handlers.end(); ++_i) \
141  { \
142  listenerclass* _t = static_cast<listenerclass*>(*_i); \
143  _t->func params ; \
144  } \
145 } while (0);
146 
154 #define FIRST_MOD_RESULT_CUSTOM(prov, listenerclass, func, result, params) do { \
155  result = MOD_RES_PASSTHRU; \
156  const ::Events::ModuleEventProvider::SubscriberList& _handlers = (prov).GetSubscribers(); \
157  for (::Events::ModuleEventProvider::SubscriberList::const_iterator _i = _handlers.begin(); _i != _handlers.end(); ++_i) \
158  { \
159  listenerclass* _t = static_cast<listenerclass*>(*_i); \
160  result = _t->func params ; \
161  if (result != MOD_RES_PASSTHRU) \
162  break; \
163  } \
164 } while (0);
ModuleEventProvider(Module *mod, const std::string &eventid)
Definition: event.h:48
Definition: dynref.h:95
Definition: modules.h:240
Definition: event.h:37
Definition: event.h:22
ModuleEventListener(Module *mod, const std::string &eventid, unsigned int eventprio=DefaultPriority)
Definition: event.h:109
const SubscriberList & GetSubscribers() const
Definition: event.h:58
Definition: base.h:244
void SetCaptureHook(CaptureHook *h)
Definition: dynref.h:52
Definition: event.h:34
Definition: event.h:86