C++ 多播事件
用于在 C++ 中声明和定义多播事件源和接收器的辅助工具
介绍
许多编程语言原生提供某种形式的事件处理机制,包括委托。网络上有很多优秀的解决方案,例如 成员函数指针和最快的 C++ 委托 [^],这仍然是我最喜欢的 CodeProject 文章之一,或者 Boost [^] 和 Loki [^],这些是我首先想到的库。
提供的源代码提供了一种基本解决方案,用于在 C++ 中声明和定义多播事件源和事件接收器。
背景
提供的解决方案大量使用宏来
- 定义模板化的基类,这些基类可用于声明和定义事件源;
- 定义基类,这些基类可用于声明和定义事件接收器。
使用宏和继承来解决问题的一个少数积极方面是,可以生成易于阅读的事件 getter 方法名称。
另一方面,宏的所有负面影响,尤其是复杂的宏,是众所周知的。新的 C++ 语言特性也为新的方法提供了大量的机会。
该解决方案也没有提供指定签名中返回类型的方法。可以轻松添加它,但我认为这需要额外的处理才能真正保持一致,正如我在 这个 C# 技巧 [^] 中尝试展示的那样,因此它可能属于后续版本。
使用代码
附带的源代码包含头文件 MulticastEvent.h,这是使用该库所需的唯一文件。
#include "MultiCastEvent.h"
事件签名可以这样定义:
#define MULTICAST_EVENT_CALLED_A (ClassExposingEvents, MethodACalledEvent, int, x, int, y)
#define MULTICAST_EVENT_CALLED_B (ClassExposingEvents, MethodBCalledEvent)
事件源可以使用事件签名这样定义:
// a class which exposes two events named MethodACalledEvent and MethodBCalledEvent
class ClassExposingEvents
{
public:
ClassExposingEvents()
// initialize the multicast target lists
: MULTICAST_EVENT_VAR_DEF(MULTICAST_EVENT_CALLED_A)
, MULTICAST_EVENT_VAR_DEF(MULTICAST_EVENT_CALLED_B)
{};
~ClassExposingEvents() {};
public:
// declare and define the two events
DECLARE_MULTICAST_EVENT(MULTICAST_EVENT_CALLED_A);
DECLARE_MULTICAST_EVENT(MULTICAST_EVENT_CALLED_B);
public:
// two example methods which invoke the events and report themselfes
void a(int x, int y) { getMethodACalledEvent().invoke(x, y); /* 2do: add code */ };
bool b() { getMethodBCalledEvent().invoke(); /* 2do: add code */ return true; };
};
事件接收器可以类似地定义:
// a class which sinks the two exposed events of ClassExposingEvents to report on invocation
class ClassImplementingEventHandlers
// implement the interfaces of the events
: public DECLARE_MULTICAST_EVENT_TARGET_SUPERCLASS(MULTICAST_EVENT_CALLED_A)
, public DECLARE_MULTICAST_EVENT_TARGET_SUPERCLASS(MULTICAST_EVENT_CALLED_B)
{
public:
ClassImplementingEventHandlers() {};
~ClassImplementingEventHandlers() {};
public:
// declare or inline define the event handlers to report when being invoked
DECLARE_MULTICAST_EVENT_TARGET(MULTICAST_EVENT_CALLED_A) /* or define it inline */;
DECLARE_MULTICAST_EVENT_TARGET(MULTICAST_EVENT_CALLED_B) /* or define it inline */;
};
// define the event handlers if they haven't got inline defined to report when being invoked
DEFINE_MULTICAST_EVENT_TARGET(ClassImplementingEventHandlers, MULTICAST_EVENT_CALLED_A)
{
// todo: add handler code
}
DEFINE_MULTICAST_EVENT_TARGET(ClassImplementingEventHandlers, MULTICAST_EVENT_CALLED_B)
{
// todo: add handler code
}
实例化后,源和接收器可以像这样路由:
// define event sources
ClassExposingEvents eventSource;
// define event sinks
ClassImplementingEventHandlers eventSink;
// create routes
eventSource.getMethodACalledEvent().addListener(eventSink);
兴趣点
提供的源代码非常基础,仅提供作为进一步开发的起点所需的最低限度。既没有考虑线程安全,也没有考虑性能、内存使用或其他方面。
历史
- 2014/01/08:提交了第一个版本。