我正在编写一个Arduino库(Arduino平台上没有RTTI),其目的是模仿动作脚本3语言的事件系统,但是对于c ++来说我是新手,所以我遇到了一些我没想到的问题当我开始这个项目时:-)
为简明起见,此系统基于以下三项:事件/事件分派器/事件侦听器。 Event(或Event的子类)由Event Dispatcher调度,Event侦听器是采用Event类型的单个参数的回调函数。每当调度事件时,都会调用此事件类型的每个侦听器。
这里是一个极简示例代码(未实现实际的调度过程),以显示其工作原理:
#include <iostream>
#include <vector>
class Event
{
public:
std::string type;
Event(std::string type) : type(type){}
};
class FanEvent : public Event
{
public:
int fanRPM;
FanEvent(std::string type, int fanRPM)
: Event::Event(type), fanRPM(fanRPM){}
};
class EventListener
{
public:
std::function<void(Event *)> _listener;
std::string type;
EventListener(std::string type, std::function<void(Event *)> listener)
:type(type), _listener(listener){};
};
class ControllerBase
{
private:
std::vector<EventListener *> _eventListeners;
public:
void addEventlistener(std::string eventType, std::function<void(Event *)> listener)
{
_eventListeners.push_back(new EventListener(eventType, listener));
};
void dispatchEvent(Event *event)
{
_eventListeners[0]->_listener(event);
}
};
class FanController : public ControllerBase
{
public:
void init()
{
addEventlistener("speedChange", [this](Event *event)
{
this->updateFanStatus(static_cast<FanEvent *>(event));
});
}
void simulateEventDispatching()
{
dispatchEvent(new FanEvent("speedChange", 1200));
};
void updateFanStatus(FanEvent *event)
{
std::cout << "Fan RPM :" << event->fanRPM << std::endl;
}
};
int main()
{
FanController fanController;
fanController.init();
fanController.simulateEventDispatching();
return 0;
}
控制台输出为
风扇转速:1200
所以从原理上讲,它是可行的,但是我在执行真实事件分配过程时遇到两个问题:
如果最新的事件监听器已经指向相同的监听器函数,但我想阻止将eventListener添加到std :: vector,但我找不到找到两个std的方法: :功能相同。
如果指向该侦听器的EventListener实例的std :: string类型值等于Event的std :: string类型值,则将Event分配给侦听器。但是我想检查事件的事件类类型是否与侦听器的事件类类型参数相同:假设您有一个CustomEventA类和一个CustomEventB类,以及一个使用字符串类型注册到CustomEventA的侦听器=«更改»。如果派发了字符串类型=«更改»的CustomEventB,我不希望通知该侦听器。