Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
EventHandler.hxx
Go to the documentation of this file.
1
34#ifndef _OPENLCB_EVENTHANDLER_HXX_
35#define _OPENLCB_EVENTHANDLER_HXX_
36
37#include <stdint.h>
38
40#include "utils/AsyncMutex.hxx"
41#include "utils/macros.h"
42#include "utils/Singleton.hxx"
44
45namespace openlcb
46{
47
48typedef uint64_t EventId;
49class Node;
50class EventHandler;
51
52/*enum EventMask {
53 EVENT_EXACT_MASK = 1,
54 EVENT_ALL_MASK = 0xffffffffffffffffULL
55 };*/
56
57enum TestingEnum
58{
59 FOR_TESTING
60};
61
65{
67 EventId event;
72 EventId mask;
84
88 template <int N> WriteHelper *event_write_helper()
89 {
90 static_assert(1 <= N && N <= 4, "WriteHelper out of range.");
91 return write_helpers + (N - 1);
92 }
93
95 EventReport(TestingEnum)
96 {
97 }
98
99private:
105 friend class EventIteratorFlow;
106 friend class DecoderRangeTest;
107
110};
111
114{
115public:
118 EventId event;
123 uint32_t user_arg;
124 EventRegistryEntry(EventHandler *_handler, EventId _event)
125 : event(_event)
126 , handler(_handler)
127 , user_arg(0)
128 {
129 }
130 EventRegistryEntry(EventHandler *_handler, EventId _event,
131 unsigned _user_arg)
132 : event(_event)
133 , handler(_handler)
134 , user_arg(_user_arg)
135 {
136 }
137};
138
143{
144public:
147 using EventId = openlcb::EventId;
148
149 virtual ~EventHandler()
150 {
151 }
152
158 virtual void handle_event_report(const EventRegistryEntry &registry_entry,
159 EventReport *event,
160 BarrierNotifiable *done) = 0;
161
167 virtual void
169 EventReport *event, BarrierNotifiable *done)
170 {
171 done->notify();
172 };
173
179 virtual void
181 EventReport *event, BarrierNotifiable *done)
182 {
183 done->notify();
184 }
185
192 virtual void
194 EventReport *event, BarrierNotifiable *done)
195 {
196 done->notify();
197 }
198
205 virtual void
207 EventReport *event, BarrierNotifiable *done)
208 {
209 done->notify();
210 }
211
218 virtual void handle_identify_global(const EventRegistryEntry &registry_entry,
219 EventReport *event,
220 BarrierNotifiable *done) = 0;
221
227 virtual void
229 EventReport *event, BarrierNotifiable *done) = 0;
230
236 virtual void
238 EventReport *event, BarrierNotifiable *done) = 0;
239};
240
241typedef void (EventHandler::*EventHandlerFunction)(
242 const EventRegistryEntry &registry_entry, EventReport *event,
243 BarrierNotifiable *done);
244
245class EventIterator;
246
253class EventRegistry : public Singleton<EventRegistry>
254{
255public:
256 virtual ~EventRegistry();
257
265 static unsigned align_mask(EventId *event, unsigned size);
266
272 virtual void register_handler(const EventRegistryEntry &entry,
273 unsigned mask) = 0;
278 virtual void unregister_handler(EventHandler *handler,
279 uint32_t user_arg = 0, uint32_t user_arg_mask = 0) = 0;
280
283 virtual void reserve(size_t count)
284 {
285 }
286
289
293 unsigned get_epoch()
294 {
295 return dirtyCounter_;
296 }
297
298protected:
300
304 {
306 }
307
308private:
309 static EventRegistry *instance_;
310
313 unsigned dirtyCounter_ = 0;
314
316};
317
318}; /* namespace openlcb */
319
320#endif // _OPENLCB_EVENTHANDLER_HXX_
A BarrierNotifiable allows to create a number of child Notifiable and wait for all of them to finish.
void notify() override
Implementation of the barrier semantics.
Node information.
Definition Devtab.hxx:549
Singleton class.
Definition Singleton.hxx:65
Abstract base class for all event handlers.
virtual void handle_identify_global(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done)=0
Called on the need of sending out identification messages.
virtual void handle_consumer_range_identified(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done)
Called on another node sending ConsumerRangeIdentified.
virtual void handle_producer_range_identified(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done)
Called on another node sending ProducerRangeIdentified for this event.
virtual void handle_event_report(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done)=0
Called on incoming EventReport messages.
virtual void handle_identify_consumer(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done)=0
Called on another node sending IdentifyConsumer.
virtual void handle_producer_identified(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done)
Called on another node sending ProducerIdentified for this event.
virtual void handle_consumer_identified(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done)
Called on another node sending ConsumerIdentified for this event.
virtual void handle_identify_producer(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done)=0
Called on another node sending IdentifyProducer.
Flow to receive incoming messages of event protocol, and dispatch them to the registered event handle...
Abstract class for representing iteration through a container for event handlers.
Structure used in registering event handlers.
EventHandler * handler
Pointer to the handler.
uint32_t user_arg
Opaque user argument.
EventId event
Stores the event ID or beginning of range for which to register the given handler.
Global static object for registering event handlers.
static unsigned align_mask(EventId *event, unsigned size)
Computes the alignment mask for registering an event range.
virtual void register_handler(const EventRegistryEntry &entry, unsigned mask)=0
Adds a new event handler to the registry.
unsigned dirtyCounter_
This counter will be incremented every time the set of event handlers change (and thus the event iter...
virtual void unregister_handler(EventHandler *handler, uint32_t user_arg=0, uint32_t user_arg_mask=0)=0
Removes all registered instances of a given event handler pointer.
unsigned get_epoch()
Returns a monotonically increasing number that will change every time the set of registered event han...
void set_dirty()
Implementations must call this function from register and unregister handler to mark iterators being ...
virtual void reserve(size_t count)
Prepares storage for adding many event handlers.
virtual EventIterator * create_iterator()=0
Creates a new event iterator. Caller takes ownership of object.
Base class for NMRAnet nodes conforming to the asynchronous interface.
Definition Node.hxx:52
A statically allocated buffer for sending one message to the OpenLCB bus.
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Removes default copy-constructor and assignment added by C++.
Definition macros.h:171
EventState
Allowed states of producers and consumers.
Shared notification structure that is assembled for each incoming event-related message,...
EventId mask
Specifies the mask in case the request is for an event range.
WriteHelper write_helpers[4]
Static objects usable by all event handler implementations.
EventState state
For producer/consumer identified messages, specifies the state of the producer/consumer as the sender...
EventReport()
Constrained access to the constructors.
NodeHandle src_node
Information about the sender of the incoming event-related OpenLCB message.
EventId event
The event ID from the incoming message.
Node * dst_node
nullptr for global messages; points to the specific virtual node for addressed events identify messag...
EventReport(TestingEnum)
Public constructor for use in tests only.
WriteHelper * event_write_helper()
These allow event handlers to produce up to four messages per invocation.
Container of both a NodeID and NodeAlias.