From 62f79856e9a14337e32355db8a6add14badb372f Mon Sep 17 00:00:00 2001 From: Porteries Tristan Date: Sun, 19 Apr 2015 20:32:14 +0200 Subject: BGE : Standardization of callbacks execution. A new function (RunPythonCallBackList) to call all python functions contained in a python list was developed. This function has: - first argument is the python list of callbacks - second argument is a python list of arguments - third argument is the minimum quantity of arguments - forth argument is the maximum quantity of arguments It improves flexibility and supports *args. Reviewers: moguri, dfelinto, campbellbarton, sybren Reviewed By: campbellbarton, sybren Subscribers: sybren Projects: #game_engine Differential Revision: https://developer.blender.org/D1102 --- source/gameengine/Ketsji/KX_GameObject.cpp | 66 ++++-------------------------- source/gameengine/Ketsji/KX_Scene.cpp | 27 ++---------- 2 files changed, 11 insertions(+), 82 deletions(-) (limited to 'source/gameengine/Ketsji') diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 1536b31d1ba..e464883016e 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -69,6 +69,7 @@ #include "BL_ActionManager.h" #include "BL_Action.h" +#include "KX_PythonCallBack.h" #include "PyObjectPlus.h" /* python stuff */ #include "BLI_utildefines.h" #include "python_utildefines.h" @@ -1565,67 +1566,14 @@ void KX_GameObject::RegisterCollisionCallbacks() void KX_GameObject::RunCollisionCallbacks(KX_GameObject *collider, const MT_Vector3 &point, const MT_Vector3 &normal) { #ifdef WITH_PYTHON - Py_ssize_t len; - PyObject* collision_callbacks = m_collisionCallbacks; - - if (collision_callbacks && (len=PyList_GET_SIZE(collision_callbacks))) - { - // Argument tuples are created lazily, only when they are needed. - PyObject *args_3 = NULL; - PyObject *args_1 = NULL; // Only for compatibility with pre-2.74 callbacks that take 1 argument. - - PyObject *func; - PyObject *ret; - int co_argcount; - - // Iterate the list and run the callbacks - for (Py_ssize_t pos=0; pos < len; pos++) - { - func = PyList_GET_ITEM(collision_callbacks, pos); - - // Get the number of arguments, supporting functions, methods and generic callables. - if (PyMethod_Check(func)) { - // Take away the 'self' argument for methods. - co_argcount = ((PyCodeObject *)PyFunction_GET_CODE(PyMethod_GET_FUNCTION(func)))->co_argcount - 1; - } else if (PyFunction_Check(func)) { - co_argcount = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_argcount; - } else { - // We'll just assume the callable takes the correct number of arguments. - co_argcount = 3; - } - - // Check whether the function expects the colliding object only, - // or also the point and normal. - if (co_argcount <= 1) { - // One argument, or *args (which gives co_argcount == 0) - if (args_1 == NULL) { - args_1 = PyTuple_New(1); - PyTuple_SET_ITEMS(args_1, collider->GetProxy()); - } - ret = PyObject_Call(func, args_1, NULL); - } else { - // More than one argument, assume we can give point & normal. - if (args_3 == NULL) { - args_3 = PyTuple_New(3); - PyTuple_SET_ITEMS(args_3, - collider->GetProxy(), - PyObjectFrom(point), - PyObjectFrom(normal)); - } - ret = PyObject_Call(func, args_3, NULL); - } + if (!m_collisionCallbacks || PyList_GET_SIZE(m_collisionCallbacks) == 0) + return; - if (ret == NULL) { - PyErr_Print(); - PyErr_Clear(); - } - else { - Py_DECREF(ret); - } - } + PyObject *args[] = {collider->GetProxy(), PyObjectFrom(point), PyObjectFrom(normal)}; + RunPythonCallBackList(m_collisionCallbacks, args, 1, ARRAY_SIZE(args)); - if (args_3) Py_DECREF(args_3); - if (args_1) Py_DECREF(args_1); + for (unsigned int i = 0; i < ARRAY_SIZE(args); ++i) { + Py_DECREF(args[i]); } #endif } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index db4ed58d65f..a3e1d1562c9 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -43,6 +43,7 @@ #include "KX_FontObject.h" #include "RAS_IPolygonMaterial.h" #include "ListValue.h" +#include "KX_PythonCallBack.h" #include "SCA_LogicManager.h" #include "SCA_TimeEventManager.h" //#include "SCA_AlwaysEventManager.h" @@ -2132,30 +2133,10 @@ void KX_Scene::Render2DFilters(RAS_ICanvas* canvas) void KX_Scene::RunDrawingCallbacks(PyObject *cb_list) { - Py_ssize_t len; - - if (cb_list && (len=PyList_GET_SIZE(cb_list))) - { - PyObject *args = PyTuple_New(0); // save python creating each call - PyObject *func; - PyObject *ret; - - // Iterate the list and run the callbacks - for (Py_ssize_t pos=0; pos < len; pos++) - { - func= PyList_GET_ITEM(cb_list, pos); - ret= PyObject_Call(func, args, NULL); - if (ret==NULL) { - PyErr_Print(); - PyErr_Clear(); - } - else { - Py_DECREF(ret); - } - } + if (!cb_list || PyList_GET_SIZE(cb_list) == 0) + return; - Py_DECREF(args); - } + RunPythonCallBackList(cb_list, NULL, 0, 0); } //---------------------------------------------------------------------------- -- cgit v1.2.3