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/python/intern/bpy_app_handlers.c')
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c475
1 files changed, 238 insertions, 237 deletions
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index c91c0d69a16..7134bf520ac 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -40,40 +40,42 @@ void bpy_app_generic_callback(struct Main *main, struct ID *id, void *arg);
static PyTypeObject BlenderAppCbType;
static PyStructSequence_Field app_cb_info_fields[] = {
- {(char *)"frame_change_pre", (char *)"on frame change for playback and rendering (before)"},
- {(char *)"frame_change_post", (char *)"on frame change for playback and rendering (after)"},
- {(char *)"render_pre", (char *)"on render (before)"},
- {(char *)"render_post", (char *)"on render (after)"},
- {(char *)"render_write", (char *)"on writing a render frame (directly after the frame is written)"},
- {(char *)"render_stats", (char *)"on printing render statistics"},
- {(char *)"render_init", (char *)"on initialization of a render job"},
- {(char *)"render_complete", (char *)"on completion of render job"},
- {(char *)"render_cancel", (char *)"on canceling a render job"},
- {(char *)"load_pre", (char *)"on loading a new blend file (before)"},
- {(char *)"load_post", (char *)"on loading a new blend file (after)"},
- {(char *)"save_pre", (char *)"on saving a blend file (before)"},
- {(char *)"save_post", (char *)"on saving a blend file (after)"},
- {(char *)"undo_pre", (char *)"on loading an undo step (before)"},
- {(char *)"undo_post", (char *)"on loading an undo step (after)"},
- {(char *)"redo_pre", (char *)"on loading a redo step (before)"},
- {(char *)"redo_post", (char *)"on loading a redo step (after)"},
- {(char *)"depsgraph_update_pre", (char *)"on depsgraph update (pre)"},
- {(char *)"depsgraph_update_post", (char *)"on depsgraph update (post)"},
- {(char *)"version_update", (char *)"on ending the versioning code"},
- {(char *)"load_factory_startup_post", (char *)"on loading factory startup (after)"},
-
- /* sets the permanent tag */
+ {(char *)"frame_change_pre", (char *)"on frame change for playback and rendering (before)"},
+ {(char *)"frame_change_post", (char *)"on frame change for playback and rendering (after)"},
+ {(char *)"render_pre", (char *)"on render (before)"},
+ {(char *)"render_post", (char *)"on render (after)"},
+ {(char *)"render_write",
+ (char *)"on writing a render frame (directly after the frame is written)"},
+ {(char *)"render_stats", (char *)"on printing render statistics"},
+ {(char *)"render_init", (char *)"on initialization of a render job"},
+ {(char *)"render_complete", (char *)"on completion of render job"},
+ {(char *)"render_cancel", (char *)"on canceling a render job"},
+ {(char *)"load_pre", (char *)"on loading a new blend file (before)"},
+ {(char *)"load_post", (char *)"on loading a new blend file (after)"},
+ {(char *)"save_pre", (char *)"on saving a blend file (before)"},
+ {(char *)"save_post", (char *)"on saving a blend file (after)"},
+ {(char *)"undo_pre", (char *)"on loading an undo step (before)"},
+ {(char *)"undo_post", (char *)"on loading an undo step (after)"},
+ {(char *)"redo_pre", (char *)"on loading a redo step (before)"},
+ {(char *)"redo_post", (char *)"on loading a redo step (after)"},
+ {(char *)"depsgraph_update_pre", (char *)"on depsgraph update (pre)"},
+ {(char *)"depsgraph_update_post", (char *)"on depsgraph update (post)"},
+ {(char *)"version_update", (char *)"on ending the versioning code"},
+ {(char *)"load_factory_startup_post", (char *)"on loading factory startup (after)"},
+
+/* sets the permanent tag */
#define APP_CB_OTHER_FIELDS 1
- {(char *)"persistent", (char *)"Function decorator for callback functions not to be removed when loading new files"},
+ {(char *)"persistent",
+ (char *)"Function decorator for callback functions not to be removed when loading new files"},
- {NULL},
+ {NULL},
};
static PyStructSequence_Desc app_cb_info_desc = {
- (char *)"bpy.app.handlers", /* name */
- (char *)"This module contains callback lists", /* doc */
- app_cb_info_fields, /* fields */
- ARRAY_SIZE(app_cb_info_fields) - 1,
+ (char *)"bpy.app.handlers", /* name */
+ (char *)"This module contains callback lists", /* doc */
+ app_cb_info_fields, /* fields */
+ ARRAY_SIZE(app_cb_info_fields) - 1,
};
#if 0
@@ -86,251 +88,250 @@ static PyStructSequence_Desc app_cb_info_desc = {
/* permanent tagging code */
#define PERMINENT_CB_ID "_bpy_persistent"
-static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *UNUSED(kwds))
+static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type),
+ PyObject *args,
+ PyObject *UNUSED(kwds))
{
- PyObject *value;
-
- if (!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value)) {
- return NULL;
- }
-
- if (PyFunction_Check(value)) {
- PyObject **dict_ptr = _PyObject_GetDictPtr(value);
- if (dict_ptr == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "bpy.app.handlers.persistent wasn't able to "
- "get the dictionary from the function passed");
- return NULL;
- }
- else {
- /* set id */
- if (*dict_ptr == NULL) {
- *dict_ptr = PyDict_New();
- }
-
- PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None);
- }
-
- Py_INCREF(value);
- return value;
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "bpy.app.handlers.persistent expected a function");
- return NULL;
- }
+ PyObject *value;
+
+ if (!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value)) {
+ return NULL;
+ }
+
+ if (PyFunction_Check(value)) {
+ PyObject **dict_ptr = _PyObject_GetDictPtr(value);
+ if (dict_ptr == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "bpy.app.handlers.persistent wasn't able to "
+ "get the dictionary from the function passed");
+ return NULL;
+ }
+ else {
+ /* set id */
+ if (*dict_ptr == NULL) {
+ *dict_ptr = PyDict_New();
+ }
+
+ PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None);
+ }
+
+ Py_INCREF(value);
+ return value;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError, "bpy.app.handlers.persistent expected a function");
+ return NULL;
+ }
}
/* dummy type because decorators can't be PyCFunctions */
static PyTypeObject BPyPersistent_Type = {
#if defined(_MSC_VER)
- PyVarObject_HEAD_INIT(NULL, 0)
+ PyVarObject_HEAD_INIT(NULL, 0)
#else
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
#endif
- "persistent", /* tp_name */
- 0, /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- 0, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_BASETYPE, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- bpy_app_handlers_persistent_new, /* tp_new */
- 0, /* tp_free */
+ "persistent", /* tp_name */
+ 0, /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ bpy_app_handlers_persistent_new, /* tp_new */
+ 0, /* tp_free */
};
static PyObject *py_cb_array[BLI_CB_EVT_TOT] = {NULL};
static PyObject *make_app_cb_info(void)
{
- PyObject *app_cb_info;
- int pos;
-
- app_cb_info = PyStructSequence_New(&BlenderAppCbType);
- if (app_cb_info == NULL) {
- return NULL;
- }
-
- for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
- if (app_cb_info_fields[pos].name == NULL) {
- Py_FatalError("invalid callback slots 1");
- }
- PyStructSequence_SET_ITEM(app_cb_info, pos, (py_cb_array[pos] = PyList_New(0)));
- }
- if (app_cb_info_fields[pos + APP_CB_OTHER_FIELDS].name != NULL) {
- Py_FatalError("invalid callback slots 2");
- }
-
- /* custom function */
- PyStructSequence_SET_ITEM(app_cb_info, pos++, (PyObject *)&BPyPersistent_Type);
-
- return app_cb_info;
+ PyObject *app_cb_info;
+ int pos;
+
+ app_cb_info = PyStructSequence_New(&BlenderAppCbType);
+ if (app_cb_info == NULL) {
+ return NULL;
+ }
+
+ for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
+ if (app_cb_info_fields[pos].name == NULL) {
+ Py_FatalError("invalid callback slots 1");
+ }
+ PyStructSequence_SET_ITEM(app_cb_info, pos, (py_cb_array[pos] = PyList_New(0)));
+ }
+ if (app_cb_info_fields[pos + APP_CB_OTHER_FIELDS].name != NULL) {
+ Py_FatalError("invalid callback slots 2");
+ }
+
+ /* custom function */
+ PyStructSequence_SET_ITEM(app_cb_info, pos++, (PyObject *)&BPyPersistent_Type);
+
+ return app_cb_info;
}
PyObject *BPY_app_handlers_struct(void)
{
- PyObject *ret;
+ PyObject *ret;
#if defined(_MSC_VER)
- BPyPersistent_Type.ob_base.ob_base.ob_type = &PyType_Type;
+ BPyPersistent_Type.ob_base.ob_base.ob_type = &PyType_Type;
#endif
- if (PyType_Ready(&BPyPersistent_Type) < 0) {
- BLI_assert(!"error initializing 'bpy.app.handlers.persistent'");
- }
+ if (PyType_Ready(&BPyPersistent_Type) < 0) {
+ BLI_assert(!"error initializing 'bpy.app.handlers.persistent'");
+ }
- PyStructSequence_InitType(&BlenderAppCbType, &app_cb_info_desc);
+ PyStructSequence_InitType(&BlenderAppCbType, &app_cb_info_desc);
- ret = make_app_cb_info();
+ ret = make_app_cb_info();
- /* prevent user from creating new instances */
- BlenderAppCbType.tp_init = NULL;
- BlenderAppCbType.tp_new = NULL;
- BlenderAppCbType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
+ /* prevent user from creating new instances */
+ BlenderAppCbType.tp_init = NULL;
+ BlenderAppCbType.tp_new = NULL;
+ BlenderAppCbType.tp_hash = (hashfunc)
+ _Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
- /* assign the C callbacks */
- if (ret) {
- static bCallbackFuncStore funcstore_array[BLI_CB_EVT_TOT] = {{NULL}};
- bCallbackFuncStore *funcstore;
- int pos = 0;
+ /* assign the C callbacks */
+ if (ret) {
+ static bCallbackFuncStore funcstore_array[BLI_CB_EVT_TOT] = {{NULL}};
+ bCallbackFuncStore *funcstore;
+ int pos = 0;
- for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
- funcstore = &funcstore_array[pos];
- funcstore->func = bpy_app_generic_callback;
- funcstore->alloc = 0;
- funcstore->arg = POINTER_FROM_INT(pos);
- BLI_callback_add(funcstore, pos);
- }
- }
+ for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
+ funcstore = &funcstore_array[pos];
+ funcstore->func = bpy_app_generic_callback;
+ funcstore->alloc = 0;
+ funcstore->arg = POINTER_FROM_INT(pos);
+ BLI_callback_add(funcstore, pos);
+ }
+ }
- return ret;
+ return ret;
}
void BPY_app_handlers_reset(const short do_all)
{
- PyGILState_STATE gilstate;
- int pos = 0;
-
- gilstate = PyGILState_Ensure();
-
- if (do_all) {
- for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
- /* clear list */
- PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL);
- }
- }
- else {
- /* save string conversion thrashing */
- PyObject *perm_id_str = PyUnicode_FromString(PERMINENT_CB_ID);
-
- for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
- /* clear only items without PERMINENT_CB_ID */
- PyObject *ls = py_cb_array[pos];
- Py_ssize_t i;
-
- PyObject *item;
- PyObject **dict_ptr;
-
- for (i = PyList_GET_SIZE(ls) - 1; i >= 0; i--) {
-
- if ((PyFunction_Check((item = PyList_GET_ITEM(ls, i)))) &&
- (dict_ptr = _PyObject_GetDictPtr(item)) &&
- (*dict_ptr) &&
- (PyDict_GetItem(*dict_ptr, perm_id_str) != NULL))
- {
- /* keep */
- }
- else {
- /* remove */
- /* PySequence_DelItem(ls, i); */ /* more obvious buw slower */
- PyList_SetSlice(ls, i, i + 1, NULL);
- }
- }
- }
-
- Py_DECREF(perm_id_str);
- }
-
- PyGILState_Release(gilstate);
+ PyGILState_STATE gilstate;
+ int pos = 0;
+
+ gilstate = PyGILState_Ensure();
+
+ if (do_all) {
+ for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
+ /* clear list */
+ PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL);
+ }
+ }
+ else {
+ /* save string conversion thrashing */
+ PyObject *perm_id_str = PyUnicode_FromString(PERMINENT_CB_ID);
+
+ for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
+ /* clear only items without PERMINENT_CB_ID */
+ PyObject *ls = py_cb_array[pos];
+ Py_ssize_t i;
+
+ PyObject *item;
+ PyObject **dict_ptr;
+
+ for (i = PyList_GET_SIZE(ls) - 1; i >= 0; i--) {
+
+ if ((PyFunction_Check((item = PyList_GET_ITEM(ls, i)))) &&
+ (dict_ptr = _PyObject_GetDictPtr(item)) && (*dict_ptr) &&
+ (PyDict_GetItem(*dict_ptr, perm_id_str) != NULL)) {
+ /* keep */
+ }
+ else {
+ /* remove */
+ /* PySequence_DelItem(ls, i); */ /* more obvious buw slower */
+ PyList_SetSlice(ls, i, i + 1, NULL);
+ }
+ }
+ }
+
+ Py_DECREF(perm_id_str);
+ }
+
+ PyGILState_Release(gilstate);
}
/* the actual callback - not necessarily called from py */
void bpy_app_generic_callback(struct Main *UNUSED(main), struct ID *id, 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 */
- 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));
- }
- else {
- PyTuple_SET_ITEM(args, 0, Py_INCREF_RET(Py_None));
- }
-
- /* 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);
- ret = PyObject_Call(func, args, NULL);
- if (ret == NULL) {
- /* Don't set last system variables because they might cause some
- * dangling pointers to external render engines (when exception
- * happens during rendering) which will break logic of render pipeline
- * which expects to be the only user of render engine when rendering
- * is finished.
- */
- PyErr_PrintEx(0);
- PyErr_Clear();
- }
- else {
- Py_DECREF(ret);
- }
- }
-
- Py_DECREF(args);
-
- PyGILState_Release(gilstate);
- }
+ 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 */
+ 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));
+ }
+ else {
+ PyTuple_SET_ITEM(args, 0, Py_INCREF_RET(Py_None));
+ }
+
+ /* 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);
+ ret = PyObject_Call(func, args, NULL);
+ if (ret == NULL) {
+ /* Don't set last system variables because they might cause some
+ * dangling pointers to external render engines (when exception
+ * happens during rendering) which will break logic of render pipeline
+ * which expects to be the only user of render engine when rendering
+ * is finished.
+ */
+ PyErr_PrintEx(0);
+ PyErr_Clear();
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ }
+
+ Py_DECREF(args);
+
+ PyGILState_Release(gilstate);
+ }
}