[Bf-blender-cvs] [a650258158d] master: Python handlers: Pass depsgraph to events where it makes sense
Sergey Sharybin
noreply at git.blender.org
Wed Sep 11 10:59:16 CEST 2019
Commit: a650258158dd7ad8fa9b6cb1b7da749e30ae15c1
Author: Sergey Sharybin
Date: Mon Sep 9 10:25:04 2019 +0200
Branches: master
https://developer.blender.org/rBa650258158dd7ad8fa9b6cb1b7da749e30ae15c1
Python handlers: Pass depsgraph to events where it makes sense
The goal is to make it possible to access evaluated datablocks at a
corresponding context. For example, be able to check evaluated state
if an object used for rendering.
Allows to write scripts in a safe manner for T63548 and T60094.
Reviewers: brecht
Differential Revision: https://developer.blender.org/D5726
===================================================================
M source/blender/blenkernel/BKE_callbacks.h
M source/blender/blenkernel/intern/callbacks.c
M source/blender/blenkernel/intern/scene.c
M source/blender/editors/undo/ed_undo.c
M source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
M source/blender/python/intern/bpy_app_handlers.c
M source/blender/render/intern/source/pipeline.c
M source/blender/windowmanager/intern/wm_files.c
M source/blender/windowmanager/intern/wm_init_exit.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_callbacks.h b/source/blender/blenkernel/BKE_callbacks.h
index 380ce30668d..e15cf7fed18 100644
--- a/source/blender/blenkernel/BKE_callbacks.h
+++ b/source/blender/blenkernel/BKE_callbacks.h
@@ -21,8 +21,10 @@
#ifndef __BKE_CALLBACKS_H__
#define __BKE_CALLBACKS_H__
+struct Depsgraph;
struct ID;
struct Main;
+struct PointerRNA;
/**
* Common suffix uses:
@@ -59,12 +61,21 @@ typedef enum {
typedef struct bCallbackFuncStore {
struct bCallbackFuncStore *next, *prev;
- void (*func)(struct Main *, struct ID *, void *arg);
+ void (*func)(struct Main *, struct PointerRNA **, const int num_pointers, void *arg);
void *arg;
short alloc;
} bCallbackFuncStore;
-void BKE_callback_exec(struct Main *bmain, struct ID *self, eCbEvent evt);
+void BKE_callback_exec(struct Main *bmain,
+ struct PointerRNA **pointers,
+ const int num_pointers,
+ eCbEvent evt);
+void BKE_callback_exec_null(struct Main *bmain, eCbEvent evt);
+void BKE_callback_exec_id(struct Main *bmain, struct ID *id, eCbEvent evt);
+void BKE_callback_exec_id_depsgraph(struct Main *bmain,
+ struct ID *id,
+ struct Depsgraph *depsgraph,
+ eCbEvent evt);
void BKE_callback_add(bCallbackFuncStore *funcstore, eCbEvent evt);
void BKE_callback_global_init(void);
diff --git a/source/blender/blenkernel/intern/callbacks.c b/source/blender/blenkernel/intern/callbacks.c
index cbecba2efe1..367fed818af 100644
--- a/source/blender/blenkernel/intern/callbacks.c
+++ b/source/blender/blenkernel/intern/callbacks.c
@@ -25,18 +25,55 @@
#include "MEM_guardedalloc.h"
+#include "RNA_types.h"
+#include "RNA_access.h"
+
static ListBase callback_slots[BKE_CB_EVT_TOT] = {{NULL}};
-void BKE_callback_exec(struct Main *bmain, struct ID *self, eCbEvent evt)
+void BKE_callback_exec(struct Main *bmain,
+ struct PointerRNA **pointers,
+ const int num_pointers,
+ eCbEvent evt)
{
ListBase *lb = &callback_slots[evt];
bCallbackFuncStore *funcstore;
for (funcstore = lb->first; funcstore; funcstore = funcstore->next) {
- funcstore->func(bmain, self, funcstore->arg);
+ funcstore->func(bmain, pointers, num_pointers, funcstore->arg);
}
}
+void BKE_callback_exec_null(struct Main *bmain, eCbEvent evt)
+{
+ BKE_callback_exec(bmain, NULL, 0, evt);
+}
+
+void BKE_callback_exec_id(struct Main *bmain, struct ID *id, eCbEvent evt)
+{
+ PointerRNA id_ptr;
+ RNA_id_pointer_create(id, &id_ptr);
+
+ PointerRNA *pointers[1] = {&id_ptr};
+
+ BKE_callback_exec(bmain, pointers, 1, evt);
+}
+
+void BKE_callback_exec_id_depsgraph(struct Main *bmain,
+ struct ID *id,
+ struct Depsgraph *depsgraph,
+ eCbEvent evt)
+{
+ PointerRNA id_ptr;
+ RNA_id_pointer_create(id, &id_ptr);
+
+ PointerRNA depsgraph_ptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, depsgraph, &depsgraph_ptr);
+
+ PointerRNA *pointers[2] = {&id_ptr, &depsgraph_ptr};
+
+ BKE_callback_exec(bmain, pointers, 2, evt);
+}
+
void BKE_callback_add(bCallbackFuncStore *funcstore, eCbEvent evt)
{
ListBase *lb = &callback_slots[evt];
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index aa812dff877..cd10713897a 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1309,7 +1309,7 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
bool run_callbacks = DEG_id_type_any_updated(depsgraph);
if (run_callbacks) {
- BKE_callback_exec(bmain, &scene->id, BKE_CB_EVT_DEPSGRAPH_UPDATE_PRE);
+ BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_DEPSGRAPH_UPDATE_PRE);
}
for (int pass = 0; pass < 2; pass++) {
@@ -1327,7 +1327,8 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
BKE_scene_update_sound(depsgraph, bmain);
/* Notify python about depsgraph update. */
if (run_callbacks) {
- BKE_callback_exec(bmain, &scene->id, BKE_CB_EVT_DEPSGRAPH_UPDATE_POST);
+ BKE_callback_exec_id_depsgraph(
+ bmain, &scene->id, depsgraph, BKE_CB_EVT_DEPSGRAPH_UPDATE_POST);
}
/* Inform editors about possible changes. */
DEG_ids_check_recalc(bmain, depsgraph, scene, view_layer, false);
@@ -1362,7 +1363,7 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
/* Keep this first. */
- BKE_callback_exec(bmain, &scene->id, BKE_CB_EVT_FRAME_CHANGE_PRE);
+ BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_FRAME_CHANGE_PRE);
for (int pass = 0; pass < 2; pass++) {
/* Update animated image textures for particles, modifiers, gpu, etc,
@@ -1384,7 +1385,7 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
/* Notify editors and python about recalc. */
if (pass == 0) {
- BKE_callback_exec(bmain, &scene->id, BKE_CB_EVT_FRAME_CHANGE_POST);
+ BKE_callback_exec_id_depsgraph(bmain, &scene->id, depsgraph, BKE_CB_EVT_FRAME_CHANGE_POST);
}
/* Inform editors about possible changes. */
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index df927726e82..315a4c73e5f 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -172,7 +172,7 @@ static int ed_undo_step_impl(
/* Note: ignore grease pencil for now. */
Main *bmain = CTX_data_main(C);
wm->op_undo_depth++;
- BKE_callback_exec(
+ BKE_callback_exec_id(
bmain, &scene->id, (step_for_callback > 0) ? BKE_CB_EVT_UNDO_PRE : BKE_CB_EVT_REDO_PRE);
wm->op_undo_depth--;
}
@@ -220,7 +220,7 @@ static int ed_undo_step_impl(
Main *bmain = CTX_data_main(C);
scene = CTX_data_scene(C);
wm->op_undo_depth++;
- BKE_callback_exec(
+ BKE_callback_exec_id(
bmain, &scene->id, step_for_callback > 0 ? BKE_CB_EVT_UNDO_POST : BKE_CB_EVT_REDO_POST);
wm->op_undo_depth--;
}
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index afa14d9b1f1..07839ac6e61 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -80,7 +80,10 @@ static AppView *view = NULL;
static FreestyleLineSet lineset_buffer;
static bool lineset_copied = false;
-static void load_post_callback(struct Main * /*main*/, struct ID * /*id*/, void * /*arg*/)
+static void load_post_callback(struct Main * /*main*/,
+ struct PointerRNA ** /*pointers*/,
+ const int /*num_pointers*/,
+ void * /*arg*/)
{
lineset_copied = false;
}
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index 77d036532f4..e6a8febbf29 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -36,7 +36,10 @@
#include "BPY_extern.h"
-void bpy_app_generic_callback(struct Main *main, struct ID *id, void *arg);
+void bpy_app_generic_callback(struct Main *main,
+ struct PointerRNA **pointers,
+ const int num_pointers,
+ void *arg);
static PyTypeObject BlenderAppCbType;
@@ -290,32 +293,58 @@ void BPY_app_handlers_reset(const short do_all)
PyGILState_Release(gilstate);
}
+static PyObject *choose_arguments(PyObject *func, PyObject *args_all, PyObject *args_single)
+{
+ if (!PyFunction_Check(func)) {
+ return args_all;
+ }
+ PyCodeObject *code = (PyCodeObject *)PyFunction_GetCode(func);
+ if (code->co_argcount == 1) {
+ return args_single;
+ }
+ return args_all;
+}
+
/* the actual callback - not necessarily called from py */
-void bpy_app_generic_callback(struct Main *UNUSED(main), struct ID *id, void *arg)
+void bpy_app_generic_callback(struct Main *UNUSED(main),
+ struct PointerRNA **pointers,
+ const int num_pointers,
+ void *arg)
{
PyObject *cb_list = py_cb_array[POINTER_AS_INT(arg)];
if (PyList_GET_SIZE(cb_list) > 0) {
PyGILState_STATE gilstate = PyGILState_Ensure();
- PyObject *args = PyTuple_New(1); /* save python creating each call */
+ const int num_arguments = 2;
+ PyObject *args_all = PyTuple_New(num_arguments); /* save python creating each call */
+ PyObject *args_single = PyTuple_New(1);
PyObject *func;
PyObject *ret;
Py_ssize_t pos;
/* setup arguments */
- if (id) {
- PointerRNA id_ptr;
- RNA_id_pointer_create(id, &id_ptr);
- PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&id_ptr));
+ for (int i = 0; i < num_pointers; ++i) {
+ PyTuple_SET_ITEM(args_all, i, pyrna_struct_CreatePyObject(pointers[i]));
+ }
+ for (int i = num_pointers; i < num_arguments; ++i) {
+ PyTuple_SET_ITEM(args_all, i, Py_INCREF_RET(Py_None));
+ }
+
+ if (num_pointers == 0) {
+ PyTuple_SET_ITEM(args_single, 0, Py_INCREF_RET(Py_None));
+ }
+ else if (num_pointers == 1) {
+ args_single = args_all;
}
else {
- PyTuple_SET_ITEM(args, 0, Py_INCREF_RET(Py_None));
+ PyTuple_SET_ITEM(args_single, 0, pyrna_struct_CreatePyObject(pointers[0]));
}
/* Iterate the list and run the callbacks
* note: don't store the list size since the scripts may remove themselves */
for (pos = 0; pos < PyList_GET_SIZE(cb_list); pos++) {
func = PyList_GET_ITEM(cb_list, pos);
+ PyObject *args = choose_arguments(func, args_all, args_single);
ret = PyObject_Call(func, args, NULL);
if (ret == NULL) {
/* Don't set last system variables because they might cause some
@@ -332,7 +361,
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list