Blender  V3.3
callbacks.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "BLI_listbase.h"
8 #include "BLI_utildefines.h"
9 
10 #include "BKE_callbacks.h"
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "RNA_access.h"
15 #include "RNA_prototypes.h"
16 #include "RNA_types.h"
17 
19 
20 static bool callbacks_initialized = false;
21 
22 #define ASSERT_CALLBACKS_INITIALIZED() \
23  BLI_assert_msg(callbacks_initialized, \
24  "Callbacks should be initialized with BKE_callback_global_init() before using " \
25  "the callback system.")
26 
27 void BKE_callback_exec(struct Main *bmain,
28  struct PointerRNA **pointers,
29  const int num_pointers,
30  eCbEvent evt)
31 {
33 
34  /* Use mutable iteration so handlers are able to remove themselves. */
35  ListBase *lb = &callback_slots[evt];
36  LISTBASE_FOREACH_MUTABLE (bCallbackFuncStore *, funcstore, lb) {
37  funcstore->func(bmain, pointers, num_pointers, funcstore->arg);
38  }
39 }
40 
41 void BKE_callback_exec_null(struct Main *bmain, eCbEvent evt)
42 {
43  BKE_callback_exec(bmain, NULL, 0, evt);
44 }
45 
46 void BKE_callback_exec_id(struct Main *bmain, struct ID *id, eCbEvent evt)
47 {
48  PointerRNA id_ptr;
49  RNA_id_pointer_create(id, &id_ptr);
50 
51  PointerRNA *pointers[1] = {&id_ptr};
52 
53  BKE_callback_exec(bmain, pointers, 1, evt);
54 }
55 
57  struct ID *id,
58  struct Depsgraph *depsgraph,
59  eCbEvent evt)
60 {
61  PointerRNA id_ptr;
62  RNA_id_pointer_create(id, &id_ptr);
63 
64  PointerRNA depsgraph_ptr;
65  RNA_pointer_create(NULL, &RNA_Depsgraph, depsgraph, &depsgraph_ptr);
66 
67  PointerRNA *pointers[2] = {&id_ptr, &depsgraph_ptr};
68 
69  BKE_callback_exec(bmain, pointers, 2, evt);
70 }
71 
73 {
75  ListBase *lb = &callback_slots[evt];
76  BLI_addtail(lb, funcstore);
77 }
78 
80 {
81  /* The callback may have already been removed by BKE_callback_global_finalize(), for
82  * example when removing callbacks in response to a BKE_blender_atexit_register callback
83  * function. `BKE_blender_atexit()` runs after `BKE_callback_global_finalize()`. */
84  if (!callbacks_initialized) {
85  return;
86  }
87 
88  ListBase *lb = &callback_slots[evt];
89 
90  /* Be noisy about potential programming errors. */
91  BLI_assert_msg(BLI_findindex(lb, funcstore) != -1, "To-be-removed callback not found");
92 
93  BLI_remlink(lb, funcstore);
94 
95  if (funcstore->alloc) {
96  MEM_freeN(funcstore);
97  }
98 }
99 
101 {
102  callbacks_initialized = true;
103 }
104 
106 {
107  eCbEvent evt;
108  for (evt = 0; evt < BKE_CB_EVT_TOT; evt++) {
109  ListBase *lb = &callback_slots[evt];
110  bCallbackFuncStore *funcstore;
111  bCallbackFuncStore *funcstore_next;
112  for (funcstore = lb->first; funcstore; funcstore = funcstore_next) {
113  funcstore_next = funcstore->next;
114  BKE_callback_remove(funcstore, evt);
115  }
116  }
117 
118  callbacks_initialized = false;
119 }
eCbEvent
Definition: BKE_callbacks.h:74
@ BKE_CB_EVT_TOT
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
Read Guarded memory(de)allocation.
void BKE_callback_add(bCallbackFuncStore *funcstore, eCbEvent evt)
Definition: callbacks.c:72
void BKE_callback_exec_id_depsgraph(struct Main *bmain, struct ID *id, struct Depsgraph *depsgraph, eCbEvent evt)
Definition: callbacks.c:56
static ListBase callback_slots[BKE_CB_EVT_TOT]
Definition: callbacks.c:18
void BKE_callback_global_finalize(void)
Definition: callbacks.c:105
static bool callbacks_initialized
Definition: callbacks.c:20
void BKE_callback_remove(bCallbackFuncStore *funcstore, eCbEvent evt)
Definition: callbacks.c:79
void BKE_callback_exec_null(struct Main *bmain, eCbEvent evt)
Definition: callbacks.c:41
void BKE_callback_exec_id(struct Main *bmain, struct ID *id, eCbEvent evt)
Definition: callbacks.c:46
void BKE_callback_exec(struct Main *bmain, struct PointerRNA **pointers, const int num_pointers, eCbEvent evt)
Definition: callbacks.c:27
void BKE_callback_global_init(void)
Definition: callbacks.c:100
#define ASSERT_CALLBACKS_INITIALIZED()
Definition: callbacks.c:22
const Depsgraph * depsgraph
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
Definition: DNA_ID.h:368
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
struct bCallbackFuncStore * next