EAMessageExtra provides additional optional functionality on top of EAMessage related to delayed message delivery beyond the message posting functionality present in the EAMessage Server. Three classes are currently provided:
Class Description DeferredMessage Implements a message that is sent after a given amount of time. This is like a posted message but the delivery doesn't just occur upon the next message management cycle but instead after a certain amount of time or events (e.g. vblanks). ThreadSafeCallback Implements a callback that is done via EA::Callback but the callback occurs in the main thread instead of the Callback thread. A primary use of this is to allow a system to receive callbacks in a thread-safe way because Callback may occur outside the main thread but the recipient wants the callback to occur in the main thread. CallbackMessage Implements a Callback (EA::Callback) that sends or posts a callback event to a given recipient instead of a calling a member function. A primary use of this is to allow a system to receive Callbacks via messaging instead of via a specific member function. This allows some systems to be written in a more generic way and have reduced dependencies, assuming those systems are already messaging-savvy.
DeferredMessage:
/// DeferredMessage /// /// Implements a message that is sent after a certain amount of time. /// This is like a posted message but the delivery doesn't just occur /// upon the next message management cycle but instead after a certain /// amount of time or events (e.g. vblanks). /// /// Example usage: /// DeferredMessage dM; /// SomeMessage* pMessage = new SomeMessage; /// dm.MessagePost(1000, 0x12345678, pMessage, NULL, pServer); /// class DeferredMessage { public: /// MessagePost /// /// This function is guaranteed to succeed as long as a valid Server /// is supplied or available. If successful, pMessageRC and pHandlerRC /// (if non-NULL) will be AddRefd once each; the Release of each will /// occur upon delivery of the message. /// /// Currently this is a member function and not a static member function, /// even though there is no member data. We want to reserve the right to /// have member data in the future. /// bool MessagePost(uint32_t nTimeDeltaMS, MessageId id, IMessageRC* pMessageRC, IHandlerRC* pHandlerRC = NULL, Server* pServer = NULL); };
ThreadSafeCallback:
/// ThreadSafeCallback
///
/// Implements a callback that is done via EA::Callback but the callback
/// occurs in the main thread instead of the Callback thread. A primary use
/// of this is to allow a system to receive callbacks in a thread-safe way
/// because Callback may occur outside the main thread but the recipient
/// wants the callback to occur in the main thread.
///
/// Since this class works by transferring information from one thread to
/// another, the precision of this callback is necessarily lower than
/// when using EA::Callback directly.
///
/// This class is a subclass of IHandlerRC because this class needs to be a
/// message handler itself and because the asynchronous nature of this
/// functionality requires reference counting in order to work as desired.
///
/// Example usage:
/// void SomeCallbackFunction(void* pContext, uint32_t absTime, uint32_t deltaTime);
///
/// ThreadSafeCallback* pThreadSafeCallback = new ThreadSafeCallback;
/// pThreadSafeCallback->AddRef(); // AddRef for our own ownership.
/// pThreadSafeCallback->Start(1000, true, SomeCallbackFunction, NULL, pServer);
/// ...
/// pThreadSafeCallback->Release(); // Release when we are done with it.
///
class ThreadSafeCallback : public IHandlerRC
{
public:
ThreadSafeCallback();
virtual ~ThreadSafeCallback();
bool Start(uint32_t nPeriodMS, bool bOneShot, EA::Callback::CallbackFunctionType pFunction,
void* pContext = NULL, Server* pServer = NULL);
bool Stop();
bool HandleMessage(MessageId messageId, void* pMessage);
int AddRef();
int Release();
};
CallbackMessage:
/// CallbackMessage
///
/// Implements a Callback (EA::Callback) that sends or posts a callback event
/// to a given recipient instead of a calling a member function. A primary use
/// of this is to allow a system to receive Callbacks via messaging instead of
/// via a specific member function. This allows some systems to be written in
/// a more generic way and have reduced dependencies, assuming those systems
/// are already messaging-savvy.
///
/// If the delivery method is kDeliverySend, then the send occurs directly from
/// a Callback and thus might not occur within the main thread. If the delivery
/// method is kDeliveryPost, the deliver occurs via the processing of the server
/// message queue, which usually happens in the main thread but is dependent on
/// the use of the Server.
///
/// To consider:
/// Allow for this CallbackMessage object to be refcounted by the Callback system.
///
/// Example usage:
/// CallbackMessage callbackMessage;
/// callbackMessage.Start(1000, false, kDeliveryPost, 0x12345678, NULL, pServer);
/// ...
/// callbackMessage.Stop();
///
class CallbackMessage
{
public:
typedef MessageBasicRC<2> CallbackMessageData;
CallbackMessage();
~CallbackMessage();
bool Start(uint32_t nPeriodMS, bool bOneShot, Delivery delivery, MessageId id,
IHandlerRC* pHandlerRC = NULL, Server* pServer = NULL);
bool Stop();
};