diff --git a/CMakeLists.txt b/CMakeLists.txt index 6547c450..34aec49e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,8 +41,8 @@ include_directories(${CMAKE_SOURCE_DIR}/include) # Prefer static linking over dynamic #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so") -set(CMAKE_BUILD_TYPE "Debug") -#set(CMAKE_BUILD_TYPE "Release") +#set(CMAKE_BUILD_TYPE "Debug") +set(CMAKE_BUILD_TYPE "Release") # enable C++11 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall") diff --git a/deploy/hyperion.tar.gz.REMOVED.git-id b/deploy/hyperion.tar.gz.REMOVED.git-id index 440b9e4d..93746779 100644 --- a/deploy/hyperion.tar.gz.REMOVED.git-id +++ b/deploy/hyperion.tar.gz.REMOVED.git-id @@ -1 +1 @@ -8f880f994b0855ace23e27818896fc34ba1677a8 \ No newline at end of file +0c20a678370e38a9a8da650e04445088d892a49f \ No newline at end of file diff --git a/libsrc/effectengine/Effect.cpp b/libsrc/effectengine/Effect.cpp index b19d40cc..09411c87 100644 --- a/libsrc/effectengine/Effect.cpp +++ b/libsrc/effectengine/Effect.cpp @@ -22,36 +22,36 @@ PyMethodDef Effect::effectMethods[] = { #if PY_MAJOR_VERSION >= 3 // create the hyperion module struct PyModuleDef Effect::moduleDef = { - PyModuleDef_HEAD_INIT, - "hyperion", /* m_name */ - "Hyperion module", /* m_doc */ - -1, /* m_size */ - Effect::effectMethods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ + PyModuleDef_HEAD_INIT, + "hyperion", /* m_name */ + "Hyperion module", /* m_doc */ + -1, /* m_size */ + Effect::effectMethods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ }; PyObject* Effect::PyInit_hyperion() { - return PyModule_Create(&moduleDef); + return PyModule_Create(&moduleDef); } #else void Effect::PyInit_hyperion() { - Py_InitModule("hyperion", effectMethods); + Py_InitModule("hyperion", effectMethods); } #endif void Effect::registerHyperionExtensionModule() { - PyImport_AppendInittab("hyperion", &PyInit_hyperion); + PyImport_AppendInittab("hyperion", &PyInit_hyperion); } Effect::Effect(PyThreadState * mainThreadState, int priority, int timeout, const std::string & script, const Json::Value & args) : QThread(), - _mainThreadState(mainThreadState), + _mainThreadState(mainThreadState), _priority(priority), _timeout(timeout), _script(script), @@ -74,26 +74,26 @@ Effect::~Effect() void Effect::run() { - // switch to the main thread state and acquire the GIL - PyEval_RestoreThread(_mainThreadState); + // switch to the main thread state and acquire the GIL + PyEval_RestoreThread(_mainThreadState); // Initialize a new thread state - _interpreterThreadState = Py_NewInterpreter(); + _interpreterThreadState = Py_NewInterpreter(); - // import the buildtin Hyperion module - PyObject * module = PyImport_ImportModule("hyperion"); + // import the buildtin Hyperion module + PyObject * module = PyImport_ImportModule("hyperion"); - // add a capsule containing 'this' to the module to be able to retrieve the effect from the callback function - PyObject_SetAttrString(module, "__effectObj", PyCapsule_New(this, nullptr, nullptr)); + // add a capsule containing 'this' to the module to be able to retrieve the effect from the callback function + PyObject_SetAttrString(module, "__effectObj", PyCapsule_New(this, nullptr, nullptr)); - // add ledCount variable to the interpreter - PyObject_SetAttrString(module, "ledCount", Py_BuildValue("i", _imageProcessor->getLedCount())); + // add ledCount variable to the interpreter + PyObject_SetAttrString(module, "ledCount", Py_BuildValue("i", _imageProcessor->getLedCount())); - // add a args variable to the interpreter - PyObject_SetAttrString(module, "args", json2python(_args)); + // add a args variable to the interpreter + PyObject_SetAttrString(module, "args", json2python(_args)); - // decref the module - Py_XDECREF(module); + // decref the module + Py_XDECREF(module); // Set the end time if applicable if (_timeout > 0) @@ -155,19 +155,23 @@ PyObject *Effect::json2python(const Json::Value &json) const return Py_BuildValue("s", json.asCString()); case Json::objectValue: { - PyObject * obj = PyDict_New(); + PyObject * dict= PyDict_New(); for (Json::Value::iterator i = json.begin(); i != json.end(); ++i) { - PyDict_SetItemString(obj, i.memberName(), json2python(*i)); + PyObject * obj = json2python(*i); + PyDict_SetItemString(dict, i.memberName(), obj); + Py_XDECREF(obj); } - return obj; + return dict; } case Json::arrayValue: { PyObject * list = PyList_New(json.size()); for (Json::Value::iterator i = json.begin(); i != json.end(); ++i) { - PyList_SetItem(list, i.index(), json2python(*i)); + PyObject * obj = json2python(*i); + PyList_SetItem(list, i.index(), obj); + Py_XDECREF(obj); } return list; } @@ -180,7 +184,7 @@ PyObject *Effect::json2python(const Json::Value &json) const PyObject* Effect::wrapSetColor(PyObject *self, PyObject *args) { // get the effect - Effect * effect = getEffect(); + Effect * effect = getEffect(); // check if we have aborted already if (effect->_abortRequested) @@ -265,7 +269,7 @@ PyObject* Effect::wrapSetColor(PyObject *self, PyObject *args) PyObject* Effect::wrapSetImage(PyObject *self, PyObject *args) { // get the effect - Effect * effect = getEffect(); + Effect * effect = getEffect(); // check if we have aborted already if (effect->_abortRequested) @@ -328,7 +332,7 @@ PyObject* Effect::wrapSetImage(PyObject *self, PyObject *args) PyObject* Effect::wrapAbort(PyObject *self, PyObject *) { - Effect * effect = getEffect(); + Effect * effect = getEffect(); // Test if the effect has reached it end time if (effect->_timeout > 0 && QDateTime::currentMSecsSinceEpoch() > effect->_endTime) @@ -341,22 +345,31 @@ PyObject* Effect::wrapAbort(PyObject *self, PyObject *) Effect * Effect::getEffect() { - // extract the module from the runtime - PyObject * module = PyObject_GetAttrString(PyImport_AddModule("__main__"), "hyperion"); + // extract the module from the runtime + PyObject * module = PyObject_GetAttrString(PyImport_AddModule("__main__"), "hyperion"); - if (PyModule_Check(module)) - { - // retrieve the capsule with the effect - PyObject * effectCapsule = PyObject_GetAttrString(module, "__effectObj"); + if (!PyModule_Check(module)) + { + // something is wrong + Py_XDECREF(module); + std::cerr << "Unable to retrieve the effect object from the Python runtime" << std::endl; + return nullptr; + } - if (PyCapsule_CheckExact(effectCapsule)) - { - // Get the effect from the capsule - return reinterpret_cast(PyCapsule_GetPointer(effectCapsule, nullptr)); - } - } + // retrieve the capsule with the effect + PyObject * effectCapsule = PyObject_GetAttrString(module, "__effectObj"); + Py_XDECREF(module); - // something is wrong - std::cerr << "Unable to retrieve the effect object from the Python runtime" << std::endl; - return nullptr; + if (!PyCapsule_CheckExact(effectCapsule)) + { + // something is wrong + Py_XDECREF(effectCapsule); + std::cerr << "Unable to retrieve the effect object from the Python runtime" << std::endl; + return nullptr; + } + + // Get the effect from the capsule + Effect * effect = reinterpret_cast(PyCapsule_GetPointer(effectCapsule, nullptr)); + Py_XDECREF(effectCapsule); + return effect; }