Py-Driver: re-use self PyObject when its unchanged.
This commit is contained in:
parent
55f481d052
commit
01d5d2853b
Notes:
blender-bot
2023-02-14 10:14:07 +01:00
Referenced by issue #48988, BBones Ease in/out don´t update the mesh deformation at current frame Referenced by issue #48980, crash when loading a file that contains a custom node tree
|
@ -100,24 +100,48 @@ int bpy_pydriver_create_dict(void)
|
|||
|
||||
/* note, this function should do nothing most runs, only when changing frame */
|
||||
/* not thread safe but neither is python */
|
||||
static float bpy_pydriver_evaltime_prev = FLT_MAX;
|
||||
static struct {
|
||||
float evaltime;
|
||||
|
||||
/* borrowed reference to the 'self' in 'bpy_pydriver_Dict'
|
||||
* keep for as long as the same self is used. */
|
||||
PyObject *self;
|
||||
} g_pydriver_state_prev = {
|
||||
.evaltime = FLT_MAX,
|
||||
.self = NULL,
|
||||
};
|
||||
|
||||
static void bpy_pydriver_namespace_update_frame(const float evaltime)
|
||||
{
|
||||
if (bpy_pydriver_evaltime_prev != evaltime) {
|
||||
if (g_pydriver_state_prev.evaltime != evaltime) {
|
||||
PyObject *item = PyFloat_FromDouble(evaltime);
|
||||
PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_frame, item);
|
||||
Py_DECREF(item);
|
||||
|
||||
bpy_pydriver_evaltime_prev = evaltime;
|
||||
g_pydriver_state_prev.evaltime = evaltime;
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_pydriver_namespace_update_self(struct PathResolvedRNA *anim_rna)
|
||||
{
|
||||
PyObject *item = pyrna_driver_self_from_anim_rna(anim_rna);
|
||||
PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_self, item);
|
||||
Py_DECREF(item);
|
||||
if ((g_pydriver_state_prev.self == NULL) ||
|
||||
(pyrna_driver_is_equal_anim_rna(anim_rna, g_pydriver_state_prev.self) == false))
|
||||
{
|
||||
PyObject *item = pyrna_driver_self_from_anim_rna(anim_rna);
|
||||
PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_self, item);
|
||||
Py_DECREF(item);
|
||||
|
||||
g_pydriver_state_prev.self = item;
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_pydriver_namespace_clear_self(void)
|
||||
{
|
||||
if (g_pydriver_state_prev.self) {
|
||||
PyDict_DelItem(bpy_pydriver_Dict, bpy_intern_str_self);
|
||||
|
||||
g_pydriver_state_prev.self = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update function, it gets rid of pydrivers global dictionary, forcing
|
||||
|
@ -139,7 +163,10 @@ void BPY_driver_reset(void)
|
|||
bpy_pydriver_Dict = NULL;
|
||||
}
|
||||
|
||||
bpy_pydriver_evaltime_prev = FLT_MAX;
|
||||
g_pydriver_state_prev.evaltime = FLT_MAX;
|
||||
|
||||
/* freed when clearing driver dict */
|
||||
g_pydriver_state_prev.self = NULL;
|
||||
|
||||
if (use_gil)
|
||||
PyGILState_Release(gilstate);
|
||||
|
@ -225,6 +252,9 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna, ChannelDriver *driver, c
|
|||
if (driver->flag & DRIVER_FLAG_USE_SELF) {
|
||||
bpy_pydriver_namespace_update_self(anim_rna);
|
||||
}
|
||||
else {
|
||||
bpy_pydriver_namespace_clear_self();
|
||||
}
|
||||
|
||||
if (driver->expr_comp == NULL)
|
||||
driver->flag |= DRIVER_FLAG_RECOMPILE;
|
||||
|
|
|
@ -78,7 +78,23 @@ PyObject *pyrna_driver_get_variable_value(
|
|||
return driver_arg;
|
||||
}
|
||||
|
||||
PyObject *pyrna_driver_self_from_anim_rna(struct PathResolvedRNA *anim_rna)
|
||||
PyObject *pyrna_driver_self_from_anim_rna(PathResolvedRNA *anim_rna)
|
||||
{
|
||||
return pyrna_struct_CreatePyObject(&anim_rna->ptr);
|
||||
}
|
||||
|
||||
bool pyrna_driver_is_equal_anim_rna(const PathResolvedRNA *anim_rna, const PyObject *py_anim_rna)
|
||||
{
|
||||
if (BPy_StructRNA_Check(py_anim_rna)) {
|
||||
const PointerRNA *ptr_a = &anim_rna->ptr;
|
||||
const PointerRNA *ptr_b = &(((const BPy_StructRNA *)py_anim_rna)->ptr);
|
||||
|
||||
if ((ptr_a->id.data == ptr_b->id.data) &&
|
||||
(ptr_a->type == ptr_b->type) &&
|
||||
(ptr_a->data == ptr_b->data))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ struct DriverTarget;
|
|||
struct PathResolvedRNA;
|
||||
|
||||
PyObject *pyrna_driver_get_variable_value(struct ChannelDriver *driver, struct DriverTarget *dtar);
|
||||
|
||||
PyObject *pyrna_driver_self_from_anim_rna(struct PathResolvedRNA *anim_rna);
|
||||
bool pyrna_driver_is_equal_anim_rna(const struct PathResolvedRNA *anim_rna, const PyObject *py_anim_rna);
|
||||
|
||||
#endif /* __BPY_RNA_DRIVER_H__ */
|
||||
|
|
Loading…
Reference in New Issue