Skip to content

Commit

Permalink
UPBGE: Allow KX_LibLoadStatus.onFinish to call python method. (#896)
Browse files Browse the repository at this point in the history
Previously KX_LibLoadStatus finish callback was only permitted to be
python function not method.

To allow calling a method, work from EXP_RunPythonCallBackList is reused
and the calling of a python function is moved into new function
EXP_RunPythonCallback. This function is in charge of checking that the
python object is callable and construct a tuple of the arguments.

EXP_RunPythonCallback is now called into KX_LibLoadStatus::RunFinishCallback.
  • Loading branch information
panzergame authored and youle31 committed May 26, 2019
1 parent 9eff631 commit 0da4cda
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 23 deletions.
8 changes: 8 additions & 0 deletions source/gameengine/Expressions/EXP_PythonCallBack.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@

#include "EXP_Python.h"

/** Check and call a python callable object.
* \param value Callable object candidate.
* \param arglist The first item in the tuple to execute callbacks (can be nullptr for no arguments).
* \param minargcount The minimum of arguments possible.
* \param maxargcount The maximum of arguments possible.
*/
void EXP_RunPythonCallback(PyObject *value, PyObject **arglist, unsigned int minargcount, unsigned int maxargcount);

/** Execute each functions with at least one argument
* \param functionlist The python list which contains callbacks.
* \param arglist The first item in the tuple to execute callbacks (can be nullptr for no arguments).
Expand Down
30 changes: 13 additions & 17 deletions source/gameengine/Expressions/intern/PythonCallBack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,29 +84,20 @@ static PyObject *CreatePythonTuple(unsigned int argcount, PyObject **arglist)
return tuple;
}

void EXP_RunPythonCallBackList(PyObject *functionlist, PyObject **arglist, unsigned int minargcount, unsigned int maxargcount)
void EXP_RunPythonCallback(PyObject *value, PyObject **arglist, unsigned int minargcount, unsigned int maxargcount)
{
unsigned int size = PyList_Size(functionlist);
PyObject **argTuples = (PyObject **)BLI_array_alloca(argTuples, maxargcount - minargcount + 1);
memset(argTuples, 0, sizeof(PyObject *) * (maxargcount - minargcount + 1));

for (unsigned int i = 0; i < size; ++i) {
unsigned int funcargcount = 0;

PyObject *item = PyList_GET_ITEM(functionlist, i);
PyObject *func = CheckPythonFunction(item, minargcount, maxargcount, funcargcount);
// This item fails the check.
PyObject *func = CheckPythonFunction(value, minargcount, maxargcount, funcargcount);
// This value fails the check.
if (!func) {
PyErr_Print();
PyErr_Clear();
continue;
return;
}

// Get correct argument tuple.
PyObject *tuple = argTuples[funcargcount - minargcount];
if (!tuple) {
argTuples[funcargcount - minargcount] = tuple = CreatePythonTuple(funcargcount, arglist);
}
PyObject *tuple = CreatePythonTuple(funcargcount, arglist);

PyObject *ret = PyObject_Call(func, tuple, nullptr);
if (!ret) { // If ret is nullptr this seems that the function doesn't work.
Expand All @@ -116,9 +107,14 @@ void EXP_RunPythonCallBackList(PyObject *functionlist, PyObject **arglist, unsig
else {
Py_DECREF(ret);
}
}
}

void EXP_RunPythonCallBackList(PyObject *functionlist, PyObject **arglist, unsigned int minargcount, unsigned int maxargcount)
{
const unsigned int size = PyList_Size(functionlist);

for (unsigned int i = 0; i <= (maxargcount - minargcount); ++i) {
Py_XDECREF(argTuples[i]);
for (unsigned int i = 0; i < size; ++i) {
PyObject *item = PyList_GET_ITEM(functionlist, i);
EXP_RunPythonCallback(item, arglist, minargcount, maxargcount);
}
}
12 changes: 6 additions & 6 deletions source/gameengine/Ketsji/KX_LibLoadStatus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
*/

#include "KX_LibLoadStatus.h"

#include "EXP_PythonCallBack.h"

#include "PIL_time.h"

KX_LibLoadStatus::KX_LibLoadStatus(BL_Converter *converter, KX_KetsjiEngine *engine, KX_Scene *merge_scene, const std::string& path)
Expand Down Expand Up @@ -57,14 +60,11 @@ void KX_LibLoadStatus::RunFinishCallback()
{
#ifdef WITH_PYTHON
if (m_finish_cb) {
PyObject *args = Py_BuildValue("(O)", GetProxy());
PyObject *args[] = {GetProxy()};

if (!PyObject_Call(m_finish_cb, args, nullptr)) {
PyErr_Print();
PyErr_Clear();
}
EXP_RunPythonCallback(m_finish_cb, args, 0, 1);

Py_DECREF(args);
Py_DECREF(args[0]);
}
#endif
}
Expand Down

0 comments on commit 0da4cda

Please sign in to comment.