1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#ifndef EVENTCALLPROXY_H
6#define EVENTCALLPROXY_H
7
8#include "framework/event/event.h"
9#include "framework/event/eventhandler.h"
10#include "framework/log/frameworklog.h"
11
12#include <QObject>
13#include <QMutex>
14#include <QDebug>
15
16#include <functional>
17#include <memory>
18
19
20DPF_BEGIN_NAMESPACE
21class EventCallProxy final
22{
23 template <typename T>
24 friend class AutoEventHandlerRegister;
25 struct HandlerInfo;
26 using CreateFunc = std::function<QSharedPointer<EventHandler>()> ;
27 using ExportFunc = std::function<void(HandlerInfo &info, const Event &event)>;
28
29 struct HandlerInfo
30 {
31 QSharedPointer<EventHandler> handler;
32 ExportFunc invoke;
33 QStringList topics;
34 QFuture<void> future;
35 };
36
37public:
38 static EventCallProxy &instance();
39 bool pubEvent(const Event& event);
40
41private:
42 static void registerHandler(EventHandler::Type type, const QStringList &topics, CreateFunc creator);
43 static QList<HandlerInfo> &getInfoList();
44 static void fillInfo(HandlerInfo &info, CreateFunc creator);
45 static QMutex *eventMutex();
46};
47
48// auto register all event handler
49template <typename T>
50class AutoEventHandlerRegister
51{
52public:
53 AutoEventHandlerRegister()
54 {
55 // must keep it!!!
56 // Otherwise `trigger` will not be called !
57 qDebug() << isRegistered;
58 }
59
60 static bool trigger();
61
62private:
63 static bool isRegistered;
64};
65
66// for example:
67
68/*!
69 * class WindowEventHandler: public EventHandler, AutoEventHandlerRegister<WindowEventHandler>
70 * {
71 * Q_OBJECT
72 *
73 * public:
74 * WindowEventHandler(): AutoEventHandlerRegister<WindowEventHandler>() {}
75 *
76 * static EventHandler::Type type()
77 * {
78 * return EventHandler::Type::Sync;
79 * }
80 *
81 * static QStringList topics()
82 * {
83 * return QStringList() << "WindowEvent";
84 * }
85 * };
86 */
87
88
89template <typename T>
90bool AutoEventHandlerRegister<T>::isRegistered = AutoEventHandlerRegister<T>::trigger();
91template <typename T>
92bool AutoEventHandlerRegister<T>::trigger()
93{
94 EventCallProxy::registerHandler(T::type(), T::topics(), [] { return QSharedPointer<T>(new T()); });
95 return true;
96}
97
98DPF_END_NAMESPACE
99
100#endif // EVENTCALLPROXY_H
101