c++事件总线模型

Posted Fireplusplus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++事件总线模型相关的知识,希望对你有一定的参考价值。

什么是事件总线,它是发布-订阅模式的一种实现。最近从事的工作中,就用到一种事件总线机制。

事件发送者将事件发布到一个总线上(抛出事件),订阅者通过在总线上注册(监听总线),达到订阅总线事件的目的。这种模型允许不同的组件或者模块之间以较低的耦合进行通信。

 C++实现的简化版如下:

template <typename EventClass>
class EventBus 
public:
	EventBus() = default;
	~EventBus() = default;

	static void Register(std::weak_ptr<EventClass> event) 
		for (auto& ev : events_) 
			auto ev_ptr = ev.lock();
			auto event_ptr = event.lock();
			if (ev_ptr == event_ptr) 
				INFO("skip exist event!");
				return;
			
		
		events_.emplace_back(event);
	
	
	static void Unregister(std::weak_ptr<EventClass> event) 
		for (auto ev_it = events_.begin(); ev_it != events_.end(); ++ev_it) 
			auto ev_ptr = ev_it->lock();
			auto event_ptr = event.lock();
			if (ev_ptr == event_ptr) 
				events_.erase(ev_it);
				return;
			
		
	

	template<typename EventFun, typename... EventArgs>
	static void OnEvent(EventFun fun, EventArgs&&... args) 
		for (const auto& ev : events_) 
			auto ptr = ev.lock();
			if (!ptr) 
				ERROR("skip not exist event!");
				continue;
			

		 	auto obj = ptr.get();
			(obj->*fun)(args...);
		
	

private:
	static std::list<std::weak_ptr<EventClass>> events_;
;

template <typename EventClass>
std::list<std::weak_ptr<EventClass>> EventBus<EventClass>::events_;

其中Register与Unregister接口供监听者向总线上注册监听,OnEvent接口供事件发送者抛出事件,测试demo如下:

class Base 
public:
	virtual void print(int a) = 0;
;

class Test_One : public std::enable_shared_from_this<Test_One>,
				public Base 
public:
	virtual void print(int a) override 
		printf("This Is Test Print: %d !\\n", a);
	
;

class Test_Two : public std::enable_shared_from_this<Test_Two>,
				public Base 
public:
	virtual void print(int a) override 
		printf("This Is Test2 Print: %d !\\n", a);
	
;


int main(int argc, char *argv[])

	auto ptr1 = std::make_shared<Test_One>();
	auto weak_ptr1 = std::weak_ptr<Base>(ptr1);
	auto ptr2 = std::make_shared<Test_Two>();
	auto weak_ptr2 = std::weak_ptr<Base>(ptr2);
	
	EventBus<Base>::Register(weak_ptr1);
	EventBus<Base>::Register(weak_ptr2);
	
	EventBus<Base>::OnEvent(&Base::print, 123);

	INFO("unregister ptr1");
	EventBus<Base>::Unregister(weak_ptr1);
	EventBus<Base>::OnEvent(&Base::print, 123);

	INFO("unregister ptr2");
	EventBus<Base>::Unregister(weak_ptr2);
	EventBus<Base>::OnEvent(&Base::print, 123);

	return 0;

运行结果:

可以看到在总线上注册的模块,当事件发生时,能够执行该事件对应的动作,这就是简单的总线模型。

附:

源码:GitHub - Fireplusplus/event_bus: simple event bus for c++

以上是关于c++事件总线模型的主要内容,如果未能解决你的问题,请参考以下文章

c++事件总线模型

领域事件

在流分析工作并将它们路由到服务总线之后,事件中心中的事件会发生啥?

从事件总线和消息队列说起

EventBus 事件总线模式实例(发布/订阅事件)

消息总线 vs. 服务总线 vs. 事件中心 vs. 事件网格