diff --git a/include/effectengine/EffectEngine.h b/include/effectengine/EffectEngine.h index f1aa0106..57cc6484 100644 --- a/include/effectengine/EffectEngine.h +++ b/include/effectengine/EffectEngine.h @@ -26,13 +26,20 @@ public slots: /// Clear all effects void allChannelsCleared(); +public: + struct EffectDefinition + { + std::string script; + std::string args; + }; + private slots: void effectFinished(Effect * effect); private: Hyperion * _hyperion; - std::map _availableEffects; + std::map _availableEffects; std::list _activeEffects; diff --git a/libsrc/effectengine/Effect.cpp b/libsrc/effectengine/Effect.cpp index 7b52fabd..7ea26567 100644 --- a/libsrc/effectengine/Effect.cpp +++ b/libsrc/effectengine/Effect.cpp @@ -17,10 +17,12 @@ PyMethodDef Effect::effectMethods[] = { }; -Effect::Effect(int priority, int timeout) : +Effect::Effect(int priority, int timeout, const std::string & script, const std::string & args) : QThread(), _priority(priority), _timeout(timeout), + _script(script), + _args(args), _endTime(-1), _interpreterThreadState(nullptr), _abortRequested(false), @@ -47,6 +49,9 @@ void Effect::run() // 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", Py_BuildValue("s", _args.c_str())); + // Set the end time if applicable if (_timeout > 0) { @@ -54,9 +59,15 @@ void Effect::run() } // Run the effect script - std::string script = "test.py"; - FILE* file = fopen(script.c_str(), "r"); - PyRun_SimpleFile(file, script.c_str()); + FILE* file = fopen(_script.c_str(), "r"); + if (file != nullptr) + { + PyRun_SimpleFile(file, _script.c_str()); + } + else + { + std::cerr << "Unable to open script file " << _script << std::endl; + } // Clean up the thread state Py_EndInterpreter(_interpreterThreadState); diff --git a/libsrc/effectengine/Effect.h b/libsrc/effectengine/Effect.h index 220ec4a6..8310076c 100644 --- a/libsrc/effectengine/Effect.h +++ b/libsrc/effectengine/Effect.h @@ -14,7 +14,7 @@ class Effect : public QThread Q_OBJECT public: - Effect(int priority, int timeout); + Effect(int priority, int timeout, const std::string & script, const std::string & args = ""); virtual ~Effect(); virtual void run(); @@ -45,6 +45,10 @@ private: const int _timeout; + const std::string & _script; + + const std::string & _args; + int64_t _endTime; PyThreadState * _interpreterThreadState; diff --git a/libsrc/effectengine/EffectEngine.cpp b/libsrc/effectengine/EffectEngine.cpp index 74fdf6c5..9a9f1390 100644 --- a/libsrc/effectengine/EffectEngine.cpp +++ b/libsrc/effectengine/EffectEngine.cpp @@ -23,13 +23,12 @@ EffectEngine::EffectEngine(Hyperion * hyperion) : connect(_hyperion, SIGNAL(allChannelsCleared()), this, SLOT(allChannelsCleared())); // read all effects - _availableEffects["test"] = "test.py"; + _availableEffects["test"] = {"test.py", "{\"speed\":0.2}"}; // initialize the python interpreter std::cout << "Initializing Python interpreter" << std::endl; Py_InitializeEx(0); PyEval_InitThreads(); // Create the GIL - PyRun_SimpleString("print 'test'"); _mainThreadState = PyEval_SaveThread(); } @@ -54,11 +53,18 @@ int EffectEngine::runEffect(const std::string &effectName, int priority, int tim { std::cout << "run effect " << effectName << " on channel " << priority << std::endl; + if (_availableEffects.find(effectName) == _availableEffects.end()) + { + // no such effect + return -1; + } + // clear current effect on the channel channelCleared(priority); // create the effect - Effect * effect = new Effect(priority, timeout); + const EffectDefinition & effectDefinition = _availableEffects[effectName]; + Effect * effect = new Effect(priority, timeout, effectDefinition.script, effectDefinition.args); connect(effect, SIGNAL(setColors(int,std::vector,int)), _hyperion, SLOT(setColors(int,std::vector,int)), Qt::QueuedConnection); connect(effect, SIGNAL(effectFinished(Effect*)), this, SLOT(effectFinished(Effect*))); _activeEffects.push_back(effect);