some more work
This commit is contained in:
parent
68e9c82758
commit
59c1c8e9f2
@ -5,6 +5,7 @@
|
||||
#include "structmember.h"
|
||||
|
||||
#include "integrations/thing.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
@ -18,16 +19,12 @@ typedef struct _thing {
|
||||
} PyThing;
|
||||
|
||||
|
||||
static int PyThing_init(PyThing */*self*/, PyObject */*args*/, PyObject */*kwds*/)
|
||||
// initialize PyVoice Object
|
||||
{
|
||||
static int PyThing_init(PyThing */*self*/, PyObject */*args*/, PyObject */*kwds*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void PyThing_dealloc(PyThing * self)
|
||||
// destruct the object
|
||||
{
|
||||
static void PyThing_dealloc(PyThing * self) {
|
||||
// FIXME: Why is this not called? Seems we're leaking...
|
||||
Q_ASSERT(false);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
@ -53,12 +50,12 @@ static int PyThing_setName(PyThing *self, PyObject *value, void */*closure*/){
|
||||
|
||||
static PyObject * PyThing_setStateValue(PyThing* self, PyObject* args)
|
||||
{
|
||||
char *stateTypeIdStr;
|
||||
PyObject *valueObj;
|
||||
char *stateTypeIdStr = nullptr;
|
||||
PyObject *valueObj = nullptr;
|
||||
|
||||
// FIXME: is there any better way to do this? Value is a variant
|
||||
if (!PyArg_ParseTuple(args, "sO", &stateTypeIdStr, &valueObj)) {
|
||||
qWarning() << "error parsing parameters";
|
||||
qCWarning(dcThingManager) << "Error parsing parameters";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -68,7 +65,6 @@ static PyObject * PyThing_setStateValue(PyThing* self, PyObject* args)
|
||||
PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "~E~");
|
||||
const char *bytes = PyBytes_AS_STRING(str);
|
||||
|
||||
qWarning() << "params:" << stateTypeId << bytes << self;
|
||||
QVariant value(bytes);
|
||||
|
||||
if (self->ptrObj != nullptr) {
|
||||
@ -81,6 +77,37 @@ static PyObject * PyThing_setStateValue(PyThing* self, PyObject* args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject * PyThing_emitEvent(PyThing* self, PyObject* args)
|
||||
{
|
||||
char *eventTypeIdStr = nullptr;
|
||||
PyObject *valueObj = nullptr;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|O", &eventTypeIdStr, &valueObj)) {
|
||||
qCWarning(dcThingManager) << "Error parsing parameters";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EventTypeId eventTypeId = EventTypeId(eventTypeIdStr);
|
||||
|
||||
// if (valueObj != nullptr) {
|
||||
// PyObject* repr = PyObject_Repr(valueObj);
|
||||
// PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "~E~");
|
||||
// const char *bytes = PyBytes_AS_STRING(str);
|
||||
|
||||
// QVariant value(bytes);
|
||||
// }
|
||||
|
||||
|
||||
if (self->ptrObj != nullptr) {
|
||||
QMetaObject::invokeMethod(self->ptrObj, "emitEvent", Qt::QueuedConnection, Q_ARG(EventTypeId, eventTypeId));
|
||||
}
|
||||
|
||||
// Py_XDECREF(repr);
|
||||
// Py_XDECREF(str);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyGetSetDef PyThing_getseters[] = {
|
||||
{"name", (getter)PyThing_getName, (setter)PyThing_setName, "Thingname", nullptr},
|
||||
{nullptr , nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
@ -88,7 +115,7 @@ static PyGetSetDef PyThing_getseters[] = {
|
||||
|
||||
static PyMethodDef PyThing_methods[] = {
|
||||
{ "setStateValue", (PyCFunction)PyThing_setStateValue, METH_VARARGS, "Set a things state value" },
|
||||
// { "finish", (PyCFunction)PyThing_finish, METH_VARARGS, "finish a discovery" },
|
||||
{ "emitEvent", (PyCFunction)PyThing_emitEvent, METH_VARARGS, "Emits an event" },
|
||||
{nullptr, nullptr, 0, nullptr} // sentinel
|
||||
};
|
||||
|
||||
|
||||
@ -126,23 +126,10 @@ void PythonIntegrationPlugin::initPython()
|
||||
// Import nymea module into this interpreter
|
||||
s_nymeaModule = PyImport_ImportModule("nymea");
|
||||
|
||||
|
||||
|
||||
// // Spawn a event loop for python
|
||||
// We'll be using asyncio everywhere, so let's import it right away
|
||||
s_asyncio = PyImport_ImportModule("asyncio");
|
||||
// PyObject *get_event_loop = PyObject_GetAttrString(s_asyncio, "get_event_loop");
|
||||
// PyObject *loop = PyObject_CallFunctionObjArgs(get_event_loop, nullptr);
|
||||
// PyObject *run_forever = PyObject_GetAttrString(loop, "run_forever");
|
||||
|
||||
|
||||
// QtConcurrent::run([=](){
|
||||
// PyGILState_STATE s = PyGILState_Ensure();
|
||||
// PyObject_CallFunctionObjArgs(run_forever, nullptr);
|
||||
// PyGILState_Release(s);
|
||||
// });
|
||||
|
||||
|
||||
// Need to release ths lock from the main thread before spawning the new thread
|
||||
// Need to release ths lock from the main thread before spawning new threads
|
||||
s_mainThread = PyEval_SaveThread();
|
||||
}
|
||||
|
||||
@ -408,14 +395,14 @@ void PythonIntegrationPlugin::exportBrowserItemActionTypes(const ActionTypes &ac
|
||||
|
||||
void PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObject *param)
|
||||
{
|
||||
PyEval_RestoreThread(s_mainThread);
|
||||
PyGILState_STATE s = PyGILState_Ensure();
|
||||
|
||||
qCDebug(dcThingManager()) << "Calling python plugin function" << function;
|
||||
PyObject *pFunc = PyObject_GetAttrString(m_module, function.toUtf8());
|
||||
if(!pFunc || !PyCallable_Check(pFunc)) {
|
||||
Py_XDECREF(pFunc);
|
||||
qCWarning(dcThingManager()) << "Python plugin does not implement" << function;
|
||||
s_mainThread = PyEval_SaveThread();
|
||||
PyGILState_Release(s);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -429,12 +416,12 @@ void PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
|
||||
if (PyErr_Occurred()) {
|
||||
qCWarning(dcThingManager()) << "Error calling python method:";
|
||||
dumpError();
|
||||
s_mainThread = PyEval_SaveThread();
|
||||
PyGILState_Release(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (QByteArray(future->ob_type->tp_name) != "coroutine") {
|
||||
s_mainThread = PyEval_SaveThread();
|
||||
PyGILState_Release(s);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -453,10 +440,10 @@ void PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
|
||||
PyObject *result = PyObject_CallFunctionObjArgs(add_done_callback, task_done, nullptr);
|
||||
dumpError();
|
||||
|
||||
PyObject *run_forever = PyObject_GetAttrString(loop, "run_until_complete");
|
||||
PyObject *run_until_complete = PyObject_GetAttrString(loop, "run_until_complete");
|
||||
QtConcurrent::run([=](){
|
||||
PyGILState_STATE s = PyGILState_Ensure();
|
||||
PyObject_CallFunctionObjArgs(run_forever, task, nullptr);
|
||||
PyObject_CallFunctionObjArgs(run_until_complete, task, nullptr);
|
||||
PyGILState_Release(s);
|
||||
});
|
||||
|
||||
@ -467,6 +454,6 @@ void PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
|
||||
Py_DECREF(add_done_callback);
|
||||
Py_DECREF(result);
|
||||
|
||||
s_mainThread = PyEval_SaveThread();
|
||||
PyGILState_Release(s);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user