1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
2 | // |
3 | // SPDX-License-Identifier: GPL-3.0-or-later |
4 | |
5 | #ifndef EVENT_H |
6 | #define EVENT_H |
7 | |
8 | #include "framework/framework_global.h" |
9 | |
10 | #include <QString> |
11 | #include <QVector> |
12 | #include <QVariant> |
13 | #include <QSharedData> |
14 | |
15 | DPF_BEGIN_NAMESPACE |
16 | |
17 | class EventPrivate; |
18 | |
19 | /** |
20 | * @brief The Event class |
21 | * 事件数据源,只能当做类使用不可继承 |
22 | * 禁止被继承 |
23 | */ |
24 | class Event final |
25 | { |
26 | EventPrivate *d; |
27 | friend Q_CORE_EXPORT QDebug operator <<(QDebug, const Event &); |
28 | |
29 | public: |
30 | Event(); |
31 | explicit Event(const QString &topic); |
32 | explicit Event(const Event& event); |
33 | ~Event(); |
34 | Event &operator =(const Event &); |
35 | |
36 | void setTopic(const QString &topic); |
37 | QString topic() const; |
38 | |
39 | void setData(const QVariant &data); |
40 | QVariant data() const; |
41 | |
42 | void setProperty(const QString& key, const QVariant value); |
43 | QVariant property(const QString &key) const; |
44 | }; |
45 | |
46 | QT_BEGIN_NAMESPACE |
47 | #ifndef QT_NO_DEBUG_STREAM |
48 | Q_CORE_EXPORT QDebug operator <<(QDebug, const DPF_NAMESPACE::Event &); |
49 | #endif //QT_NO_DEBUG_STREAM |
50 | QT_END_NAMESPACE |
51 | |
52 | struct EventInterface : std::function<void(const QVector<QVariant> &)> |
53 | { |
54 | QString name; |
55 | QVector<QString> pKeys; |
56 | typedef QVariant Arg; |
57 | typedef const QVariant cArg; |
58 | typedef QVector<QVariant> Args; |
59 | EventInterface() = delete; |
60 | |
61 | EventInterface(const QString &name, const QVector<QString> &keys, |
62 | const std::function<void(const QVector<QVariant>&)> &func) |
63 | : std::function<void (const QVector<QVariant> &)> (func), name(name), pKeys(keys) {} |
64 | |
65 | void operator()(const Args &as) const { |
66 | return std::function<void(const QVector<QVariant> &)>::operator()(as); |
67 | } |
68 | |
69 | void operator()() const { operator()(Args{}); } |
70 | |
71 | template<class T0> |
72 | void operator()(const T0 &v0) const { operator()(Args{ Arg::fromValue<T0>(v0) }); } |
73 | |
74 | template<class T0, class T1> |
75 | void operator()(const T0 &v0, const T1 &v1) const { |
76 | operator()(Args{ Arg::fromValue<T0>(v0), Arg::fromValue<T1>(v1) }); |
77 | } |
78 | |
79 | template<class T0, class T1, class T2> |
80 | void operator()(const T0 &v0, const T1 &v1, const T2 &v2) const { |
81 | operator()(Args{ |
82 | Arg::fromValue<T0>(v0), Arg::fromValue<T1>(v1), |
83 | Arg::fromValue<T2>(v2) |
84 | }); |
85 | } |
86 | |
87 | template<class T0, class T1, class T2, class T3> |
88 | void operator()(const T0 &v0, const T1 &v1, const T2 &v2, const T3 &v3) const { |
89 | operator()(Args{ |
90 | Arg::fromValue<T0>(v0), Arg::fromValue<T1>(v1), |
91 | Arg::fromValue<T2>(v2), Arg::fromValue<T3>(v3) |
92 | }); |
93 | } |
94 | |
95 | template<class T0, class T1, class T2, class T3, class T4> |
96 | void operator()(const T0 &v0, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) const { |
97 | operator()(Args{ |
98 | Arg::fromValue<T0>(v0), Arg::fromValue<T1>(v1), |
99 | Arg::fromValue<T2>(v2), Arg::fromValue<T3>(v3), |
100 | Arg::fromValue<T4>(v4) |
101 | }); |
102 | } |
103 | |
104 | template<class T0, class T1, class T2, class T3, class T4, class T5> |
105 | void operator()(const T0 &v0, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, |
106 | const T5 &v5) const { |
107 | operator()(Args{ |
108 | Arg::fromValue<T0>(v0), Arg::fromValue<T1>(v1), |
109 | Arg::fromValue<T2>(v2), Arg::fromValue<T3>(v3), |
110 | Arg::fromValue<T4>(v4), Arg::fromValue<T5>(v5) |
111 | }); |
112 | } |
113 | |
114 | template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> |
115 | void operator()(const T0 &v0, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, |
116 | const T5 &v5, const T6 &v6) const { |
117 | operator()(Args{ |
118 | Arg::fromValue<T0>(v0), Arg::fromValue<T1>(v1), |
119 | Arg::fromValue<T2>(v2), Arg::fromValue<T3>(v3), |
120 | Arg::fromValue<T4>(v4), Arg::fromValue<T5>(v5), |
121 | Arg::fromValue<T6>(v6) |
122 | }); |
123 | } |
124 | |
125 | template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7> |
126 | void operator()(const T0 &v0, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, |
127 | const T5 &v5, const T6 &v6, const T7 &v7) const { |
128 | operator()(Args{ |
129 | Arg::fromValue<T0>(v0), Arg::fromValue<T1>(v1), |
130 | Arg::fromValue<T2>(v2), Arg::fromValue<T3>(v3), |
131 | Arg::fromValue<T4>(v4), Arg::fromValue<T5>(v5), |
132 | Arg::fromValue<T6>(v6), Arg::fromValue<T7>(v7) |
133 | }); |
134 | } |
135 | |
136 | template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8> |
137 | void operator()(const T0 &v0, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, |
138 | const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8) const{ |
139 | operator()(Args{ |
140 | Arg::fromValue<T0>(v0), Arg::fromValue<T1>(v1), |
141 | Arg::fromValue<T2>(v2), Arg::fromValue<T3>(v3), |
142 | Arg::fromValue<T4>(v4), Arg::fromValue<T5>(v5), |
143 | Arg::fromValue<T6>(v6), Arg::fromValue<T7>(v7), |
144 | Arg::fromValue<T8>(v8), |
145 | }); |
146 | } |
147 | |
148 | template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9> |
149 | void operator()(const T0 &v0, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, |
150 | const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9) const { |
151 | operator()(Args{ |
152 | Arg::fromValue<T0>(v0), Arg::fromValue<T1>(v1), |
153 | Arg::fromValue<T2>(v2), Arg::fromValue<T3>(v3), |
154 | Arg::fromValue<T4>(v4), Arg::fromValue<T5>(v5), |
155 | Arg::fromValue<T6>(v6), Arg::fromValue<T7>(v7), |
156 | Arg::fromValue<T8>(v8), Arg::fromValue<T9>(v9) |
157 | }); |
158 | } |
159 | }; |
160 | |
161 | /** |
162 | * @brief The OPI_OBJECT macro |
163 | * Declare and define topic scope |
164 | * |
165 | * @brief The OPI_INTERFACE macro |
166 | * Declare and define call event interface |
167 | * |
168 | * @details |
169 | * Usage: |
170 | * Call mode: |
171 | * The interface implemented by the functor will be encapsulated for the time sending interface, |
172 | * for send event package: |
173 | * Event { |
174 | * topic : "collaborators" |
175 | * data : "openRepos" |
176 | * property { "workspace": "/usr/home/test" } |
177 | * }; |
178 | * Usage: |
179 | * |
180 | * First: The receiver of eventHandler needs to be implemented in the plugin, |
181 | * abstract interface file in eventhandler.h/.cpp |
182 | * |
183 | * Second: Decl from send event interface to any file. (If you are cross plug-in event call, |
184 | * I recommend you define it in the header file that can be referenced by multiple plug-ins.) |
185 | * @code |
186 | * OPI_OBJECT(collaborators, |
187 | * OPI_INTERFACE(openRepos, "workspace") |
188 | * ) |
189 | * @endcode |
190 | * |
191 | * Third: call event: |
192 | * @code |
193 | * collaborators.openRepos("/usr/home/test"); |
194 | * @endcode |
195 | * |
196 | */ |
197 | #define OPI_ASKEEP(pKeys, pVals) if (pKeys.size() != pVals.size()) { qCritical() << "Key value pair length mismatch"; abort(); } |
198 | #define OPI_OBJECT(t, logics) inline const struct { const QString topic{#t} ; logics }t; |
199 | #define OPI_INTERFACE(d, ...) const dpf::EventInterface d { #d, {__VA_ARGS__} , [=](const QVector<QVariant> &args) -> void {\ |
200 | OPI_ASKEEP(d.pKeys, args);\ |
201 | dpf::Event event(topic); event.setData(#d);\ |
202 | for ( int idx = 0; idx < d.pKeys.size(); idx ++) { event.setProperty(d.pKeys[idx], args[idx]); }\ |
203 | dpf::EventCallProxy::instance().pubEvent(event);\ |
204 | }}; |
205 | |
206 | DPF_END_NAMESPACE |
207 | |
208 | #endif // EVENT_H |
209 | |