Commit: 01d5d2853bbbf07e4b64082e60fbb6d53799ed94
Author: Campbell Barton
Date:   Sun Jul 31 11:43:24 2016 +1000
Branches: master
https://developer.blender.org/rB01d5d2853bbbf07e4b64082e60fbb6d53799ed94

Py-Driver: re-use self PyObject when its unchanged.

===================================================================

M       source/blender/python/intern/bpy_driver.c
M       source/blender/python/intern/bpy_rna_driver.c
M       source/blender/python/intern/bpy_rna_driver.h

===================================================================

diff --git a/source/blender/python/intern/bpy_driver.c 
b/source/blender/python/intern/bpy_driver.c
index 82507dc..a03c50d 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 98fc372..b4c0de5 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 2021575..3f4bf2b 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__ */

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to