EventRouter Class Reference#include <EventRouter.h>
Inheritance diagram for EventRouter:
[legend]List of all members.
Detailed Description
This class will handle distribution of events as well as management of timers.
Classes must inherit from EventListener and/or EventTrapper in order to receive events.
Use the global erouter instance of EventRouter to both send (post) and receive (subscribe/listen) to events. (except if you are posting from within a MotionCommand, in which case you should use MotionCommand::postEvent() so that it can correctly handle inter-process communication issues under Aperios (the Aibo's OS) -- under a Unix-based OS, this wouldn't be necessary.)
The events available for processing are listed in EventBase::EventGeneratorID_t. Each generator ID's documentation specifies how to interpret the source ID field, and whether you can expect events with that generator ID to be of a subclass of EventBase, such as TextMsgEvent or LocomotionEvent. Many generators send plain EventBase instances.
When multiple listeners are subscribed, the order in which an event is distributed among them is:
- "Specific" listeners: any listener which specifies a particular source id. (doesn't matter if they specified type id as well)
- older listeners get events before more recently added listeners ("FIFO")
- "General" listeners: those that subscribe to an entire generator
- older listeners get events before more recently added listeners ("FIFO")
...but if you're relying on that ordering, there probably should be a cleaner way to do whatever you're doing.
TimerEvents are generally only sent to the generator which requested them. So if EventListener A requests a timer (see addTimer()) with ID 0 at two second intervals, and B requests a timer with ID 0 at three second intervals, each will still only receive the timers they requested - no cross talk. The timer generator is unique in this regard, which is why it is built in as an integral component of the EventRouter. However, EventListener A can receive B's timers if it specifically wants to, via addListener(). See "Timers" below.
If an EventListener/EventTrapper subscribes to the same event source multiple times, it will receive multiple copies of the event. However, the first call to removeListener for a source will remove all subscriptions to that source.
Example: EventListener A subscribes to (buttonEGID,*,*), and twice to (buttonEGID,0,*).
- If button 0 is pressed, A will get three copies of the event.
- If button 1 is pressed, A will get one copy.
- If removeListener(&A,buttonEGID) is called, the (buttonEGID,*,*) is removed, as well as both of (buttonEGID,0,*).
- If removeListener(&A,buttonEGID,0) is called, both of (buttonEGID,0,*) are removed, but (buttonEGID,*,*) would be untouched.
Timers
addTimer() allows you to request an TimerEvent to be sent at some later point in time, possibly on a repeating basis. Timers are specific to the behavior which requests them, and you do not (and usually should not) call addListener() in order to receive a timer event.
There is an important different between addTimer() and addListener(timerEGID,...)! addTimer will "create" the timer, and will send the timer to the listener which created it when the timer expires. This means that as long as the listener in question does not call addListener(timerEGID), it will only receive its own timers. In other words, with this usage there is no confusion with timer cross-talk between listeners, because each listener is only receiving its own timers.
However, if a listener calls addListener(timerEGID), it will begin receiving all timer events from throughout the system. This allows you to have one behavior "eavesdrop" on another's timers. In order to determine which listener requested/created the timer, you can use the TimerEvent::getTarget() value.
So beware that if you call both addTimer() and addListener(foo,timerEGID), 'foo' will get two calls to processEvent() for its own timers, and one call for all other timers, and will have to know to call TimerEvent::getTarget() to distinguish its timers from other listener's timers (if it cares about the difference...)
Timers are sent to the requesting listener before being broadcast -- EventTrappers cannot filter a listener's own timers, but can prevent the timer from being broadcast to other listeners.
Event processing examples:
Posting events: //method A: basic event posting (EventBase instance is sent) erouter->postEvent(EventBase::aiEGID, 1234, EventBase::statusETID);
//method B: specific event instance is posted (have to use this style to post a subclass) TextMsgEvent txt("hello world"); erouter->postEvent(txt); // or can be done in one line: erouter->postEvent(TextMsgEvent("hello world"))
Receiving events:
class YourListener : public EventListener {
public:
virtual void processEvent(const EventBase& e) {
std::cout << "Got: " << e.getName() << std::endl;
}
}; erouter->addRemoteListener(this,
remoteDog,
EventBase::buttonEGID,
RobotInfo::FrontBackButOffset,
EventBase::activateETID);
erouter->addRemoteListener(this,
remoteDog,
EventBase::buttonEGID,
RobotInfo::MiddleBackButOffset,
EventBase::activateETID);
erouter->addRemoteListener(this,
remoteDog,
EventBase::buttonEGID,
RobotInfo::RearBackButOffset,
EventBase::activateETID);
YourListener yourList;
erouter->addListener(&yourList, EventBase::aiEGID);
erouter->addListener(&yourList, EventBase::buttonEGID, ERS7Info::HeadButOffset);
Typically in a BehaviorBase subclass, you would just specify 'this' instead of '&yourList'.
Timer processing examples:
Requesting/Creating timers: Again, typically in a BehaviorBase subclass, you would just specify 'this' instead of '&yourList'.
- See also:
- EventBase::EventGeneratorID_t for a complete listing of all generators, as well as instructions on how to add new generators.
Tutorials:
Definition at line 179 of file EventRouter.h.
|
Listener Management |
|
void | addListener (EventListener *el, EventBase::EventGeneratorID_t egid) |
| | Adds a listener for all events from a given event generator.
|
|
void | addListener (EventListener *el, EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | Adds a listener for all types from a specific source and generator.
|
|
void | addListener (EventListener *el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) |
| | Adds a listener for a specific source id and type from a given event generator.
|
|
void | addListener (EventListener *el, const EventBase &e) |
| | Uses the generator, source, and type fields of e to add a listener for that specific tuple.
|
|
void | addRemoteListener (EventListener *el, int host, EventBase::EventGeneratorID_t egid) |
| | Adds a listener for all events from a given event generator.
|
|
void | addRemoteListener (EventListener *el, int host, EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | Adds a listener for all events from a given event generator.
|
|
void | addRemoteListener (EventListener *el, int host, const EventBase &e) |
| | Adds a listener for all events from a given event generator.
|
|
void | addRemoteListener (EventListener *el, int host, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) |
| | Adds a listener for all events from a given event generator.
|
|
void | removeRemoteListener (EventListener *el, int host, EventBase::EventGeneratorID_t egid) |
| | Adds a listener for all events from a given event generator.
|
|
void | removeRemoteListener (EventListener *el, int host, EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | Adds a listener for all events from a given event generator.
|
|
void | removeRemoteListener (EventListener *el, int host, const EventBase &e) |
| | Adds a listener for all events from a given event generator.
|
|
void | removeRemoteListener (EventListener *el, int host, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) |
| | Adds a listener for all events from a given event generator.
|
|
RemoteRouter & | remoteRouterForHost (int host) |
| | Adds a listener for all events from a given event generator.
|
|
void | requestRemoteStateUpdates (int host, RemoteState::StateType type, unsigned int interval=500) |
| | Adds a listener for all events from a given event generator.
|
|
void | stopRemoteStateUpdates (int host, RemoteState::StateType type) |
| | Adds a listener for all events from a given event generator.
|
|
bool | serveRemoteEventRequests () |
| | Adds a listener for all events from a given event generator.
|
|
int | processData (char *data, int bytes) |
| | Adds a listener for all events from a given event generator.
|
|
void | removeListener (EventListener *el) |
| | stops sending ALL events to the listener -- does not remove pending timers however (may need to call removeTimer(el) as well); see remove()
|
|
void | removeListener (EventListener *el, EventBase::EventGeneratorID_t egid) |
| | stops sending specified events from the generator to the listener.
|
|
void | removeListener (EventListener *el, EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | stops sending specified events from the generator to the listener.
|
|
void | removeListener (EventListener *el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) |
| | stops sending specified events from the generator to the listener.
|
|
void | removeListener (EventListener *el, const EventBase &e) |
| | Uses the generator, source, and type fields of e to remove a listener for that specific tuple.
|
|
void | remove (EventListener *el) |
| | stops all events and timers, shorthand for removeListener(el) and removeTimer(el); Note that trappers are separate, removeTrapper() is not called
|
|
static std::string | intToStringIP (int ip) |
| | Adds a listener for all events from a given event generator.
|
|
static int | stringToIntIP (std::string ip) |
| | Adds a listener for all events from a given event generator.
|
|
static const int | defaultPort = 2424 |
| | Adds a listener for all events from a given event generator.
|
|
std::list< EventProxy * > | proxies |
| | Adds a listener for all events from a given event generator.
|
|
std::map< int, RemoteRouter * > | rrouters |
| | Adds a listener for all events from a given event generator.
|
|
Socket * | sck |
| | Adds a listener for all events from a given event generator.
|
|
int | nextProxyPort |
| | Adds a listener for all events from a given event generator.
|
Public Member Functions |
|
| EventRouter () |
| | Constructs the router.
|
|
virtual | ~EventRouter () |
| | just calls reset and removeAllTimers()
|
|
void | reset () |
| | erases all listeners, trappers and timers, resets EventRouter
|
|
|
void | postEvent (EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid, unsigned int dur=0) |
| | recommended to create and post an event using current buffer setting
|
|
void | postEvent (EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid, unsigned int dur, const std::string &n, float m) |
| | recommended to create and post an event using current buffer setting
|
| void | postEvent (EventBase *e) ATTR_deprecated |
| | deprecated -- pass by reference instead; this version posts the specified event and then deletes it after processing is complete
|
|
void | postEvent (const EventBase &e) |
| | posts the specified event, but doesn't delete it at the end -- equivalent to processEvent(e)
|
| void | processTimers () |
| | determines if timers need to be posted, and posts them if so.
|
| void | processEvent (const EventBase &e) |
| | sends event to its trappers & listeners, but doesn't delete the event at the end (see also postEvent())
|
|
EventTranslator * | getForwardingAgent (ProcessID::ProcessID_t proc) const |
| | returns the forwarding agent for a given process/thread group (see forwards)
|
|
void | setForwardingAgent (ProcessID::ProcessID_t proc, EventTranslator *trans) |
| | sets the forwarding agent for a given process/thread group (see forwards)
|
|
|
bool | isListeningAny (EventListener *el, EventBase::EventGeneratorID_t egid) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isListeningAny (EventListener *el, EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isListeningAll (EventListener *el, EventBase::EventGeneratorID_t egid) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isListeningAll (EventListener *el, EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isListening (EventListener *el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isListening (EventListener *el, const EventBase &e) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isTrappingAny (EventTrapper *el, EventBase::EventGeneratorID_t egid) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isTrappingAny (EventTrapper *el, EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isTrappingAll (EventTrapper *el, EventBase::EventGeneratorID_t egid) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isTrappingAll (EventTrapper *el, EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isTrapping (EventTrapper *el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
bool | isTrapping (EventTrapper *el, const EventBase &e) |
| | returns true if the specified listener/trapper would receive any events that match the specified criteria
|
|
|
bool | hasListeners (EventBase::EventGeneratorID_t egid) |
| | counts both listeners and trappers, so generators can tell if it even needs to bother generating an event...
|
|
bool | hasListeners (EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | counts both listeners and trappers, so generators can tell if it even needs to bother generating an event...
|
|
bool | hasListeners (EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) |
| | counts both listeners and trappers, so generators can tell if it even needs to bother generating an event...
|
|
bool | hasListeners (const EventBase &e) |
| | counts both listeners and trappers, so generators can tell if it even needs to bother generating an event...
|
|
| void | addTimer (EventListener *el, unsigned int sid, unsigned int delay, bool repeat=true) |
| | adds a timer if it doesn't exist, or resets the timer if it already exists.
|
|
void | addTimer (EventListener *el, const EventBase &e, bool repeat=true) |
| | calls the other addTimer() with the event's source id and duration, doesn't check to see if the generator is timerEGID
|
|
void | removeTimer (EventListener *el) |
| | clears all pending timers for listener el; see remove()
|
|
void | removeTimer (EventListener *el, unsigned int sid) |
| | clears any pending timers with source id sid for listener el
|
|
void | removeTimer (EventListener *el, EventBase &e) |
| | clears any pending timers with source id matching that of e, but only if e has generator timerEGID
|
|
void | removeAllTimers () |
| | clears all timers for all listeners
|
|
unsigned int | getNextTimer () |
| | returns time of next timer activation
|
|
| void | addTrapper (EventTrapper *el, const EventBase &e) |
| | Adds a trapper for a specific source id and type from a given event generator.
|
| void | addTrapper (EventTrapper *el, EventBase::EventGeneratorID_t egid) |
| | Adds a trapper for all events from a given event generator.
|
| void | addTrapper (EventTrapper *el, EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | Adds a trapper for all types from a specific source and generator.
|
| void | addTrapper (EventTrapper *el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) |
| | Adds a trapper for a specific source id and type from a given event generator.
|
| void | addTrapper (EventTrapper *el) |
| | adds a trapper for ALL events
|
|
void | removeTrapper (EventTrapper *el, const EventBase &e) |
| | stops sending specified events from the generator to the trapper.
|
|
void | removeTrapper (EventTrapper *el, EventBase::EventGeneratorID_t egid) |
| | stops sending specified events from the generator to the trapper.
|
|
void | removeTrapper (EventTrapper *el, EventBase::EventGeneratorID_t egid, unsigned int sid) |
| | stops sending specified events from the generator to the trapper.
|
|
void | removeTrapper (EventTrapper *el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) |
| | stops sending specified events from the generator to the trapper.
|
|
void | removeTrapper (EventTrapper *el) |
| | stops sending ALL events to the trapper
|
Protected Types |
typedef std::vector< TimerEntry
* >::iterator | timer_it_t |
| | makes code more readable
|
Protected Member Functions |
|
void | chkTimers () |
| | just for debugging
|
|
void | dispTimers () |
| | just for debugging
|
Protected Attributes |
|
std::vector< TimerEntry * > | timers |
| | the list of timer entries being maintained, kept sorted by time they go active
|
|
EventMapper | trappers |
| | A mapping of which EventTrapper's should get a chance to trap the event.
|
|
EventMapper | listeners |
| | A mapping of which EventListener's should receive events.
|
|
std::queue< PostingStatus * > | postings |
| | stores calls to post() currently in progress -- may grow if one postEvent() triggers another; this allows us to finish processing of the original postEvent() before starting the second.
|
| EventTranslator * | forwards [ProcessID::NumProcesses] |
| | This table will be checked on each processEvent to forward the event to some other destination.
|
Private Member Functions |
|
| EventRouter (const EventRouter &) |
| | don't call this
|
|
EventRouter & | operator= (const EventRouter &) |
| | don't call this
|
Classes |
| class | EventMapper |
| | Does the actual storage of the mapping between EventBase's and the EventListeners/EventTrappers who should receive them. More...
|
| class | PostingStatus |
| | contains information regarding the progress of posting an event More...
|
| struct | TimerEntry |
| | Contains all the information needed to maintain a timer by the EventRouter. More...
|
| class | TimerEntryPtrCmp |
| | Used by STL to sort the timer list in order of activation time. More...
|
Member Function Documentation
| void EventRouter::addTimer |
( |
EventListener * |
el, |
|
|
unsigned int |
sid, |
|
|
unsigned int |
delay, |
|
|
bool |
repeat = true | |
|
) |
| | |
adds a timer if it doesn't exist, or resets the timer if it already exists.
timers are unique by EventListener and source ID - can't have two timers for the same el and sid
a delay of 0 with repeating will cause an event to be sent at every opportunity, use sparingly
a delay of -1U will call removeTimer() if it already exists, otherwise is ignored
- Parameters:
-
| el | the EventListener to send the timer event to |
| sid | the source ID to use on that event (if you need to send more info, send a pointer to a struct of your devising, typecasted as int) |
| delay | the delay between the first (and future) calls |
| repeat | set to true if you want to keep receiving this event, otherwise it will only send once |
Definition at line 110 of file EventRouter.cc.
Referenced by addTimer(), NullTrans::DoStart(), ConnectionMadeTrans::DoStart(), EventProxy::handleRemoteRequest(), PostureEditor::processEvent(), BatteryMonitorBehavior::processEvent(), SensorObserverControl::RTViewControl::refresh(), PostureEditor::refresh(), NetworkStatusControl::refresh(), RemoteRouter::RemoteRouter(), TimeOutTrans::resetTimer(), FreeMemReportControl::resetTimerFreq(), WalkControllerBehavior::runCommand(), UPennWalkControllerBehavior::runCommand(), RemoteRouter::sendRemoteRequest(), BatteryMonitorBehavior::startWarning(), and TorqueCalibrate::TakeMeasurementControl::takeInput().
adds a trapper for ALL events
Note that since timers are not broadcast, they cannot be trapped. Only the EventListener which requested the timer will receive that timer.
Definition at line 419 of file EventRouter.cc.
Adds a trapper for a specific source id and type from a given event generator.
Note that since timers are not broadcast, they cannot be trapped. Only the EventListener which requested the timer will receive that timer.
Definition at line 409 of file EventRouter.cc.
Adds a trapper for all types from a specific source and generator.
Note that since timers are not broadcast, they cannot be trapped. Only the EventListener which requested the timer will receive that timer.
Definition at line 399 of file EventRouter.cc.
Adds a trapper for all events from a given event generator.
Note that since timers are not broadcast, they cannot be trapped. Only the EventListener which requested the timer will receive that timer.
Definition at line 390 of file EventRouter.cc.
| void EventRouter::postEvent |
( |
EventBase * |
e |
) |
|
deprecated -- pass by reference instead; this version posts the specified event and then deletes it after processing is complete
moving to pass by reference instead of pass by pointer to avoid questions about who deletes the event and the event's scope, also keeping the event on the stack is faster by avoiding unnecessary heap operations.
Definition at line 50 of file EventRouter.cc.
| void EventRouter::processEvent |
( |
const EventBase & |
e |
) |
[virtual] |
sends event to its trappers & listeners, but doesn't delete the event at the end (see also postEvent())
this posting method is supplied to allow an EventRouter to behave as a listener as well -- the 'routers' really can form a sort of network, if desired. postEvent() is probably a more memnomic interface to use in direct function calls however, so that is the one you should call.
Implements EventListener.
Definition at line 475 of file EventRouter.cc.
Referenced by postEvent().
| void EventRouter::processTimers |
( |
|
) |
|
determines if timers need to be posted, and posts them if so.
Call this often to ensure accurate timers.
Definition at line 53 of file EventRouter.cc.
Member Data Documentation
This table will be checked on each processEvent to forward the event to some other destination.
The main reason for including this functionality is in the uni-process model, we don't want event postings from real time processes like Motion to block on the event queue processing. So with this mechanism we can intercept those events, and queue them in a separate IPC mechanism to be picked up by Main later on.
This might also be handy for other purposes, such as remote event forwarding over the network...
If the EventTranslator's trapEvent returns true, then further processing on the event is skipped. (see EventTranslator::setTrapEventValue() )
Definition at line 522 of file EventRouter.h.
Referenced by EventRouter(), getForwardingAgent(), processEvent(), setForwardingAgent(), and ~EventRouter().
The documentation for this class was generated from the following files:
|