Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/callbacks.c')
-rw-r--r--source/blender/blenkernel/intern/callbacks.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/source/blender/blenkernel/intern/callbacks.c b/source/blender/blenkernel/intern/callbacks.c
index dbc213907ac..72dd51a940d 100644
--- a/source/blender/blenkernel/intern/callbacks.c
+++ b/source/blender/blenkernel/intern/callbacks.c
@@ -30,11 +30,20 @@
static ListBase callback_slots[BKE_CB_EVT_TOT] = {{NULL}};
+static bool callbacks_initialized = false;
+
+#define ASSERT_CALLBACKS_INITIALIZED() \
+ BLI_assert_msg(callbacks_initialized, \
+ "Callbacks should be initialized with BKE_callback_global_init() before using " \
+ "the callback system.")
+
void BKE_callback_exec(struct Main *bmain,
struct PointerRNA **pointers,
const int num_pointers,
eCbEvent evt)
{
+ ASSERT_CALLBACKS_INITIALIZED();
+
/* Use mutable iteration so handlers are able to remove themselves. */
ListBase *lb = &callback_slots[evt];
LISTBASE_FOREACH_MUTABLE (bCallbackFuncStore *, funcstore, lb) {
@@ -75,18 +84,26 @@ void BKE_callback_exec_id_depsgraph(struct Main *bmain,
void BKE_callback_add(bCallbackFuncStore *funcstore, eCbEvent evt)
{
+ ASSERT_CALLBACKS_INITIALIZED();
ListBase *lb = &callback_slots[evt];
BLI_addtail(lb, funcstore);
}
void BKE_callback_remove(bCallbackFuncStore *funcstore, eCbEvent evt)
{
- ListBase *lb = &callback_slots[evt];
-
- /* Be safe, as the callback may have already been removed by BKE_callback_global_finalize(), for
+ /* The callback may have already been removed by BKE_callback_global_finalize(), for
* example when removing callbacks in response to a BKE_blender_atexit_register callback
* function. `BKE_blender_atexit()` runs after `BKE_callback_global_finalize()`. */
- BLI_remlink_safe(lb, funcstore);
+ if (!callbacks_initialized) {
+ return;
+ }
+
+ ListBase *lb = &callback_slots[evt];
+
+ /* Be noisy about potential programming errors. */
+ BLI_assert_msg(BLI_findindex(lb, funcstore) != -1, "To-be-removed callback not found");
+
+ BLI_remlink(lb, funcstore);
if (funcstore->alloc) {
MEM_freeN(funcstore);
@@ -95,7 +112,7 @@ void BKE_callback_remove(bCallbackFuncStore *funcstore, eCbEvent evt)
void BKE_callback_global_init(void)
{
- /* do nothing */
+ callbacks_initialized = true;
}
/* call on application exit */
@@ -111,4 +128,6 @@ void BKE_callback_global_finalize(void)
BKE_callback_remove(funcstore, evt);
}
}
+
+ callbacks_initialized = false;
}