mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
effects included in hyperiond binary as qtResource (#237)
* implement effects included in hyperiond binary * cleanup * remove install of effects dir. People who wants to develop effects has to copy them from github effect params for initial effects can be changed in config permanently and other effect params can be changed via json (currently only temporarily) * fix schema of fadecandy webui fix display of specific led options * add leddevice write support * cleanup * webui: tune hue code * when use json effect definition from putsiede hyperiond but want to use py script from inside hyperiond use ad a : e.g. fade.py needs a fade.py near the json file, but :fade.py is taken from resource inside hyperiond * add ability to di * add abiloty to diable effcts via hyperion config * use effect name instead of script in active effects and prio register * finally solve open file handle during effect is playing. Now script is read before, then file closed and then t is run by python * fix some webui things - led config tabs - inital loading screen optimize qrc file generation fix compile warning in hyperion.cpp * cleanup * more cleanup
This commit is contained in:
@@ -26,6 +26,7 @@ EffectEngine::EffectEngine(Hyperion * hyperion, const Json::Value & jsonEffectCo
|
||||
, _mainThreadState(nullptr)
|
||||
, _log(Logger::getInstance("EFFECTENGINE"))
|
||||
{
|
||||
Q_INIT_RESOURCE(EffectEngine);
|
||||
qRegisterMetaType<std::vector<ColorRgb>>("std::vector<ColorRgb>");
|
||||
|
||||
// connect the Hyperion channel clear feedback
|
||||
@@ -33,11 +34,26 @@ EffectEngine::EffectEngine(Hyperion * hyperion, const Json::Value & jsonEffectCo
|
||||
connect(_hyperion, SIGNAL(allChannelsCleared()), this, SLOT(allChannelsCleared()));
|
||||
|
||||
// read all effects
|
||||
const Json::Value & paths = jsonEffectConfig["paths"];
|
||||
const Json::Value & paths = jsonEffectConfig["paths"];
|
||||
const Json::Value & disabledEfx = jsonEffectConfig["disable"];
|
||||
|
||||
QStringList efxPathList;
|
||||
efxPathList << ":/effects/";
|
||||
for (Json::UInt i = 0; i < paths.size(); ++i)
|
||||
{
|
||||
const std::string & path = paths[i].asString();
|
||||
QDir directory(QString::fromStdString(path));
|
||||
efxPathList << QString::fromStdString(paths[i].asString());
|
||||
}
|
||||
|
||||
QStringList disableList;
|
||||
for (Json::UInt i = 0; i < disabledEfx.size(); ++i)
|
||||
{
|
||||
disableList << QString::fromStdString(disabledEfx[i].asString());
|
||||
}
|
||||
|
||||
std::map<std::string, EffectDefinition> availableEffects;
|
||||
foreach (const QString & path, efxPathList )
|
||||
{
|
||||
QDir directory(path);
|
||||
if (directory.exists())
|
||||
{
|
||||
int efxCount = 0;
|
||||
@@ -45,16 +61,33 @@ EffectEngine::EffectEngine(Hyperion * hyperion, const Json::Value & jsonEffectCo
|
||||
foreach (const QString & filename, filenames)
|
||||
{
|
||||
EffectDefinition def;
|
||||
if (loadEffectDefinition(path, filename.toStdString(), def))
|
||||
if (loadEffectDefinition(path, filename, def))
|
||||
{
|
||||
_availableEffects.push_back(def);
|
||||
efxCount++;
|
||||
if (availableEffects.find(def.name) != availableEffects.end())
|
||||
{
|
||||
Info(_log, "effect overload effect '%s' is now taken from %s'", def.name.c_str(), path.toUtf8().constData() );
|
||||
}
|
||||
|
||||
if ( disableList.contains(QString::fromStdString(def.name)) )
|
||||
{
|
||||
Info(_log, "effect '%s' not loaded, because it is disabled in hyperion config", def.name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
availableEffects[def.name] = def;
|
||||
efxCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Info(_log, "%d effects loaded from directory %s", efxCount, path.c_str());
|
||||
Info(_log, "%d effects loaded from directory %s", efxCount, path.toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
foreach(auto item, availableEffects)
|
||||
{
|
||||
_availableEffects.push_back(item.second);
|
||||
}
|
||||
|
||||
if (_availableEffects.size() == 0)
|
||||
{
|
||||
Error(_log, "no effects found, check your effect directories");
|
||||
@@ -88,7 +121,8 @@ const std::list<ActiveEffectDefinition> &EffectEngine::getActiveEffects()
|
||||
for (Effect * effect : _activeEffects)
|
||||
{
|
||||
ActiveEffectDefinition activeEffectDefinition;
|
||||
activeEffectDefinition.script = effect->getScript();
|
||||
activeEffectDefinition.script = effect->getScript().toStdString();
|
||||
activeEffectDefinition.name = effect->getName().toStdString();
|
||||
activeEffectDefinition.priority = effect->getPriority();
|
||||
activeEffectDefinition.timeout = effect->getTimeout();
|
||||
activeEffectDefinition.args = effect->getArgs();
|
||||
@@ -98,26 +132,29 @@ const std::list<ActiveEffectDefinition> &EffectEngine::getActiveEffects()
|
||||
return _availableActiveEffects;
|
||||
}
|
||||
|
||||
bool EffectEngine::loadEffectDefinition(const std::string &path, const std::string &effectConfigFile, EffectDefinition & effectDefinition)
|
||||
bool EffectEngine::loadEffectDefinition(const QString &path, const QString &effectConfigFile, EffectDefinition & effectDefinition)
|
||||
{
|
||||
std::string fileName = path + QDir::separator().toLatin1() + effectConfigFile;
|
||||
std::ifstream file(fileName.c_str());
|
||||
QString fileName = path + QDir::separator() + effectConfigFile;
|
||||
QFile file(fileName);
|
||||
|
||||
Logger * log = Logger::getInstance("EFFECTENGINE");
|
||||
if (!file.is_open())
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
Error( log, "Effect file '%s' could not be loaded", fileName.c_str());
|
||||
Error( log, "Effect file '%s' could not be loaded", fileName.toUtf8().constData());
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray fileContent = file.readAll();
|
||||
// Read the json config file
|
||||
Json::Reader jsonReader;
|
||||
Json::Value config;
|
||||
if (!jsonReader.parse(file, config, false))
|
||||
const char* fileContent_cStr = reinterpret_cast<const char *>(fileContent.constData());
|
||||
|
||||
if (! Json::Reader().parse(fileContent_cStr, fileContent_cStr+fileContent.size(), config, false) )
|
||||
{
|
||||
Error( log, "Error while reading effect '%s': %s", fileName.c_str(), jsonReader.getFormattedErrorMessages().c_str());
|
||||
Error( log, "Error while reading effect '%s': %s", fileName.toUtf8().constData(), jsonReader.getFormattedErrorMessages().c_str());
|
||||
return false;
|
||||
}
|
||||
file.close();
|
||||
|
||||
// Read the json schema file
|
||||
QResource schemaData(":effect-schema");
|
||||
@@ -129,14 +166,22 @@ bool EffectEngine::loadEffectDefinition(const std::string &path, const std::stri
|
||||
{
|
||||
const std::list<std::string> & errors = schemaChecker.getMessages();
|
||||
foreach (const std::string & error, errors) {
|
||||
Error( log, "Error while checking '%s':%s", fileName.c_str(), error.c_str());
|
||||
Error( log, "Error while checking '%s':%s", fileName.toUtf8().constData(), error.c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// setup the definition
|
||||
std::string scriptName = config["script"].asString();
|
||||
effectDefinition.name = config["name"].asString();
|
||||
effectDefinition.script = path + QDir::separator().toLatin1() + config["script"].asString();
|
||||
if (scriptName.empty())
|
||||
return false;
|
||||
|
||||
if (scriptName[0] == ':' )
|
||||
effectDefinition.script = ":/effects/"+scriptName.substr(1);
|
||||
else
|
||||
effectDefinition.script = path.toStdString() + QDir::separator().toLatin1() + scriptName;
|
||||
|
||||
effectDefinition.args = config["args"];
|
||||
|
||||
return true;
|
||||
@@ -167,22 +212,22 @@ int EffectEngine::runEffect(const std::string &effectName, const Json::Value &ar
|
||||
return -1;
|
||||
}
|
||||
|
||||
return runEffectScript(effectDefinition->script, args.isNull() ? effectDefinition->args : args, priority, timeout);
|
||||
return runEffectScript(effectDefinition->script, effectName, args.isNull() ? effectDefinition->args : args, priority, timeout);
|
||||
}
|
||||
|
||||
int EffectEngine::runEffectScript(const std::string &script, const Json::Value &args, int priority, int timeout)
|
||||
int EffectEngine::runEffectScript(const std::string &script, const std::string &name, const Json::Value &args, int priority, int timeout)
|
||||
{
|
||||
// clear current effect on the channel
|
||||
channelCleared(priority);
|
||||
|
||||
// create the effect
|
||||
Effect * effect = new Effect(_mainThreadState, priority, timeout, script, args);
|
||||
Effect * effect = new Effect(_mainThreadState, priority, timeout, QString::fromStdString(script), QString::fromStdString(name), args);
|
||||
connect(effect, SIGNAL(setColors(int,std::vector<ColorRgb>,int,bool)), _hyperion, SLOT(setColors(int,std::vector<ColorRgb>,int,bool)), Qt::QueuedConnection);
|
||||
connect(effect, SIGNAL(effectFinished(Effect*)), this, SLOT(effectFinished(Effect*)));
|
||||
_activeEffects.push_back(effect);
|
||||
|
||||
// start the effect
|
||||
_hyperion->registerPriority("EFFECT: "+FileUtils::getBaseName(script), priority);
|
||||
_hyperion->registerPriority("EFFECT: "+name, priority);
|
||||
effect->start();
|
||||
|
||||
return 0;
|
||||
@@ -227,5 +272,5 @@ void EffectEngine::effectFinished(Effect *effect)
|
||||
|
||||
// cleanup the effect
|
||||
effect->deleteLater();
|
||||
_hyperion->unRegisterPriority("EFFECT: " + FileUtils::getBaseName(effect->getScript()));
|
||||
_hyperion->unRegisterPriority("EFFECT: " + effect->getName().toStdString());
|
||||
}
|
||||
|
Reference in New Issue
Block a user