Skip to content

Commit

Permalink
Create docs for event notifier
Browse files Browse the repository at this point in the history
  • Loading branch information
FreeZoneMods committed Nov 10, 2018
1 parent fbb86ef commit fb67938
Showing 1 changed file with 75 additions and 0 deletions.
75 changes: 75 additions & 0 deletions src/xrCore/Events/Notifier.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/*!
\file
\brief Implementation of simple thread-safe event processing and notifying system
\details Will be useful when you need a system which allows you to handle events with calling the subscribed callbacks.
*/

#pragma once

#include "xrCommon/xr_smart_pointers.h"
Expand All @@ -6,26 +13,52 @@
#include "xrCore/Threading/Lock.hpp"
#include "xrCore/Threading/ScopeLock.hpp"

/*!
\brief Base abstract class for implementing event handling callbacks
\details Derive it and override @ref ProcessEvent method, then register the instanciated callback into the event
notifier. The @ref ProcessEvent method will be called by the notifier every time when the selected event happens
*/
class CEventNotifierCallback
{
public:
/*! Callback ID, type for identifying registered callbacks in the notifier */
using CID = size_t;

/*! Invalid callback ID, will be never returned after successful subscription */
static const CID INVALID_CID = std::numeric_limits<CID>::max();

/*! This method will be automatically called by the notifier for processing the event */
virtual void ProcessEvent() = 0;

virtual ~CEventNotifierCallback(){};
};

/*!
\brief Abstract class for event processing callback which stores own callback ID
\details Designed to use primarily in pair with @ref CEventNotifier::CreateRegisteredCallback method,
very useful for self-unsubscribing callbacks
*/
class CEventNotifierCallbackWithCid : public CEventNotifierCallback
{
private:
const CID m_cid;

public:
/*! Constructor, takes callback ID which was generated by the notifier
/param[in] cid callback ID, should be generated by the notifier in subscription process only
*/
CEventNotifierCallbackWithCid(CID cid) : m_cid(cid), CEventNotifierCallback(){};

/*! Returns the callback ID which was generated by the notifier and passed to the constructor */
CID GetCid() const { return m_cid; }
};

/*! \brief Template class for the event processing dispatcher
\details Manages with subscribing, calling and unsubscribing handlers. Template parameter CNT is a count of events
which we are going to process using the dispatcher. Owns the event's handling callbacks and controls its lifetime.
*/
template <unsigned int CNT>
class CEventNotifier
{
Expand Down Expand Up @@ -134,25 +167,67 @@ class CEventNotifier
xr_array<CCallbackStorage, CNT> m_callbacks;

public:
/*! \brief Method for registering an existing event handler.
\details Use it to register in the notifier previously created event handling callback.
\warning Please consider using @ref CreateRegisteredCallback method instead. When using the @ref
RegisterCallback method you should register only the callbacks which were created by the other methods of the
notifier. This restriction happens because the notifier owns the callbacks and destroyes it internally, so you
can get some problems when creating the callbacks outside of the notifier (notifier will call improper
destruction methods).
\todo Provide the method for creating callbacks without the registration
\param[in] cb pointer to
the callback to register. After registration the notifier becomes an owner of the registered callback
\param[in] event_id Index of the event type which the callback should process, must be lesser than the template
parameter CNT
\return Callback ID of the registered callback (unique for each event type)
*/
CEventNotifierCallback::CID RegisterCallback(CEventNotifierCallback* cb, unsigned int event_id)
{
R_ASSERT(event_id < CNT);
return m_callbacks[event_id].RegisterCallback(cb);
}

/*! \brief Template method which creates a new event handling callback and registers it in the notifier
\details Provides a convenient way for registering the event handlers. It's a preferred method for setting up
the event handlers. The template parameter CB is a type of the event handling callback which we are going to
create
\param[in] event_id Index of the event type which the callback should process, must be lesser than template
parameter template parameter CNT
\param[in] args Arguments which should be passed to the constructor of the callback
\return Callback ID of the registered callback (unique for each event type)
*/
template <class CB, class... Args>
CEventNotifierCallback::CID CreateRegisteredCallback(unsigned int event_id, Args&&... args)
{
R_ASSERT(event_id < CNT);
return m_callbacks[event_id].CreateRegisteredCallback<CB>(args...);
}

/*! \brief Provides the way to unsubscribe and delete the callback
\details The callback will be automatically destroyed by the notifier after unsubscribing. However, the
unsubscribing logic allows to unsubscribe the callback directly while processing the event. Callback won't be
destroyed while its event handling method is executing.
\param[in] cid Callback ID which was returning by the subscribing function
\param[in] event_id Index of the event type which the callback is subscribed to
\return True if unsubscribing is successful, false otherwise
*/
bool UnregisterCallback(CEventNotifierCallback::CID cid, unsigned int event_id)
{
R_ASSERT(event_id < CNT);
return m_callbacks[event_id].UnregisterCallback(cid);
}

/*! \brief The method to notify the subscribed callbacks about the event
\details Call this method when the event happens. All the subscribed callbacks would be called one-by-one in the
caller's thread.
\param[in] event_id Index of the event type
*/
void FireEvent(unsigned int event_id)
{
R_ASSERT(event_id < CNT);
Expand Down

0 comments on commit fb67938

Please sign in to comment.