C++ 此事件调度器/侦听器是否工作?
我正在开发一个多线程的程序。我需要对对象和线程之间的事件做出响应,因此我提出了以下代码C++ 此事件调度器/侦听器是否工作?,c++,multithreading,events,C++,Multithreading,Events,我正在开发一个多线程的程序。我需要对对象和线程之间的事件做出响应,因此我提出了以下代码 #ifndef EVENT_H #define EVENT_H #include <vector> #include <mutex> #include <algorithm> #include <memory> /** * Create the definition of a dispatcher for the event type (t) */ #d
#ifndef EVENT_H
#define EVENT_H
#include <vector>
#include <mutex>
#include <algorithm>
#include <memory>
/**
* Create the definition of a dispatcher for the event type (t)
*/
#define DISPATCHER(t) EventDispatcher<t>
/**
* Create the definition of a listener for event type (t)
*/
#define LISTENER(t) DISPATCHER(t)::EventListener
/**
* Dispatch a event (e) of type (t)
*/
#define DISPATCH(t, e) DISPATCHER(t)::dispatch(e);
/**
* Attach a listener (l) of type (t) to the dispatcher (d)
*/
#define LISTEN(t, d, l) ((DISPATCHER(t) *)(d))->addListener((l));
template <typename T>
class EventDispatcher {
public:
virtual ~EventDispatcher() {
std::unique_lock<std::recursive_mutex> uLock(lock);
// Prevent more listeners from being added.
isAlive = false;
// Remove all listeners.
while (listeners.begin() != listeners.end()) {
EventDispatcher<T>::EventListener *listener = *listeners.begin();
// Call remove listener so that the listener will be notified of the change.
removeListener(listener);
}
}
class EventListener {
friend EventDispatcher<T>;
public:
virtual ~EventListener() {
std::unique_lock<std::recursive_mutex> uLock(lock);
// Stop more dispatchers from connecting.
isAlive = false;
// Remove self from all dispatchers.
// Use while loop as removeListener will call removeDispatcher and modify dispatchers.
while (dispatchers.begin() != dispatchers.end()) {
EventDispatcher<T> *dispatcher = *dispatchers.begin();
dispatcher->removeListener(this);
}
}
protected:
/**
* Respond to an event.
* @param sender The dispatcher that sent the event.
* @param event The event that occurred.
*/
virtual void onEvent(EventDispatcher<T> *sender, std::shared_ptr<T> event) = 0;
private:
bool isAlive = true;
typedef std::vector<EventDispatcher<T> *> DispatcherList;
DispatcherList dispatchers;
std::recursive_mutex lock;
/**
* Add a reference to the dispatchers this listener is attached to.
* @param dispatcher The dispatcher that attached this listener.
* @return true if the listener is still alive.
*/
bool addDispatcher(EventDispatcher<T> *dispatcher) {
if (dispatcher == NULL) {
return false;
}
std::unique_lock<std::recursive_mutex> uLock(lock);
if (isAlive) {
if (std::find(dispatchers.begin(), dispatchers.end(), dispatcher) == dispatchers.end()) {
// This should only ever be called by the dispatcher so no need to call addListener.
dispatchers.push_back(dispatcher);
}
}
return isAlive;
}
/**
* Remove a reference to the dispatchers this listener is attached to.
* @param dispatcher The dispatcher that removed this listener.
*/
void removeDispatcher(EventDispatcher<T> *dispatcher) {
if (dispatcher == NULL) {
return;
}
std::unique_lock<std::recursive_mutex> uLock(lock);
typename DispatcherList::iterator itr = std::find(dispatchers.begin(), dispatchers.end(), dispatcher);
if (itr != dispatchers.end()) {
// This should only ever be called by the dispatcher so no need to call removeListener.
dispatchers.erase(itr);
}
}
};
public:
/**
* Add a listener to the dispatcher.
* @param listener The listener to add.
*/
void addListener(EventDispatcher<T>::EventListener *listener) {
if (listener == NULL) {
return;
}
std::unique_lock<std::recursive_mutex> uLock(lock);
if (isAlive) {
if (std::find(listeners.begin(), listeners.end(), listener) == listeners.end()) {
// Listener not in list, add it.
if (listener->addDispatcher(this)) {
// The listener was still alive so register it.
listeners.push_back(listener);
}
}
}
}
/**
* Remove a listener from the dispatcher.
* @param listener The listener to remove.
*/
void removeListener(EventDispatcher<T>::EventListener *listener) {
if (listener == NULL) {
return;
}
std::unique_lock<std::recursive_mutex> uLock(lock);
typename ListenerList::iterator itr = std::find(listeners.begin(), listeners.end(), listener);
if (itr != listeners.end()) {
listener->removeDispatcher(this);
listeners.erase(itr);
}
}
protected:
/**
* Dispatch an event to all listeners.
* @param event The event to dispatch.
* @note If the event is modifiable then not all listeners will necessarily get the exact same message.
* @note The event will be deleted before the function returns.
*/
void dispatch(T *event) {
std::shared_ptr<T> evt(event);
std::unique_lock<std::recursive_mutex> uLock(lock);
for (typename ListenerList::iterator iter = listeners.begin(); iter != listeners.end(); iter++) {
(*iter)->onEvent(this, evt);
}
}
/**
* Dispatch an event to all listeners.
* @param event The event to dispatch.
* @note If the event is modifiable then not all listeners will necessarily get the exact same message.
*/
void dispatch(std::shared_ptr<T> event) {
std::unique_lock<std::recursive_mutex> uLock(lock);
for (typename ListenerList::iterator iter = listeners.begin(); iter != listeners.end(); iter++) {
(*iter)->onEvent(this, event);
}
}
private:
bool isAlive = true;
typedef std::vector<EventListener *> ListenerList;
ListenerList listeners;
std::recursive_mutex lock;
};
#endif /* EVENT_H */
\ifndef事件
#定义事件
#包括
#包括
#包括
#包括
/**
*为事件类型(t)创建调度程序的定义
*/
#定义调度程序(t)EventDispatcher
/**
*为事件类型(t)创建侦听器的定义
*/
#定义侦听器(t)调度程序(t)::EventListener
/**
*分派类型(t)的事件(e)
*/
#定义调度(t,e)调度员(t)::调度(e);
/**
*将类型(t)的侦听器(l)连接到调度程序(d)
*/
#定义LISTEN(t,d,l)((DISPATCHER(t)*)(d))->addListener((l));
模板
类事件调度器{
公众:
虚拟~EventDispatcher(){
std::唯一锁定(锁定);
//防止添加更多侦听器。
isAlive=假;
//删除所有侦听器。
while(listeners.begin()!=listeners.end()){
EventDispatcher::EventListener*listener=*listeners.begin();
//调用remove listener,以便将更改通知给侦听器。
removeListener(监听器);
}
}
类EventListener{
好友事件调度员;
公众:
虚拟~EventListener(){
std::唯一锁定(锁定);
//阻止更多调度员连接。
isAlive=假;
//从所有调度员中删除self。
//使用while循环作为removeListener将调用removeDispatcher并修改dispatchers。
while(dispatchers.begin()!=dispatchers.end()){
EventDispatcher*dispatcher=*dispatchers.begin();
dispatcher->removeListener(此);
}
}
受保护的:
/**
*对事件作出反应。
*@param sender发送事件的调度程序。
*@param event发生的事件。
*/
虚拟void onEvent(EventDispatcher*sender,std::shared_ptr event)=0;
私人:
bool-isAlive=true;
typedef std::vector DispatcherList;
调度员名单调度员;
std::递归_互斥锁;
/**
*添加对此侦听器附加到的dispatchers的引用。
*@param dispatcher附加此侦听器的调度器。
*@如果侦听器仍处于活动状态,则返回true。
*/
bool addDispatcher(事件调度器*调度器){
if(dispatcher==NULL){
返回false;
}
std::唯一锁定(锁定);
如果(现场){
if(std::find(dispatchers.begin()、dispatchers.end()、dispatcher)=dispatchers.end()){
//这应该只由调度器调用,因此不需要调用addListener。
调度员。推回(调度员);
}
}
返回现场;
}
/**
*删除对此侦听器附加到的dispatchers的引用。
*@param dispatcher删除此侦听器的调度器。
*/
void removedDispatcher(EventDispatcher*dispatcher){
if(dispatcher==NULL){
返回;
}
std::唯一锁定(锁定);
typename DispatcherList::iterator itr=std::find(dispatchers.begin()、dispatchers.end()、dispatcher);
if(itr!=dispatchers.end()){
//这应该只由调度器调用,因此不需要调用removeListener。
调度员删除(itr);
}
}
};
公众:
/**
*将侦听器添加到调度程序。
*@param listener要添加的侦听器。
*/
void addListener(EventDispatcher::EventListener*监听器){
if(侦听器==NULL){
返回;
}
std::唯一锁定(锁定);
如果(现场){
if(std::find(listeners.begin()、listeners.end()、listener)=listeners.end()){
//侦听器不在列表中,请添加它。
如果(侦听器->添加调度程序(此)){
//听众还活着,所以请注册它。
监听器。推回(监听器);
}
}
}
}
/**
*从调度程序中删除侦听器。
*@param listener要删除的侦听器。
*/
void RemovelListener(EventDispatcher::EventListener*监听器){
if(侦听器==NULL){
返回;
}
std::唯一锁定(锁定);
typename ListenerList::迭代器itr=std::find(listeners.begin(),listeners.end(),listener);
if(itr!=listeners.end()){
侦听器->removeDispatcher(此);
侦听器。擦除(itr);
}
}
受保护的:
/**
*将事件分派给所有侦听器。
*@param event要分派的事件。
*@note如果事件是可修改的,则并非所有侦听器都必须获得完全相同的消息。
*@注意:在函数返回之前,事件将被删除。
*/
无效调度(T*事件){
std::共享的ptr evt(事件);
std::唯一锁定(锁定);
对于(typename ListenerList::iterator iter=listeners.begin();iter!=listeners.end();iter++){
(*国际热核实验堆)->onEvent(即evt);
}
}
/**
*将事件分派给所有侦听器。
*@param event要分派的事件。
*@note如果事件是可修改的,则并非所有侦听器都必须获得完全相同的消息。
*/
无效调度(std::共享ptr事件){
std::唯一锁定(锁定);
对于(typename ListenerList::iterator iter=listeners.begin();iter!=listeners.end();iter++){
(*国际热核实验堆)->onEvent(本次事件);
}
}
私人:
bool-isAlive=true;
typedef std::vector ListenerList;
监听器列表监听器;
std::递归_互斥锁;
};
#endif/*事件*/
这是我设置的一个简单测试(还没有多线程)
#包括“include/Event.h”
#包括
类动作事件{
公众:
ActionEvent(int id):actionID(id){
//actionID=id;
}
const int actionID;
};
类PropertyChangeEvent{
公众:
int-propertyID;
};
类testDispatcher:public DISPATCHER(ActionEvent)、public DISPATCHER(PropertyChangeEvent){
公众:
无效测试(){
//分派(新ActionEvent(0));//函数不明确。
//dispatch(new PropertyChangeEvent());//函数不明确
#include "include/Event.h"
#include <iostream>
class ActionEvent {
public:
ActionEvent(int id) : actionID(id) {
// actionID = id;
}
const int actionID;
};
class PropertyChangeEvent {
public:
int propertyID;
};
class testDispatcher : public DISPATCHER(ActionEvent), public DISPATCHER(PropertyChangeEvent) {
public:
void test() {
// dispatch(new ActionEvent(0)); // ambiguous function.
// dispatch(new PropertyChangeEvent()); // ambiguous function.
// EventDispatcher<ActionEvent>::dispatch(new ActionEvent(1)); // works but is long.
// EventDispatcher<ActionEvent>::dispatch(new ActionEvent(2)); // works but is long.
// EventDispatcher<PropertyChangeEvent>::dispatch(new PropertyChangeEvent()); // works but is long.
DISPATCH(ActionEvent, new ActionEvent(1)); // The dispatcher will make a shared pointer then delete the event.
DISPATCH(ActionEvent, std::shared_ptr<ActionEvent>(new ActionEvent(2)));
DISPATCH(PropertyChangeEvent, new PropertyChangeEvent());
}
};
class testListener :
public LISTENER(ActionEvent), public LISTENER(PropertyChangeEvent) {
int ID;
public:
testListener(testDispatcher *dispatcher, int id) {
ID = id;
// dispatcher->addListener(this); // ambiguous function.
// dispatcher->addListener((EventDispatcher<ActionEvent>::EventListener *) this); // ambiguous function.
// ((EventDispatcher<ActionEvent> *)dispatcher)->addListener(this); // works but is long.
LISTEN(ActionEvent, dispatcher, this);
if(id % 2) {
// Only respond to property change events on odd numbered listeners just to be different.
// dispatcher->addListener(this); // ambiguous function.
// ((EventDispatcher<PropertyChangeEvent> *)dispatcher)->addListener(this); // works but is long.
LISTEN(PropertyChangeEvent, dispatcher, this);
}
}
protected:
void onEvent(EventDispatcher<ActionEvent> *source, std::shared_ptr<ActionEvent> event) {
(void)source;
(void)event;
std::cout << ID << " ActionEvent " << event->actionID << std::endl;
// event->actionID += 5;
// std::cout << " set to " << event->actionID << std::endl;
}
void onEvent(EventDispatcher<PropertyChangeEvent> *source, std::shared_ptr<PropertyChangeEvent> event) {
(void)source;
(void)event;
std::cout << ID << "PropertyChangeEvent" << std::endl;
}
};
int main(int argc, char *argv[]) {
testDispatcher td();
testListener tl1(&td, 1);
testListener tl2(&td, 2);
testListener tl3(&td, 3);
testListener tl4(&td, 4);
td.test();
return 0;
}