Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
CallbackEventHandler.hxx
Go to the documentation of this file.
1
36#ifndef _OPENLCB_CALLBACKEVENTHANDLER_HXX_
37#define _OPENLCB_CALLBACKEVENTHANDLER_HXX_
38
39#include <functional>
40
42
43namespace openlcb
44{
45
55{
56public:
65 typedef std::function<void(const EventRegistryEntry &registry_entry,
70 typedef std::function<EventState(const EventRegistryEntry &registry_entry,
84 typedef std::function<void(openlcb::Defs::MTI mti,
85 const EventRegistryEntry &registry_entry, EventReport *report,
86 BarrierNotifiable *done)>
88
90 {
93 IS_PRODUCER = (1U << 31),
96 IS_CONSUMER = (1U << 30),
100 };
101
114 EventStateHandlerFn state_handler = nullptr,
115 EventIdentifiedHandlerFn identified_handler = nullptr)
116 : reportHandler_(std::move(report_handler))
117 , stateHandler_(std::move(state_handler))
118 , identifiedHandler_(std::move(identified_handler))
119 , node_(node)
120 {
121 }
122
124 {
126 }
127
139 void add_entry(EventId event, uint32_t entry_bits)
140 {
141 EventRegistry::instance()->register_handler(
142 EventRegistryEntry(this, event, entry_bits), 0);
143 }
144
147 {
148 EventRegistry::instance()->unregister_handler(this);
149 }
150
154 void remove_entry(uint32_t entry_bits)
155 {
156 EventRegistry::instance()->unregister_handler(
157 this, entry_bits, 0xFFFFFFFFu);
158 }
159
162 {
163 return node_;
164 }
165
167 EventReport *event, BarrierNotifiable *done) override
168 {
169 if (reportHandler_)
170 {
171 reportHandler_(entry, event, done);
172 }
173 done->notify();
174 }
175
177 EventReport *event, BarrierNotifiable *done) override
178 {
179 if (registry_entry.user_arg & IS_CONSUMER)
180 {
181 send_consumer_identified(registry_entry, event, done);
182 }
183 done->notify();
184 };
185
187 EventReport *event, BarrierNotifiable *done) override
188 {
189 if (registry_entry.user_arg & IS_PRODUCER)
190 {
191 send_producer_identified(registry_entry, event, done);
192 }
193 done->notify();
194 };
195
196 void handle_identify_global(const EventRegistryEntry &registry_entry,
197 EventReport *event, BarrierNotifiable *done) override
198 {
199 if (registry_entry.user_arg & IS_PRODUCER)
200 {
201 send_producer_identified(registry_entry, event, done);
202 }
203 if (registry_entry.user_arg & IS_CONSUMER)
204 {
205 send_consumer_identified(registry_entry, event, done);
206 }
207 done->notify();
208 };
209
211 EventReport *event, BarrierNotifiable *done) override
212 {
214 {
217 }
218 done->notify();
219 }
220
222 EventReport *event, BarrierNotifiable *done) override
223 {
225 {
228 }
229 done->notify();
230 }
231
232protected:
235 EventReport *event, BarrierNotifiable *done)
236 {
237 EventState state =
238 stateHandler_ ? stateHandler_(entry, event) : EventState::UNKNOWN;
240 event->event_write_helper<1>()->WriteAsync(node_, mti,
241 WriteHelper::global(), eventid_to_buffer(entry.event),
242 done->new_child());
243 }
244
247 EventReport *event, BarrierNotifiable *done)
248 {
249 EventState state =
250 stateHandler_ ? stateHandler_(entry, event) : EventState::UNKNOWN;
252 event->event_write_helper<3>()->WriteAsync(node_, mti,
253 WriteHelper::global(), eventid_to_buffer(entry.event),
254 done->new_child());
255 }
256
257private:
267};
268
269} // namespace openlcb
270
271#endif // _OPENLCB_CALLBACKEVENTHANDLER_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.
BarrierNotifiable * new_child()
Call this for each child task.
static EventRegistry * instance()
Definition Singleton.hxx:77
Event handler implementation class that calls a user-specified std::function callback every time an e...
std::function< EventState(const EventRegistryEntry &registry_entry, EventReport *report)> EventStateHandlerFn
Function signature that returns the event state for the current registry entry.
void handle_consumer_identified(const EventRegistryEntry &entry, EventReport *event, BarrierNotifiable *done) override
Called on another node sending ConsumerIdentified for this event.
std::function< void(const EventRegistryEntry &registry_entry, EventReport *report, BarrierNotifiable *done)> EventReportHandlerFn
This function (signature) is called every time a given event report arrives.
Node * node_
Node on which we are registered.
EventIdentifiedHandlerFn identifiedHandler_
Stores the user callback for P/C identified messages.
void send_consumer_identified(const EventRegistryEntry &entry, EventReport *event, BarrierNotifiable *done)
Helper function for implementations.
void remove_entry(uint32_t entry_bits)
Removes the registration of entries added before with a given user_arg value.
void handle_event_report(const EventRegistryEntry &entry, EventReport *event, BarrierNotifiable *done) override
Called on incoming EventReport messages.
void handle_producer_identified(const EventRegistryEntry &entry, EventReport *event, BarrierNotifiable *done) override
Called on another node sending ProducerIdentified for this event.
void add_entry(EventId event, uint32_t entry_bits)
Registers this event handler for a given event ID in the global event service's registry.
EventStateHandlerFn stateHandler_
Stores the user callback for getting state for event identified responses.
void remove_all_entries()
Removes the registration of every single entry added so far.
void handle_identify_global(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done) override
Called on the need of sending out identification messages.
@ IS_CONSUMER
Set this bit in the param entry_bits in order to mark the event as being consumed.
@ IS_PRODUCER
Set this bit in the param entry_bits in order to mark the event as being produced.
@ USER_BIT_MASK
This is the mask of bits that can be used by the caller for storing arbitrary information next to the...
void handle_identify_consumer(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done) override
Called on another node sending IdentifyConsumer.
std::function< void(openlcb::Defs::MTI mti, const EventRegistryEntry &registry_entry, EventReport *report, BarrierNotifiable *done)> EventIdentifiedHandlerFn
This function (signature) is called when a producer/consumer identified message arrives.
void send_producer_identified(const EventRegistryEntry &entry, EventReport *event, BarrierNotifiable *done)
Helper function for implementations.
void handle_identify_producer(const EventRegistryEntry &registry_entry, EventReport *event, BarrierNotifiable *done) override
Called on another node sending IdentifyProducer.
EventReportHandlerFn reportHandler_
Stores the user callback for event reports.
CallbackEventHandler(Node *node, EventReportHandlerFn report_handler, EventStateHandlerFn state_handler=nullptr, EventIdentifiedHandlerFn identified_handler=nullptr)
Constructor.
Structure used in registering event handlers.
uint32_t user_arg
Opaque user argument.
EventId event
Stores the event ID or beginning of range for which to register the given handler.
Base class for NMRAnet nodes conforming to the asynchronous interface.
Definition Node.hxx:52
SimpleEventHandler ignores all non-essential callbacks.
EventState
Allowed states of producers and consumers.
Payload eventid_to_buffer(uint64_t eventid)
Converts an Event ID to a Payload suitable to be sent as an event report.
Definition If.cxx:72
MTI
Known Message type indicators.
@ MTI_CONSUMER_IDENTIFIED_UNKNOWN
consumer broadcast, validity unknown
@ MTI_PRODUCER_IDENTIFIED_VALID
producer broadcast, valid state
@ MTI_PRODUCER_IDENTIFIED_UNKNOWN
producer broadcast, validity unknown
@ MTI_CONSUMER_IDENTIFIED_VALID
consumer broadcast, valid state
Shared notification structure that is assembled for each incoming event-related message,...