MessageQueue Class Reference
#include <message.h>
Detailed Description
A doubly-linked queue of messages.Player Message objects are delivered by being pushed on and popped off queues of this type. Importantly, every driver has one, Driver::InQueue. All messages sent to the driver arrive on this queue. However, the driver rarely pops messages off its queue directly; instead the driver calls Driver::ProcessMessages, which hands off each incoming message to Driver::ProcessMessage (which the driver has presumably re-implemented).
Every queue has a maximum length that is determined when it is created; for drivers this happens in the constructor Driver::Driver. This length determines the maximum number of messages that can be pushed onto the queue. Since messages vary greatly in size, there is not a direct correspondence between the length of a queue and the memory that it occupies. Furthermore, since messages are reference counted and may be shared across multiple queues, it is not necessarily meaningful to consider how much memory a given queue "occupies."
The queue supports configurable message replacement. This functionality is useful when, for example, a driver wants new incoming commands to overwrite old ones, rather than to have them queue up. To decide whether an incoming message should replace an existing message that has the same address (host:robot:interface:index), type, and subtype, the following logic is applied:
- If a matching replacement rule was set via AddReplaceRule(), that rule is followed.
- Else:
- If the message type is PLAYER_MSGTYPE_REQ, PLAYER_MSGTYPE_RESP_ACK, or PLAYER_MSGTYPE_RESP_NACK, the message is not replaced.
- Else:
- If MessageQueue::Replace is false (it is set in the constructor and can be changed via SetReplace()), the message is not replaced.
- Else:
- The message is replaced.
Most drivers can simply choose true or false in their constructors (this setting is passed on to the MessageQueue constructor). However, drivers that support multiple interfaces may use AddReplaceRule() to establish different replacement rules for messages that arrive for different interfaces. For example, the p2os driver has incoming commands to the wheelmotors overwrite each other, but queues up commands to the manipulator arm.
The queue also supports filtering based on device address. After SetFilter() is called, Pop() will only return messages that match the given filter. Use ClearFilter() to return to normal operation. This filter is not usually manipulated directly in driver code; it's main use inside Device::Request.
Public Member Functions | |
MessageQueue (bool _Replace, size_t _Maxlen) | |
Create an empty message queue. | |
~MessageQueue () | |
Destroy a message queue. | |
bool | Empty () |
Check whether a queue is empty. | |
MessageQueueElement * | Push (Message &msg) |
Push a message onto the queue. | |
Message * | Pop () |
Pop a message off the queue. | |
Message * | PopReady (void) |
Pop a ready message off the queue. | |
void | SetReplace (bool _Replace) |
Set the Replace flag, which governs whether data and command messages of the same subtype from the same device are replaced in the queue. | |
void | AddReplaceRule (int _host, int _robot, int _interf, int _index, int _type, int _subtype, bool _replace) |
Add a replacement rule to the list. | |
void | AddReplaceRule (const player_devaddr_t &device, int _type, int _subtype, bool _replace) |
Add a replacement rule to the list. | |
bool | CheckReplace (player_msghdr_t *hdr) |
Check whether a message with the given header should replace any existing message of the same signature. | |
void | Wait (void) |
Wait on this queue. | |
void | DataAvailable (void) |
Signal that new data is available. | |
bool | Filter (Message &msg) |
Check whether a message passes the current filter. | |
void | ClearFilter (void) |
Clear (i.e., turn off) message filter. | |
void | SetFilter (int host, int robot, int interf, int index, int type, int subtype) |
Set filter values. | |
void | SetPull (bool _pull) |
Set the pull flag, which if true then requires messages to be marked as ready before they will be sent to the client. | |
void | MarkAllReady (void) |
Mark all messages in the queue as ready to be sent. |
Member Function Documentation
|
Add a replacement rule to the list. Use this version if you already have the device address assembled in a player_devaddr_t structure. The tradeoff is that you cannot use -1 to indicate don't care for those values (the fields in that structure are unsigned). |
|
Add a replacement rule to the list. The first 6 arguments determine the signature that a message will have to match in order for this rule to be applied. If an incoming message matches this signature, the last argument determines whether replacement will occur. Set any of the first 6 arguments to -1 to indicate don't care. |
|
Signal that new data is available. Calling this method will release any threads currently waiting on this queue. |
|
Pop a message off the queue. Pop the head (i.e., the first-inserted) message from the queue. Returns pointer to said message, or NULL if the queue is empty |
|
Pop a ready message off the queue. Pop the head (i.e., the first-inserted) message from the queue. If pull_flag is true, only pop messages marked as ready. Returns pointer to said message, or NULL if the queue is empty |
|
Push a message onto the queue. Returns a pointer to the new last element in the queue. |
|
Wait on this queue. This method blocks until new data is available (as indicated by a call to DataAvailable()). |
The documentation for this class was generated from the following file: