Files
QTradeProgram/Sqbase/qeventbus.cpp

191 lines
4.9 KiB
C++
Raw Normal View History

2026-02-25 23:01:42 +08:00
#include "qeventbus.h"
#include <QDebug>
#include <QMetaObject>
#include <QCoreApplication>
QEventBus* QEventBus::instance()
{
static QEventBus* instance = nullptr;
static QMutex mutex;
if (!instance) {
QMutexLocker locker(&mutex);
if (!instance) {
instance = new QEventBus();
}
}
return instance;
}
QEventBus::QEventBus(QObject *parent) : QObject(parent)
{
// 初始化事件总线
qDebug() << "QEventBus initialized";
}
QEventBus::~QEventBus()
{
// 清理所有订阅
m_subscriptions.clear();
m_eventHistory.clear();
}
void QEventBus::publish(const QString& eventType, const QVariant& data, const QString& source)
{
QMutexLocker locker(&m_mutex);
// 创建事件
Event event(eventType, data, source);
// 添加到历史记录
m_eventHistory.prepend(event);
if (m_eventHistory.size() > m_maxHistorySize) {
m_eventHistory.removeLast();
}
// 发布事件信号
emit eventPublished(event);
// 通知订阅者
if (m_subscriptions.contains(eventType)) {
const QList<Subscription>& subscribers = m_subscriptions[eventType];
for (const Subscription& sub : subscribers) {
if (sub.receiver) {
// 使用元对象系统调用方法
QMetaObject::invokeMethod(sub.receiver, sub.method.constData(),
Q_ARG(QVariant, data));
}
}
}
// 也通知通用事件类型订阅者(如果有)
if (m_subscriptions.contains("*")) {
const QList<Subscription>& subscribers = m_subscriptions["*"];
for (const Subscription& sub : subscribers) {
if (sub.receiver) {
QMetaObject::invokeMethod(sub.receiver, sub.method.constData(),
Q_ARG(QString, eventType),
Q_ARG(QVariant, data));
}
}
}
}
void QEventBus::subscribe(const QString& eventType, QObject* receiver, const char* method)
{
if (!receiver || !method) {
qWarning() << "QEventBus: Invalid subscription - receiver or method is null";
return;
}
QMutexLocker locker(&m_mutex);
Subscription sub;
sub.receiver = receiver;
sub.method = QMetaObject::normalizedSignature(method + 1); // 跳过SLOT()的冒号
// 验证方法是否存在
const QMetaObject* meta = receiver->metaObject();
bool methodFound = false;
for (int i = 0; i < meta->methodCount(); ++i) {
QMetaMethod metaMethod = meta->method(i);
if (metaMethod.methodSignature() == sub.method) {
methodFound = true;
break;
}
}
if (!methodFound) {
qWarning() << "QEventBus: Method not found:" << sub.method << "in" << receiver;
return;
}
m_subscriptions[eventType].append(sub);
// 连接销毁信号以自动清理
connect(receiver, &QObject::destroyed, this, [this, receiver, eventType]() {
unsubscribe(eventType, receiver);
});
}
void QEventBus::unsubscribe(const QString& eventType, QObject* receiver)
{
QMutexLocker locker(&m_mutex);
if (m_subscriptions.contains(eventType)) {
QList<Subscription>& subscribers = m_subscriptions[eventType];
for (int i = subscribers.size() - 1; i >= 0; --i) {
if (subscribers[i].receiver == receiver) {
subscribers.removeAt(i);
}
}
// 如果该事件类型没有订阅者了,移除空列表
if (subscribers.isEmpty()) {
m_subscriptions.remove(eventType);
}
}
}
void QEventBus::unsubscribeAll(QObject* receiver)
{
QMutexLocker locker(&m_mutex);
QList<QString> eventTypes = m_subscriptions.keys();
for (const QString& eventType : eventTypes) {
unsubscribe(eventType, receiver);
}
}
QList<Event> QEventBus::getEventHistory(const QString& type, int limit) const
{
QMutexLocker locker(&m_mutex);
QList<Event> result;
int count = 0;
for (const Event& event : m_eventHistory) {
if (type.isEmpty() || event.type == type) {
result.append(event);
count++;
if (count >= limit) break;
}
}
return result;
}
void QEventBus::clearEventHistory()
{
QMutexLocker locker(&m_mutex);
m_eventHistory.clear();
}
int QEventBus::getEventCount(const QString& type) const
{
QMutexLocker locker(&m_mutex);
if (type.isEmpty()) {
return m_eventHistory.size();
}
int count = 0;
for (const Event& event : m_eventHistory) {
if (event.type == type) {
count++;
}
}
return count;
}
QMap<QString, int> QEventBus::getEventStatistics() const
{
QMutexLocker locker(&m_mutex);
QMap<QString, int> stats;
for (const Event& event : m_eventHistory) {
stats[event.type]++;
}
return stats;
}