From 016a8816346464b08386cfbbcd9cc341185bd95d Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 14 Mar 2013 14:00:10 +0100 Subject: [PATCH] Python: implement support for marshalling arrays Fixes #3858 --- lib/python/pythonlanguage.cpp | 54 ++++++++++++++++++++++++----------- lib/python/pythonlanguage.h | 2 +- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/lib/python/pythonlanguage.cpp b/lib/python/pythonlanguage.cpp index e94914721..77a5425bf 100644 --- a/lib/python/pythonlanguage.cpp +++ b/lib/python/pythonlanguage.cpp @@ -27,7 +27,7 @@ REGISTER_SCRIPTLANGUAGE("Python", PythonLanguage); PyMethodDef PythonLanguage::m_NativeMethodDef[] = { { "RegisterFunction", &PythonLanguage::PyRegisterFunction, METH_VARARGS, NULL }, - { NULL, NULL } /* sentinel */ + { NULL, NULL, NULL, NULL } /* sentinel */ }; PythonLanguage::PythonLanguage(void) @@ -60,12 +60,11 @@ void PythonLanguage::InitializeOnce(void) PyEval_ReleaseLock(); String name; - ScriptFunction::Ptr function; - BOOST_FOREACH(tie(name, function), ScriptFunction::GetFunctions()) { - RegisterNativeFunction(name, function); + BOOST_FOREACH(tie(name, tuples::ignore), ScriptFunction::GetFunctions()) { + RegisterNativeFunction(name); } - ScriptFunction::OnRegistered.connect(boost::bind(&PythonLanguage::RegisterNativeFunction, this, _1, _2)); + ScriptFunction::OnRegistered.connect(boost::bind(&PythonLanguage::RegisterNativeFunction, this, _1)); ScriptFunction::OnUnregistered.connect(boost::bind(&PythonLanguage::UnregisterNativeFunction, this, _1)); m_Initialized = true; @@ -153,9 +152,26 @@ PyObject *PythonLanguage::MarshalToPython(const Value& value) PyObject *dv = MarshalToPython(value); PyDict_SetItemString(pdict, key.CStr(), dv); + + Py_DECREF(dv); } return pdict; + } else if (value.IsObjectType()) { + Array::Ptr arr = value; + ObjectLock olock(arr); + + PyObject *plist = PyList_New(0); + + BOOST_FOREACH(const Value& value, arr) { + PyObject *dv = MarshalToPython(value); + + PyList_Append(plist, dv); + + Py_DECREF(dv); + } + + return plist; } Py_INCREF(Py_None); @@ -177,13 +193,24 @@ Value PythonLanguage::MarshalFromPython(PyObject *value) Py_ssize_t pos = 0; while (PyDict_Next(value, &pos, &dk, &dv)) { - String ik = PyString_AsString(dk); - Value iv = MarshalFromPython(dv); + String ik = PyString_AsString(dk); + Value iv = MarshalFromPython(dv); - dict->Set(ik, iv); + dict->Set(ik, iv); } return dict; + } else if (PyList_Check(value)) { + Array::Ptr arr = boost::make_shared(); + + for (Py_ssize_t pos = 0; pos < PyList_Size(value); pos++) { + PyObject *dv = PyList_GetItem(value, pos); + Value iv = MarshalFromPython(dv); + + arr->Add(iv); + } + + return arr; } else if (PyTuple_Check(value) && PyTuple_Size(value) == 2) { PyObject *ptype, *pname; @@ -287,8 +314,6 @@ PyObject *PythonLanguage::PyCallNativeFunction(PyObject *self, PyObject *args) try { ScriptTask::Ptr task = boost::make_shared(function, arguments); task->Start(); - task->Wait(); - result = task->GetResult(); } catch (const std::exception& ex) { PyEval_RestoreThread(tstate); @@ -308,9 +333,8 @@ PyObject *PythonLanguage::PyCallNativeFunction(PyObject *self, PyObject *args) * Registers a native function. * * @param name The name of the native function. - * @param function The function. */ -void PythonLanguage::RegisterNativeFunction(const String& name, const ScriptFunction::Ptr& function) +void PythonLanguage::RegisterNativeFunction(const String& name) { ObjectLock olock(this); @@ -357,7 +381,7 @@ void PythonLanguage::UnregisterNativeFunction(const String& name) (void) PyThreadState_Swap(tstate); } -PyObject *PythonLanguage::PyRegisterFunction(PyObject *self, PyObject *args) +PyObject *PythonLanguage::PyRegisterFunction(PyObject *, PyObject *args) { char *name; PyObject *object; @@ -390,8 +414,6 @@ PyObject *PythonLanguage::PyRegisterFunction(PyObject *self, PyObject *args) */ PythonInterpreter *PythonLanguage::GetCurrentInterpreter(void) { - ObjectLock olock(this); - return m_CurrentInterpreter; } @@ -402,7 +424,5 @@ PythonInterpreter *PythonLanguage::GetCurrentInterpreter(void) */ void PythonLanguage::SetCurrentInterpreter(PythonInterpreter *interpreter) { - ObjectLock olock(this); - m_CurrentInterpreter = interpreter; } diff --git a/lib/python/pythonlanguage.h b/lib/python/pythonlanguage.h index fc92ff2cc..22efffa32 100644 --- a/lib/python/pythonlanguage.h +++ b/lib/python/pythonlanguage.h @@ -58,7 +58,7 @@ private: PyObject *m_TracebackModule; static PythonInterpreter *m_CurrentInterpreter; - void RegisterNativeFunction(const String& name, const ScriptFunction::Ptr& function); + void RegisterNativeFunction(const String& name); void UnregisterNativeFunction(const String& name); static PyObject *PyCallNativeFunction(PyObject *self, PyObject *args);