diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-07-31 04:43:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-07-31 04:46:36 +0300 |
commit | 01d5d2853bbbf07e4b64082e60fbb6d53799ed94 (patch) | |
tree | 74140b6ca832bbaf5ddc1e5812c2bade165a382c /source/blender/python | |
parent | 55f481d05296077e061c2ade989c702c0fd2a68d (diff) |
Py-Driver: re-use self PyObject when its unchanged.
Diffstat (limited to 'source/blender/python')
-rw-r--r-- | source/blender/python/intern/bpy_driver.c | 44 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna_driver.c | 18 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna_driver.h | 2 |
3 files changed, 56 insertions, 8 deletions
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index 82507dcba04..a03c50d8c90 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -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; diff --git a/source/blender/python/intern/bpy_rna_driver.c b/source/blender/python/intern/bpy_rna_driver.c index 98fc372f2fc..b4c0de51c04 100644 --- a/source/blender/python/intern/bpy_rna_driver.c +++ b/source/blender/python/intern/bpy_rna_driver.c @@ -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; +} diff --git a/source/blender/python/intern/bpy_rna_driver.h b/source/blender/python/intern/bpy_rna_driver.h index 2021575537d..3f4bf2b9df5 100644 --- a/source/blender/python/intern/bpy_rna_driver.h +++ b/source/blender/python/intern/bpy_rna_driver.h @@ -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__ */ |