return 0;
}
+/* note, this function should do nothing most runs, only when changing frame */
+static PyObject *bpy_pydriver_InternStr__frame= NULL;
+
+static void bpy_pydriver_update_dict(const float evaltime)
+{
+ /* not thread safe but neither is python */
+ static float evaltime_prev= FLT_MAX;
+
+ if (evaltime_prev != evaltime) {
+
+ /* currently only update the frame */
+ if (bpy_pydriver_InternStr__frame == NULL) {
+ bpy_pydriver_InternStr__frame= PyUnicode_FromString("frame");
+ }
+
+ PyDict_SetItem(bpy_pydriver_Dict,
+ bpy_pydriver_InternStr__frame,
+ PyFloat_FromDouble(evaltime));
+
+ evaltime_prev= evaltime;
+ }
+}
+
/* Update function, it gets rid of pydrivers global dictionary, forcing
* BPY_driver_exec to recreate it. This function is used to force
* reloading the Blender text module "pydrivers.py", if available, so
bpy_pydriver_Dict= NULL;
}
+ if (bpy_pydriver_InternStr__frame) {
+ Py_DECREF(bpy_pydriver_InternStr__frame);
+ bpy_pydriver_InternStr__frame= NULL;
+ }
+
if (use_gil)
PyGILState_Release(gilstate);
* now release the GIL on python operator execution instead, using
* PyEval_SaveThread() / PyEval_RestoreThread() so we dont lock up blender.
*/
-float BPY_driver_exec(ChannelDriver *driver)
+float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
{
PyObject *driver_vars=NULL;
PyObject *retval= NULL;
}
}
+ /* update global namespace */
+ bpy_pydriver_update_dict(evaltime);
+
+
if (driver->expr_comp==NULL)
driver->flag |= DRIVER_FLAG_RECOMPILE;
}
}
+
#if 0 // slow, with this can avoid all Py_CompileString above.
/* execute expression to get a value */
retval= PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);