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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2016-07-31 04:43:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-07-31 04:46:36 +0300
commit01d5d2853bbbf07e4b64082e60fbb6d53799ed94 (patch)
tree74140b6ca832bbaf5ddc1e5812c2bade165a382c /source
parent55f481d05296077e061c2ade989c702c0fd2a68d (diff)
Py-Driver: re-use self PyObject when its unchanged.
Diffstat (limited to 'source')
-rw-r--r--source/blender/python/intern/bpy_driver.c44
-rw-r--r--source/blender/python/intern/bpy_rna_driver.c18
-rw-r--r--source/blender/python/intern/bpy_rna_driver.h2
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__ */