📄 eventrouter.h
字号:
#ifndef _XP_EVENTROUTER_H__
#define _XP_EVENTROUTER_H__
#include "..\CppIface.h"
#include "..\Events\Event.h"
#include "..\Events\EventListener.h"
///////////////////////////////////////////////////////////////////////////
// IEventRouter
//@doc IEventRouter
//@mfunc XPBool | IEventRouter | RouteEvent | Routes event objects to event listeners.
//@rdesc TRUE if at least one listener handled the event.
//@parm IEvent* | pIEvent | Pointer to event object.
//@doc IEventRouter
//@mfunc XPBool | IEventRouter | AddListener | Add an event listener to the router.
//@rdesc TRUE if successful, otherwise FALSE.
//@parm IEventListener* | pIListener | Pointer to event listener to add.
//@doc IEventRouter
//@mfunc XPBool | IEventRouter | RemoveListener | Remove an event listener from the router.
//@rdesc TRUE if successful, otherwise FALSE.
//@parm IEventListener* | pIListener | Pointer to event listener to remove.
//@class IEventRouter | Interface for routing events to event listeners.
// The RouteEvent method takes a pointer to an event and returns TRUE if
// the event was handled by one or more listeners or FALSE if the event
// was not handled.
//@base public | IRefCount
//@base public | IQueryGuid
#define XP_IEVENTROUTER_IID \
{ 0x8a189178, 0xb5e8, 0x4c7e, { 0x97, 0xfc, 0xa2, 0x2e, 0x57, 0x7, 0xe6, 0x5f } };
class IEventRouter : public IRefCount, public IQueryGuid
{
public:
//@cmember
/* Routes event objects to event listeners. */
virtual XPBool RouteEvent(IEvent* pIEvent) = 0;
//@cmember
/* Add an event listener to the router. */
virtual XPBool AddListener(IEventListener* pIListener) = 0;
//@cmember
/* Remove an event listener from the router. */
virtual XPBool RemoveListener(IEventListener* pIListener) = 0;
XP_IMPL_IID(XP_IEVENTROUTER_IID)
};
///////////////////////////////////////////////////////////////////////////
//@doc IEventRouterImpl
//
//@class IEventRouterImpl | Provides a default implementation of the
// <c IEventRouter> interface. This class maintains a list of event
// listeners and implements <mf IEventRouterImpl::RouteEvent> by iterating
// over the listeners and calling <mf IEventListener::HandleEvent>.
//
//@base public | IEventRouter
class IEventRouterImpl : public IEventRouter
{
// Constructors/destructor
public:
virtual ~IEventRouterImpl()
{
while (m_listeners.size() > 0)
{
IEventListener* pIListener = m_listeners.back();
pIListener->Release();
m_listeners.pop_back();
}
}
// Attributes
protected:
//@cmember
/* Array of event listeners*/
ListenerVector m_listeners;
// Operations
public:
//@cmember,mfunc Cast object to a pointer type given a GUID.
//@@rdesc XP_TRUE if object is successfully cast to the new data type, otherwise XP_FALSE.
//@@parm XPREFIID | guid | Input GUID that determines the data type to cast to.
//@@parm void ** | ppvObj | Output parameter to receive the result of the cast.
//@@end
/* Cast object to a pointer type given a GUID*/
virtual XPBool QueryGuid(XPREFIID guid, void **ppvObj)
{
XPBool bResult = XP_FALSE;
*ppvObj = 0;
if (guid == IEventRouter::IID())
{
*ppvObj = static_cast<IEventRouter*>(this);
bResult = XP_TRUE;
}
return bResult;
}
//@cmember,mfunc
// Add a reference to this object.
//@@rdesc New reference count value.
//@@comm This is a no-op implementation. Derived classes must
// override in order to provide reference counting.
//@@end
/* Add a reference to this object*/
XPUint32 XPSTDMETHODCALLTYPE AddRef()
{
return 1;
}
//@cmember,mfunc
// Release a reference to this object.
//@@rdesc New reference count value.
//@@comm This is a no-op implementation. Derived classes must
// override in order to provide reference counting.
//@@end
/* Release a reference to this object*/
XPUint32 XPSTDMETHODCALLTYPE Release()
{
return 1;
}
//@cmember,mfunc
// Routes event objects to event listeners.
//@@rdesc TRUE if at least one listener handled the event.
//@@parm IEvent* | pIEvent | Pointer to event object.
//@@end
/* Routes event objects to event listeners*/
virtual XPBool RouteEvent(IEvent* pIEvent)
{
int nHandledCount = 0;
if (pIEvent != 0)
{
ListenerVector::const_iterator itListener;
//
// Give each event listener a chance to handle the event.
//
for (itListener = m_listeners.begin(); itListener != m_listeners.end(); itListener++)
{
if ((*itListener)->HandleEvent(pIEvent))
{
nHandledCount++;
}
}
}
return (nHandledCount > 0);
}
//@cmember,mfunc
// Add an event listener to the router.
//@@rdesc TRUE if successful, otherwise FALSE.
//@@parm IEventListener* | pIListener | Pointer to event listener to add.
//@@end
/* Add an event listener to the router*/
virtual XPBool AddListener(IEventListener* pIListener)
{
if (pIListener != 0)
{
pIListener->AddRef();
m_listeners.push_back(pIListener);
return XP_TRUE;
}
return XP_FALSE;
}
//@cmember,mfunc
// Remove an event listener from the router.
//@@rdesc TRUE if successful, otherwise FALSE.
//@@parm IEventListener* | pIListener | Pointer to event listener to remove.
//@@end
/* Remove an event listener from the router*/
virtual XPBool RemoveListener(IEventListener* pIListener)
{
ListenerVector::iterator itListener = m_listeners.begin();
while (itListener != m_listeners.end())
{
if (pIListener == *itListener)
{
(*itListener)->Release();
m_listeners.erase(itListener);
return XP_TRUE;
}
else
{
itListener++;
}
}
return XP_FALSE;
}
};
///////////////////////////////////////////////////////////////////////////
//@doc CComboRouterListener
//
//@class CComboRouterListener | Implements HandleEvent method for a
// combined router and listener object.
//
//@tcarg class | base_t | Base class to override. Must be derived from both <c IEventListener>
// and <c IEventRouter>
//
//@base public | base_t
template <class base_t>
class CComboRouterListener : public base_t
{
public:
//@cmember,mfunc
// Receive an event and attempt to handle it.
//@@rdesc TRUE if successful, otherwise FALSE.
//@@parm IEvent* | pIEvent | Pointer to event to handle.
//@@comm This function first attempts to dispatch the event onto
// the base class, since it is an event listener. If the event
// isn't handle, it then calls RouteEvent.
//@@end
/* Receive an event and attempt to handle it*/
virtual XPBool HandleEvent(IEvent* pIEvent)
{
XPBool bHandled = XP_FALSE;
if (pIEvent != 0)
{
bHandled = pIEvent->Dispatch(guid_cast<IEventRouter*>(this));
}
if (!bHandled)
bHandled = base_t::RouteEvent(pIEvent);
return bHandled;
}
};
///////////////////////////////////////////////////////////////////////////
//@doc CListeningRouter
//
//@class CListeningRouter | Mixes in IEventListener into an event router
// and implements HandleEvent method.
//
//@tcarg class | base_t | Base class to override. Must be derived from <c IEventRouter>
//
//@base public | base_t
//@base public | IEventListener
template <class base_t>
class CListeningRouter : public base_t, public IEventListener
{
public:
//@cmember,mfunc
// Receive an event and attempt to handle it.
//@@rdesc TRUE if successful, otherwise FALSE.
//@@parm IEvent* | pIEvent | Pointer to event to handle.
//@@comm This function first attempts to dispatch the event onto
// the base class, since it is an event listener. If the event
// isn't handle, it then calls RouteEvent.
//@@end
/* Receive an event and attempt to handle it*/
virtual XPBool HandleEvent(IEvent* pIEvent)
{
XPBool bHandled = XP_FALSE;
if (pIEvent != 0)
{
bHandled = pIEvent->Dispatch(guid_cast<IEventRouter*>(this));
}
if (!bHandled)
bHandled = base_t::RouteEvent(pIEvent);
return bHandled;
}
BEGIN_GUID_MAP(CListeningRouter<base_t>)
GUID_ENTRY(IEventListener)
GUID_CHAIN_ENTRY(base_t)
END_GUID_MAP
XPUint32 XPSTDMETHODCALLTYPE AddRef()
{
return base_t::AddRef();
}
XPUint32 XPSTDMETHODCALLTYPE Release()
{
return base_t::Release();
}
};
#endif // #ifndef _XP_EVENTROUTER_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -