Files
2026-02-01 22:23:06 +08:00

118 lines
2.4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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();
}
}