[Bf-blender-cvs] [01d5d28] master: Py-Driver: re-use self PyObject when its unchanged.

Campbell Barton noreply at git.blender.org
Sun Jul 31 03:44:53 CEST 2016


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__ */




More information about the Bf-blender-cvs mailing list