118 lines
2.4 KiB
C++
118 lines
2.4 KiB
C++
#pragma once
|
||
#include <any>
|
||
#include <functional>
|
||
#include <mutex>
|
||
#include <map>
|
||
#include <memory>
|
||
#include <queue>
|
||
#include <thread>
|
||
#include "asio.hpp"
|
||
#include "EventEnum.h"
|
||
|
||
namespace Bus {
|
||
|
||
enum class ExecutionPolicy {
|
||
Main,
|
||
Other
|
||
};
|
||
|
||
/*
|
||
* @brief 不需要看类的实现,为了统一直接看下面的inline函数
|
||
*/
|
||
class DataBus {
|
||
|
||
public:
|
||
|
||
void startIoContext()
|
||
{
|
||
if (!worker_thread_.joinable())
|
||
{
|
||
worker_thread_ = std::thread([this]() {io_context_.run(); });
|
||
|
||
}
|
||
}
|
||
|
||
|
||
void publish(事件 event, const std::any& data)
|
||
{
|
||
std::lock_guard<std::mutex> lock(mutex_);
|
||
for (auto&& [handler,threadType] : subscribers_[event])
|
||
{
|
||
if (threadType == ExecutionPolicy::Main)
|
||
{
|
||
handler(data);
|
||
}
|
||
else if (threadType==ExecutionPolicy::Other) {
|
||
|
||
asio::post(io_context_, [handler, data]() {
|
||
handler(data);
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
void subscribe(事件 event, const std::function< void(const std::any&)>& handler, ExecutionPolicy threadType)
|
||
{
|
||
std::lock_guard<std::mutex> lock(mutex_);
|
||
|
||
subscribers_[event].emplace_back(std::make_pair(handler, threadType));
|
||
}
|
||
|
||
~DataBus() {
|
||
io_context_.stop();
|
||
if (worker_thread_.joinable())
|
||
{
|
||
worker_thread_.join();
|
||
}
|
||
};
|
||
DataBus():work_guard_(asio::make_work_guard(io_context_)){
|
||
|
||
};
|
||
|
||
//预留
|
||
void setMainThreadId(std::thread::id id)
|
||
{
|
||
main_thread_id = id;
|
||
}
|
||
private:
|
||
void runWorker() {}
|
||
|
||
private:
|
||
asio::io_context io_context_;
|
||
asio::executor_work_guard<asio::io_context::executor_type> work_guard_;
|
||
std::map<事件, std::vector<std::pair <std::function<void(std::any)>, ExecutionPolicy>>> subscribers_;
|
||
std::mutex mutex_;
|
||
std::queue<std::function<void()>> task_queue_;
|
||
std::mutex queue_mutex_;
|
||
std::thread worker_thread_;
|
||
std::thread::id main_thread_id; //记录主线程ID
|
||
};
|
||
|
||
|
||
inline std::shared_ptr<DataBus> g_dataBusInstance = nullptr;
|
||
|
||
inline void set_global_data_bus(std::shared_ptr<DataBus> databusPtr)
|
||
{
|
||
g_dataBusInstance = databusPtr;
|
||
}
|
||
|
||
inline void publish(事件 event, const std::any& data)
|
||
{
|
||
g_dataBusInstance->publish( event, data);
|
||
}
|
||
inline void subscribe(事件 event,
|
||
const std::function<void(const std::any&)>& callback,
|
||
ExecutionPolicy threadType= ExecutionPolicy::Main)
|
||
{
|
||
g_dataBusInstance->subscribe(event, callback,threadType);
|
||
}
|
||
|
||
/*
|
||
* @brief有且只能在main.cpp 初始化一次。
|
||
*/
|
||
inline void startIoContext() {
|
||
g_dataBusInstance->startIoContext();
|
||
}
|
||
|
||
|
||
} |