Cleanup: add trailing commas to structs
[blender.git] / source / blender / windowmanager / message_bus / wm_message_bus.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/windowmanager/message_bus/wm_message_bus.h
22  *  \ingroup wm
23  */
24
25 #ifndef __WM_MESSAGE_BUS_H__
26 #define __WM_MESSAGE_BUS_H__
27
28 #include <stdio.h>
29
30 struct GSet;
31 struct ID;
32 struct bContext;
33 struct wmMsg;
34
35 /* opaque (don't expose outside wm_message_bus.c) */
36 struct wmMsgBus;
37 struct wmMsgSubscribeKey;
38 struct wmMsgSubscribeValue;
39 struct wmMsgSubscribeValueLink;
40
41 typedef void (*wmMsgNotifyFn)(
42         struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val);
43 typedef void (*wmMsgSubscribeValueFreeDataFn)(
44         struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val);
45
46 /* Exactly what arguments here is not obvious. */
47 typedef void (*wmMsgSubscribeValueUpdateIdFn)(
48         struct bContext *C,
49         struct wmMsgBus *mbus,
50         struct ID *id_src, struct ID *id_dst,
51         struct wmMsgSubscribeValue *msg_val);
52 enum {
53         WM_MSG_TYPE_RNA = 0,
54         WM_MSG_TYPE_STATIC = 1,
55 };
56 #define WM_MSG_TYPE_NUM 2
57
58 typedef struct wmMsgTypeInfo {
59         struct {
60                 unsigned int (*hash_fn)(const void *msg);
61                 bool         (*cmp_fn)(const void *a, const void *b);
62                 void         (*key_free_fn)(void *key);
63         } gset;
64
65         void (*update_by_id)(struct wmMsgBus *mbus, struct ID *id_src, struct ID *id_dst);
66         void (*remove_by_id)(struct wmMsgBus *mbus, const struct ID *id);
67         void (*repr)(FILE *stream, const struct wmMsgSubscribeKey *msg_key);
68
69         /* sizeof(wmMsgSubscribeKey_*) */
70         uint msg_key_size;
71 } wmMsgTypeInfo;
72
73 typedef struct wmMsg {
74         unsigned int type;
75 // #ifdef DEBUG
76         /* For debugging: '__func__:__LINE__'. */
77         const char *id;
78 // #endif
79 } wmMsg;
80
81 typedef struct wmMsgSubscribeKey {
82         /** Linked list for predicable ordering, otherwise we would depend on ghash bucketing. */
83         struct wmMsgSubscribeKey *next, *prev;
84         ListBase values;
85         /* over-alloc, eg: wmMsgSubscribeKey_RNA */
86         /* Last member will be 'wmMsg_*' */
87 } wmMsgSubscribeKey;
88
89 /** One of many in #wmMsgSubscribeKey.values */
90 typedef struct wmMsgSubscribeValue {
91         struct wmMsgSubscribe *next, *prev;
92
93         /** Handle, used to iterate and clear. */
94         void *owner;
95         /** User data, can be whatever we like, free using the 'free_data' callback if it's owned. */
96         void *user_data;
97
98         /** Callbacks */
99         wmMsgNotifyFn notify;
100         wmMsgSubscribeValueUpdateIdFn update_id;
101         wmMsgSubscribeValueFreeDataFn free_data;
102
103         /** Keep this subscriber if possible. */
104         uint is_persistent : 1;
105         /* tag to run when handling events,
106          * we may want option for immediate execution. */
107         uint tag : 1;
108 } wmMsgSubscribeValue;
109
110 /** One of many in #wmMsgSubscribeKey.values */
111 typedef struct wmMsgSubscribeValueLink {
112         struct wmMsgSubscribeValueLink *next, *prev;
113         wmMsgSubscribeValue params;
114 } wmMsgSubscribeValueLink;
115
116 void WM_msgbus_types_init(void);
117
118 struct wmMsgBus *WM_msgbus_create(void);
119 void             WM_msgbus_destroy(struct wmMsgBus *mbus);
120
121 void WM_msgbus_clear_by_owner(struct wmMsgBus *mbus, void *owner);
122
123 void WM_msg_dump(struct wmMsgBus *mbus, const char *info);
124 void WM_msgbus_handle(struct wmMsgBus *mbus, struct bContext *C);
125
126 void WM_msg_publish_with_key(struct wmMsgBus *mbus, wmMsgSubscribeKey *msg_key);
127 wmMsgSubscribeKey *WM_msg_subscribe_with_key(
128         struct wmMsgBus *mbus,
129         const wmMsgSubscribeKey *msg_key_test,
130         const wmMsgSubscribeValue *msg_val_params);
131
132 void WM_msg_id_update(
133         struct wmMsgBus *mbus,
134         struct ID *id_src, struct ID *id_dst);
135 void WM_msg_id_remove(struct wmMsgBus *mbus, const struct ID *id);
136
137 /* -------------------------------------------------------------------------- */
138 /* wm_message_bus_static.c */
139
140 enum {
141         /* generic window redraw */
142         WM_MSG_STATICTYPE_WINDOW_DRAW = 0,
143         WM_MSG_STATICTYPE_SCREEN_EDIT = 1,
144         WM_MSG_STATICTYPE_FILE_READ = 2,
145 };
146
147 typedef struct wmMsgParams_Static {
148         int event;
149 } wmMsgParams_Static;
150
151 typedef struct wmMsg_Static {
152         wmMsg head;  /* keep first */
153         wmMsgParams_Static params;
154 } wmMsg_Static;
155
156 typedef struct wmMsgSubscribeKey_Static {
157         wmMsgSubscribeKey head;
158         wmMsg_Static msg;
159 } wmMsgSubscribeKey_Static;
160
161 void WM_msgtypeinfo_init_static(wmMsgTypeInfo *msg_type);
162
163 wmMsgSubscribeKey_Static *WM_msg_lookup_static(
164         struct wmMsgBus *mbus, const wmMsgParams_Static *msg_key_params);
165 void WM_msg_publish_static_params(
166         struct wmMsgBus *mbus,
167         const wmMsgParams_Static *msg_key_params);
168 void WM_msg_publish_static(
169         struct wmMsgBus *mbus,
170         /* wmMsgParams_Static (expanded) */
171         int event);
172 void WM_msg_subscribe_static_params(
173         struct wmMsgBus *mbus,
174         const wmMsgParams_Static *msg_key_params,
175         const wmMsgSubscribeValue *msg_val_params,
176         const char *id_repr);
177 void WM_msg_subscribe_static(
178         struct wmMsgBus *mbus,
179         int event,
180         const wmMsgSubscribeValue *msg_val_params,
181         const char *id_repr);
182
183 /* -------------------------------------------------------------------------- */
184 /* wm_message_bus_rna.c */
185
186 typedef struct wmMsgParams_RNA {
187         /** when #PointerRNA.data & id.data are NULL. match against all. */
188         PointerRNA ptr;
189         /** when NULL, match against any property. */
190         const PropertyRNA *prop;
191
192         /**
193          * Optional RNA data path for persistent RNA properties, ignore if NULL.
194          * otherwise it's allocated.
195          */
196         char *data_path;
197 } wmMsgParams_RNA;
198
199 typedef struct wmMsg_RNA {
200         wmMsg head;  /* keep first */
201         wmMsgParams_RNA params;
202 } wmMsg_RNA;
203
204 typedef struct wmMsgSubscribeKey_RNA {
205         wmMsgSubscribeKey head;
206         wmMsg_RNA msg;
207 } wmMsgSubscribeKey_RNA;
208
209 #ifdef __GNUC__
210 #define _WM_MESSAGE_EXTERN_BEGIN \
211         _Pragma("GCC diagnostic push"); \
212         _Pragma("GCC diagnostic ignored \"-Wredundant-decls\"");
213 #define _WM_MESSAGE_EXTERN_END \
214         _Pragma("GCC diagnostic pop");
215 #else
216 #define _WM_MESSAGE_EXTERN_BEGIN
217 #define _WM_MESSAGE_EXTERN_END
218 #endif
219
220 void WM_msgtypeinfo_init_rna(wmMsgTypeInfo *msg_type);
221
222 wmMsgSubscribeKey_RNA *WM_msg_lookup_rna(
223         struct wmMsgBus *mbus, const wmMsgParams_RNA *msg_key_params);
224 void WM_msg_publish_rna_params(
225         struct wmMsgBus *mbus, const wmMsgParams_RNA *msg_key_params);
226 void WM_msg_publish_rna(
227         struct wmMsgBus *mbus,
228         /* wmMsgParams_RNA (expanded) */
229         PointerRNA *ptr, PropertyRNA *prop);
230 void WM_msg_subscribe_rna_params(
231         struct wmMsgBus *mbus,
232         const wmMsgParams_RNA *msg_key_params,
233         const wmMsgSubscribeValue *msg_val_params,
234         const char *id_repr);
235 void WM_msg_subscribe_rna(
236         struct wmMsgBus *mbus,
237         PointerRNA *ptr, const PropertyRNA *prop,
238         const wmMsgSubscribeValue *msg_val_params,
239         const char *id_repr);
240
241 /* ID variants */
242 void WM_msg_subscribe_ID(
243         struct wmMsgBus *mbus, struct ID *id, const wmMsgSubscribeValue *msg_val_params,
244         const char *id_repr);
245 void WM_msg_publish_ID(
246         struct wmMsgBus *mbus, struct ID *id);
247
248 #define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_) { \
249          wmMsgParams_RNA msg_key_params_ = {{{0}}}; \
250         _WM_MESSAGE_EXTERN_BEGIN; \
251         extern PropertyRNA rna_##type_##_##prop_; \
252         _WM_MESSAGE_EXTERN_END; \
253         RNA_pointer_create(id_, &RNA_##type_, data_, &msg_key_params_.ptr); \
254         msg_key_params_.prop = &rna_##type_##_##prop_; \
255         WM_msg_publish_rna_params(mbus, &msg_key_params_); \
256 } ((void)0)
257 #define WM_msg_subscribe_rna_prop(mbus, id_, data_, type_, prop_, value) { \
258         wmMsgParams_RNA msg_key_params_ = {{{0}}}; \
259         _WM_MESSAGE_EXTERN_BEGIN; \
260         extern PropertyRNA rna_##type_##_##prop_; \
261         _WM_MESSAGE_EXTERN_END; \
262         RNA_pointer_create(id_, &RNA_##type_, data_, &msg_key_params_.ptr); \
263         msg_key_params_.prop = &rna_##type_##_##prop_; \
264         WM_msg_subscribe_rna_params(mbus, &msg_key_params_, value, __func__); \
265 } ((void)0)
266
267 /* Anonymous variants (for convenience) */
268 #define WM_msg_subscribe_rna_anon_type(mbus, type_, value) { \
269         WM_msg_subscribe_rna_params( \
270                 mbus, \
271                 &(const wmMsgParams_RNA){ \
272                     .ptr = (PointerRNA){ .type = &RNA_##type_, }, \
273                     .prop = NULL, \
274                 }, \
275                 value, __func__); \
276 } ((void)0)
277 #define WM_msg_subscribe_rna_anon_prop(mbus, type_, prop_, value) { \
278         _WM_MESSAGE_EXTERN_BEGIN; \
279         extern PropertyRNA rna_##type_##_##prop_; \
280         _WM_MESSAGE_EXTERN_END; \
281         WM_msg_subscribe_rna_params( \
282                 mbus, \
283                 &(const wmMsgParams_RNA){ \
284                     .ptr = (PointerRNA){ .type = &RNA_##type_, }, \
285                     .prop = &rna_##type_##_##prop_, \
286                 }, \
287                 value, __func__); \
288 } ((void)0)
289
290 #endif /* __WM_MESSAGE_BUS_H__ */