Fix some more threading errors (#911)

This commit is contained in:
Murat Seker 2020-08-02 10:44:42 +02:00 committed by GitHub
parent d9e33885a0
commit 8824e69986
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 132 additions and 156 deletions

View File

@ -30,7 +30,7 @@ public:
int isComponentEnabled(const hyperion::Components& comp) const; int isComponentEnabled(const hyperion::Components& comp) const;
/// contains all components and their state /// contains all components and their state
std::map<hyperion::Components, bool> getRegister() { return _componentStates; }; std::map<hyperion::Components, bool> getRegister() const { return _componentStates; };
signals: signals:
/// ///

View File

@ -11,12 +11,10 @@
#include <QJsonValue> #include <QJsonValue>
#include <QJsonArray> #include <QJsonArray>
#include <QMap> #include <QMap>
#include <QMutex>
// hyperion-utils includes // hyperion-utils includes
#include <utils/Image.h> #include <utils/Image.h>
#include <utils/ColorRgb.h> #include <utils/ColorRgb.h>
#include <utils/Logger.h>
#include <utils/Components.h> #include <utils/Components.h>
#include <utils/VideoMode.h> #include <utils/VideoMode.h>
@ -49,6 +47,7 @@ class BGEffectHandler;
class CaptureCont; class CaptureCont;
class BoblightServer; class BoblightServer;
class LedDeviceWrapper; class LedDeviceWrapper;
class Logger;
/// ///
/// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through /// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through
@ -71,13 +70,13 @@ public:
/// ///
void freeObjects(bool emitCloseSignal=false); void freeObjects(bool emitCloseSignal=false);
ImageProcessor* getImageProcessor() { return _imageProcessor; } ImageProcessor* getImageProcessor() const { return _imageProcessor; }
/// ///
/// @brief Get instance index of this instance /// @brief Get instance index of this instance
/// @return The index of this instance /// @return The index of this instance
/// ///
const quint8 & getInstanceIndex() { return _instIndex; } quint8 getInstanceIndex() const { return _instIndex; }
/// ///
/// @brief Return the size of led grid /// @brief Return the size of led grid
@ -85,28 +84,27 @@ public:
QSize getLedGridSize() const { return _ledGridSize; } QSize getLedGridSize() const { return _ledGridSize; }
/// gets the methode how image is maped to leds /// gets the methode how image is maped to leds
const int & getLedMappingType(); int getLedMappingType() const;
/// forward smoothing config /// forward smoothing config
unsigned addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0); unsigned addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0);
unsigned updateSmoothingConfig(unsigned id, int settlingTime_ms=200, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0); unsigned updateSmoothingConfig(unsigned id, int settlingTime_ms=200, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0);
VideoMode getCurrentVideoMode() const;
const VideoMode & getCurrentVideoMode();
/// ///
/// @brief Get the current active led device /// @brief Get the current active led device
/// @return The device name /// @return The device name
/// ///
const QString & getActiveDeviceType(); QString getActiveDeviceType() const;
///
/// @brief Get pointer to current LedDevice
///
LedDevice * getActiveDevice() const;
public slots: public slots:
int getLatchTime() const;
///
/// Updates the priority muxer with the current time and (re)writes the led color with applied
/// transforms.
///
void update();
/// ///
/// Returns the number of attached leds /// Returns the number of attached leds
@ -176,7 +174,7 @@ public slots:
/// Returns the ColorAdjustment with the given identifier /// Returns the ColorAdjustment with the given identifier
/// @return The adjustment with the given identifier (or nullptr if the identifier does not exist) /// @return The adjustment with the given identifier (or nullptr if the identifier does not exist)
/// ///
ColorAdjustment * getAdjustment(const QString& id); ColorAdjustment * getAdjustment(const QString& id) const;
/// Tell Hyperion that the corrections have changed and the leds need to be updated /// Tell Hyperion that the corrections have changed and the leds need to be updated
void adjustmentsUpdated(); void adjustmentsUpdated();
@ -198,7 +196,7 @@ public slots:
/// @return EffectEngine instance pointer /// @return EffectEngine instance pointer
/// ///
EffectEngine* getEffectEngineInstance() { return _effectEngine; } EffectEngine* getEffectEngineInstance() const { return _effectEngine; }
/// ///
/// @brief Save an effect /// @brief Save an effect
/// @param obj The effect args /// @param obj The effect args
@ -239,11 +237,11 @@ public slots:
/// Get the list of active effects /// Get the list of active effects
/// @return The list of active effects /// @return The list of active effects
const std::list<ActiveEffectDefinition> &getActiveEffects(); const std::list<ActiveEffectDefinition> &getActiveEffects() const;
/// Get the list of available effect schema files /// Get the list of available effect schema files
/// @return The list of available effect schema files /// @return The list of available effect schema files
const std::list<EffectSchema> &getEffectSchemas(); const std::list<EffectSchema> &getEffectSchemas() const;
/// ############# /// #############
/// PRIORITYMUXER /// PRIORITYMUXER
@ -298,7 +296,7 @@ public slots:
/// ///
/// @return The information of the given, a not found priority will return lowest priority as fallback /// @return The information of the given, a not found priority will return lowest priority as fallback
/// ///
const InputInfo getPriorityInfo(const int priority) const; InputInfo getPriorityInfo(const int priority) const;
/// ############# /// #############
/// SETTINGSMANAGER /// SETTINGSMANAGER
@ -307,11 +305,11 @@ public slots:
/// @param type The settingsType from enum /// @param type The settingsType from enum
/// @return Data Document /// @return Data Document
/// ///
QJsonDocument getSetting(const settings::type& type); QJsonDocument getSetting(const settings::type& type) const;
/// gets the current json config object from SettingsManager /// gets the current json config object from SettingsManager
/// @return json config /// @return json config
const QJsonObject& getQJsonConfig(); const QJsonObject& getQJsonConfig() const;
/// ///
/// @brief Save a complete json config /// @brief Save a complete json config
@ -327,7 +325,7 @@ public slots:
/// @brief Get the component Register /// @brief Get the component Register
/// return Component register pointer /// return Component register pointer
/// ///
ComponentRegister& getComponentRegister() { return _componentRegister; } ComponentRegister & getComponentRegister() { return _componentRegister; }
/// ///
/// @brief Called from components to update their current state. DO NOT CALL FROM USERS /// @brief Called from components to update their current state. DO NOT CALL FROM USERS
@ -340,7 +338,7 @@ public slots:
/// @brief Get a list of all contrable components and their current state /// @brief Get a list of all contrable components and their current state
/// @return list of components /// @return list of components
/// ///
std::map<hyperion::Components, bool> getAllComponents(); std::map<hyperion::Components, bool> getAllComponents() const;
/// ///
/// @brief Test if a component is enabled /// @brief Test if a component is enabled
@ -368,6 +366,8 @@ public slots:
/// ///
void stop(); void stop();
int getLatchTime() const;
signals: signals:
/// Signal which is emitted when a priority channel is actively cleared /// Signal which is emitted when a priority channel is actively cleared
/// This signal will not be emitted when a priority channel time out /// This signal will not be emitted when a priority channel time out
@ -456,15 +456,7 @@ signals:
/// ///
void started(); void started();
public slots:
///
/// Updates the priority muxer with the current time and (re)writes the led color with applied
/// transforms.
///
void update();
private slots: private slots:
/// ///
/// @brief Handle whenever the visible component changed /// @brief Handle whenever the visible component changed
/// @param comp The new component /// @param comp The new component
@ -548,6 +540,4 @@ private:
/// Boblight instance /// Boblight instance
BoblightServer* _boblightServer; BoblightServer* _boblightServer;
QMutex _changes;
}; };

View File

@ -50,24 +50,12 @@ public:
/// ///
~LedDevice() override; ~LedDevice() override;
///
/// @brief Get color order of device.
///
/// @return The color order
///
const QString & getColorOrder() const { return _colorOrder; }
/// ///
/// @brief Set the current active LED-device type. /// @brief Set the current active LED-device type.
/// ///
/// @param deviceType Device's type /// @param deviceType Device's type
/// ///
void setActiveDeviceType(const QString& deviceType); void setActiveDeviceType(const QString& deviceType);
///
/// @brief Get the current active LED-device type.
///
const QString & getActiveDeviceType() const { return _activeDeviceType; }
/// ///
/// @brief Set the number of LEDs supported by the device. /// @brief Set the number of LEDs supported by the device.
@ -76,13 +64,6 @@ public:
/// ///
void setLedCount(unsigned int ledCount); void setLedCount(unsigned int ledCount);
///
/// @brief Get the number of LEDs supported by the device.
///
/// @return Number of device's LEDs
///
unsigned int getLedCount() const { return _ledCount; }
/// ///
/// @brief Check, if the device is enabled. /// @brief Check, if the device is enabled.
/// ///
@ -100,13 +81,6 @@ public:
/// ///
void setLatchTime(int latchTime_ms); void setLatchTime(int latchTime_ms);
///
/// @brief Get the currently defined LatchTime.
///
/// @return Latch time in milliseconds
///
int getLatchTime() const { return _latchTime_ms; }
/// ///
/// @brief Discover devices of this type available (for configuration). /// @brief Discover devices of this type available (for configuration).
/// @note Mainly used for network devices. Allows to find devices, e.g. via ssdp, mDNS or cloud ways. /// @note Mainly used for network devices. Allows to find devices, e.g. via ssdp, mDNS or cloud ways.
@ -167,13 +141,6 @@ public:
/// ///
bool isInError() const { return _isDeviceInError; } bool isInError() const { return _isDeviceInError; }
///
/// @brief Get the LED-Device component's state.
///
/// @return True, if enabled
///
inline bool componentState() const { return isEnabled(); }
/// ///
/// @brief Prints the color values to stdout. /// @brief Prints the color values to stdout.
/// ///
@ -214,6 +181,39 @@ public slots:
/// ///
void setEnable(bool enable); void setEnable(bool enable);
///
/// @brief Get the currently defined LatchTime.
///
/// @return Latch time in milliseconds
///
int getLatchTime() const { return _latchTime_ms; }
///
/// @brief Get the number of LEDs supported by the device.
///
/// @return Number of device's LEDs
///
unsigned int getLedCount() const { return _ledCount; }
///
/// @brief Get the current active LED-device type.
///
QString getActiveDeviceType() const { return _activeDeviceType; }
///
/// @brief Get color order of device.
///
/// @return The color order
///
QString getColorOrder() const { return _colorOrder; }
///
/// @brief Get the LED-Device component's state.
///
/// @return True, if enabled
///
inline bool componentState() const { return isEnabled(); }
signals: signals:
/// ///
/// @brief Emits whenever the LED-Device switches between on/off. /// @brief Emits whenever the LED-Device switches between on/off.

View File

@ -6,6 +6,8 @@
#include <utils/ColorRgb.h> #include <utils/ColorRgb.h>
#include <utils/Components.h> #include <utils/Components.h>
#include <QMutex>
class LedDevice; class LedDevice;
class Hyperion; class Hyperion;
@ -53,7 +55,7 @@ public:
/// ///
/// @brief Get the current active ledDevice type /// @brief Get the current active ledDevice type
/// ///
const QString & getActiveDeviceType(); QString getActiveDeviceType();
/// ///
/// @brief Return the last enable state /// @brief Return the last enable state
@ -63,7 +65,7 @@ public:
/// ///
/// @brief Get the current colorOrder from device /// @brief Get the current colorOrder from device
/// ///
const QString & getColorOrder(); QString getColorOrder();
/// ///
/// @brief Get the number of LEDs from device /// @brief Get the number of LEDs from device
@ -103,6 +105,7 @@ private slots:
protected: protected:
/// contains all available led device constructors /// contains all available led device constructors
static LedDeviceRegistry _ledDeviceMap; static LedDeviceRegistry _ledDeviceMap;
static QMutex _ledDeviceMapLock;
private: private:
/// ///

View File

@ -15,15 +15,12 @@
#include <QTimer> #include <QTimer>
// hyperion includes // hyperion includes
#include <leddevice/LedDeviceWrapper.h>
#include <hyperion/GrabberWrapper.h>
#include <utils/jsonschema/QJsonFactory.h> #include <utils/jsonschema/QJsonFactory.h>
#include <utils/jsonschema/QJsonSchemaChecker.h> #include <utils/jsonschema/QJsonSchemaChecker.h>
#include <HyperionConfig.h> #include <HyperionConfig.h>
#include <utils/SysInfo.h> #include <utils/SysInfo.h>
#include <utils/ColorSys.h> #include <utils/ColorSys.h>
#include <utils/Process.h> #include <utils/Process.h>
//#include <utils/ApiSync.h>
// bonjour wrapper // bonjour wrapper
#include <bonjour/bonjourbrowserwrapper.h> #include <bonjour/bonjourbrowserwrapper.h>
@ -95,7 +92,6 @@ void API::setColor(const int &priority, const std::vector<uint8_t> &ledColors, c
fledColors.emplace_back(ColorRgb{ledColors[i], ledColors[i + 1], ledColors[i + 2]}); fledColors.emplace_back(ColorRgb{ledColors[i], ledColors[i + 1], ledColors[i + 2]});
} }
QMetaObject::invokeMethod(_hyperion, "setColor", Qt::QueuedConnection, Q_ARG(int, priority), Q_ARG(std::vector<ColorRgb>, fledColors), Q_ARG(int, timeout_ms), Q_ARG(QString, origin)); QMetaObject::invokeMethod(_hyperion, "setColor", Qt::QueuedConnection, Q_ARG(int, priority), Q_ARG(std::vector<ColorRgb>, fledColors), Q_ARG(int, timeout_ms), Q_ARG(QString, origin));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setColor", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, priority), Q_ARG(std::vector<ColorRgb>, fledColors), Q_ARG(int, timeout_ms), Q_ARG(QString, origin), Q_ARG(hyperion::Components, callerComp));
} }
} }
@ -175,9 +171,6 @@ bool API::setImage(ImageCmdData &data, hyperion::Components comp, QString &reply
QMetaObject::invokeMethod(_hyperion, "registerInput", Qt::QueuedConnection, Q_ARG(int, data.priority), Q_ARG(hyperion::Components, comp), Q_ARG(QString, data.origin), Q_ARG(QString, data.imgName)); QMetaObject::invokeMethod(_hyperion, "registerInput", Qt::QueuedConnection, Q_ARG(int, data.priority), Q_ARG(hyperion::Components, comp), Q_ARG(QString, data.origin), Q_ARG(QString, data.imgName));
QMetaObject::invokeMethod(_hyperion, "setInputImage", Qt::QueuedConnection, Q_ARG(int, data.priority), Q_ARG(Image<ColorRgb>, image), Q_ARG(int64_t, data.duration)); QMetaObject::invokeMethod(_hyperion, "setInputImage", Qt::QueuedConnection, Q_ARG(int, data.priority), Q_ARG(Image<ColorRgb>, image), Q_ARG(int64_t, data.duration));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "registerInput", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, data.priority), Q_ARG(hyperion::Components, comp), Q_ARG(QString, data.origin), Q_ARG(QString, data.imgName), Q_ARG(hyperion::Components, callerComp));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setInputImage", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, data.priority), Q_ARG(Image<ColorRgb>, image), Q_ARG(int64_t, data.duration), Q_ARG(hyperion::Components, comp), Q_ARG(hyperion::Components, callerComp));
return true; return true;
} }
@ -186,7 +179,6 @@ bool API::clearPriority(const int &priority, QString &replyMsg, const hyperion::
if (priority < 0 || (priority > 0 && priority < 254)) if (priority < 0 || (priority > 0 && priority < 254))
{ {
QMetaObject::invokeMethod(_hyperion, "clear", Qt::QueuedConnection, Q_ARG(int, priority)); QMetaObject::invokeMethod(_hyperion, "clear", Qt::QueuedConnection, Q_ARG(int, priority));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "clearPriority", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, priority), Q_ARG(hyperion::Components, callerComp));
} }
else else
{ {
@ -203,7 +195,6 @@ bool API::setComponentState(const QString &comp, bool &compState, QString &reply
if (component != COMP_INVALID) if (component != COMP_INVALID)
{ {
QMetaObject::invokeMethod(_hyperion, "compStateChangeRequest", Qt::QueuedConnection, Q_ARG(hyperion::Components, component), Q_ARG(bool, compState)); QMetaObject::invokeMethod(_hyperion, "compStateChangeRequest", Qt::QueuedConnection, Q_ARG(hyperion::Components, component), Q_ARG(bool, compState));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "compStateChangeRequest", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(hyperion::Components, component), Q_ARG(bool, compState), Q_ARG(hyperion::Components, callerComp));
return true; return true;
} }
replyMsg = QString("Unknown component name: %1").arg(comp); replyMsg = QString("Unknown component name: %1").arg(comp);
@ -213,13 +204,11 @@ bool API::setComponentState(const QString &comp, bool &compState, QString &reply
void API::setLedMappingType(const int &type, const hyperion::Components &callerComp) void API::setLedMappingType(const int &type, const hyperion::Components &callerComp)
{ {
QMetaObject::invokeMethod(_hyperion, "setLedMappingType", Qt::QueuedConnection, Q_ARG(int, type)); QMetaObject::invokeMethod(_hyperion, "setLedMappingType", Qt::QueuedConnection, Q_ARG(int, type));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setLedMappingType", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, type), Q_ARG(hyperion::Components, callerComp));
} }
void API::setVideoMode(const VideoMode &mode, const hyperion::Components &callerComp) void API::setVideoMode(const VideoMode &mode, const hyperion::Components &callerComp)
{ {
QMetaObject::invokeMethod(_hyperion, "setVideoMode", Qt::QueuedConnection, Q_ARG(VideoMode, mode)); QMetaObject::invokeMethod(_hyperion, "setVideoMode", Qt::QueuedConnection, Q_ARG(VideoMode, mode));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setVideoMode", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(VideoMode, mode), Q_ARG(hyperion::Components, callerComp));
} }
void API::setEffect(const EffectCmdData &dat, const hyperion::Components &callerComp) void API::setEffect(const EffectCmdData &dat, const hyperion::Components &callerComp)
@ -231,20 +220,17 @@ void API::setEffect(const EffectCmdData &dat, const hyperion::Components &caller
else else
{ {
QMetaObject::invokeMethod(_hyperion, "setEffect", Qt::QueuedConnection, Q_ARG(QString, dat.effectName), Q_ARG(int, dat.priority), Q_ARG(int, dat.duration), Q_ARG(QString, dat.origin)); QMetaObject::invokeMethod(_hyperion, "setEffect", Qt::QueuedConnection, Q_ARG(QString, dat.effectName), Q_ARG(int, dat.priority), Q_ARG(int, dat.duration), Q_ARG(QString, dat.origin));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setEffect", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(QString, dat.effectName), Q_ARG(int, dat.priority), Q_ARG(int, dat.duration), Q_ARG(QString, dat.origin), Q_ARG(hyperion::Components, callerComp));
} }
} }
void API::setSourceAutoSelect(const bool state, const hyperion::Components &callerComp) void API::setSourceAutoSelect(const bool state, const hyperion::Components &callerComp)
{ {
QMetaObject::invokeMethod(_hyperion, "setSourceAutoSelect", Qt::QueuedConnection, Q_ARG(bool, state)); QMetaObject::invokeMethod(_hyperion, "setSourceAutoSelect", Qt::QueuedConnection, Q_ARG(bool, state));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setSourceAutoSelect", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(bool, state), Q_ARG(hyperion::Components, callerComp));
} }
void API::setVisiblePriority(const int &priority, const hyperion::Components &callerComp) void API::setVisiblePriority(const int &priority, const hyperion::Components &callerComp)
{ {
QMetaObject::invokeMethod(_hyperion, "setVisiblePriority", Qt::QueuedConnection, Q_ARG(int, priority)); QMetaObject::invokeMethod(_hyperion, "setVisiblePriority", Qt::QueuedConnection, Q_ARG(int, priority));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setVisiblePriority", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, priority), Q_ARG(hyperion::Components, callerComp));
} }
void API::registerInput(const int &priority, const hyperion::Components &component, const QString &origin, const QString &owner, const hyperion::Components &callerComp) void API::registerInput(const int &priority, const hyperion::Components &component, const QString &origin, const QString &owner, const hyperion::Components &callerComp)
@ -255,7 +241,6 @@ void API::registerInput(const int &priority, const hyperion::Components &compone
_activeRegisters.insert({priority, registerData{component, origin, owner, callerComp}}); _activeRegisters.insert({priority, registerData{component, origin, owner, callerComp}});
QMetaObject::invokeMethod(_hyperion, "registerInput", Qt::QueuedConnection, Q_ARG(int, priority), Q_ARG(hyperion::Components, component), Q_ARG(QString, origin), Q_ARG(QString, owner)); QMetaObject::invokeMethod(_hyperion, "registerInput", Qt::QueuedConnection, Q_ARG(int, priority), Q_ARG(hyperion::Components, component), Q_ARG(QString, origin), Q_ARG(QString, owner));
//QMetaObject::invokeMethod(ApiSync::getInstance(), "registerInput", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, priority), Q_ARG(hyperion::Components, component), Q_ARG(QString, origin), Q_ARG(QString, owner), Q_ARG(hyperion::Components, callerComp));
} }
void API::unregisterInput(const int &priority) void API::unregisterInput(const int &priority)

View File

@ -626,8 +626,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString
// ACTIVE EFFECT INFO // ACTIVE EFFECT INFO
QJsonArray activeEffects; QJsonArray activeEffects;
const std::list<ActiveEffectDefinition> &activeEffectsDefinitions = _hyperion->getActiveEffects(); for (const ActiveEffectDefinition &activeEffectDefinition : _hyperion->getActiveEffects())
for (const ActiveEffectDefinition &activeEffectDefinition : activeEffectsDefinitions)
{ {
if (activeEffectDefinition.priority != PriorityMuxer::LOWEST_PRIORITY - 1) if (activeEffectDefinition.priority != PriorityMuxer::LOWEST_PRIORITY - 1)
{ {
@ -1236,7 +1235,9 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject &message, const QString &
sendSuccessDataReply(QJsonDocument(arr), command + "-" + subc, tan); sendSuccessDataReply(QJsonDocument(arr), command + "-" + subc, tan);
} }
else else
{
sendErrorReply("No Authorization", command + "-" + subc, tan); sendErrorReply("No Authorization", command + "-" + subc, tan);
}
return; return;
} }
@ -1411,60 +1412,43 @@ void JsonAPI::handleLedDeviceCommand(const QJsonObject &message, const QString &
} }
else else
*/ { */ {
QJsonObject config;
config.insert("type", devType);
LedDevice* ledDevice = nullptr;
if (subc == "discover") if (subc == "discover")
{ {
QJsonObject config; ledDevice = LedDeviceFactory::construct(config);
config.insert("type", devType); const QJsonObject devicesDiscovered = ledDevice->discover();
// Pointer of current led device
LedDevice* _ledDevice;
_ledDevice = LedDeviceFactory::construct(config);
QJsonObject devicesDiscovered = _ledDevice->discover();
Debug(_log, "response: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData() ); Debug(_log, "response: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData() );
sendSuccessDataReply(QJsonDocument(devicesDiscovered), full_command, tan);
delete _ledDevice; sendSuccessDataReply(QJsonDocument(devicesDiscovered), full_command, tan);
} }
else if (subc == "getProperties") else if (subc == "getProperties")
{ {
ledDevice = LedDeviceFactory::construct(config);
const QJsonObject &params = message["params"].toObject(); const QJsonObject &params = message["params"].toObject();
const QJsonObject deviceProperties = ledDevice->getProperties(params);
QJsonObject config;
config.insert("type", devType);
// Pointer of current led device
LedDevice* _ledDevice;
_ledDevice = LedDeviceFactory::construct(config);
QJsonObject deviceProperties = _ledDevice->getProperties(params);
Debug(_log, "response: [%s]", QString(QJsonDocument(deviceProperties).toJson(QJsonDocument::Compact)).toUtf8().constData() ); Debug(_log, "response: [%s]", QString(QJsonDocument(deviceProperties).toJson(QJsonDocument::Compact)).toUtf8().constData() );
sendSuccessDataReply(QJsonDocument(deviceProperties), full_command, tan);
delete _ledDevice; sendSuccessDataReply(QJsonDocument(deviceProperties), full_command, tan);
} }
else if (subc == "identify") else if (subc == "identify")
{ {
ledDevice = LedDeviceFactory::construct(config);
const QJsonObject &params = message["params"].toObject(); const QJsonObject &params = message["params"].toObject();
ledDevice->identify(params);
QJsonObject config;
config.insert("type", devType);
// Pointer of current led device
LedDevice* _ledDevice;
_ledDevice = LedDeviceFactory::construct(config);
_ledDevice->identify(params);
sendSuccessReply(full_command, tan); sendSuccessReply(full_command, tan);
delete _ledDevice;
} }
else else
{ {
sendErrorReply("Unknown or missing subcommand", full_command, tan); sendErrorReply("Unknown or missing subcommand", full_command, tan);
} }
delete ledDevice;
} }
} }

View File

@ -148,13 +148,16 @@ bool JsonCB::subscribeFor(const QString& type, const bool & unsubscribe)
return true; return true;
} }
void JsonCB::resetSubscriptions(void){ void JsonCB::resetSubscriptions()
for(const auto & entry : getSubscribedCommands()){ {
for(const auto & entry : getSubscribedCommands())
{
subscribeFor(entry, true); subscribeFor(entry, true);
} }
} }
void JsonCB::setSubscriptionsTo(Hyperion* hyperion){ void JsonCB::setSubscriptionsTo(Hyperion* hyperion)
{
// get current subs // get current subs
QStringList currSubs(getSubscribedCommands()); QStringList currSubs(getSubscribedCommands());

View File

@ -16,6 +16,7 @@
// utils // utils
#include <utils/hyperion.h> #include <utils/hyperion.h>
#include <utils/GlobalSignals.h> #include <utils/GlobalSignals.h>
#include <utils/Logger.h>
// Leddevice includes // Leddevice includes
#include <leddevice/LedDeviceWrapper.h> #include <leddevice/LedDeviceWrapper.h>
@ -80,7 +81,7 @@ void Hyperion::start()
_hwLedCount = qMax(unsigned(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount())), getLedCount()); _hwLedCount = qMax(unsigned(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount())), getLedCount());
// init colororder vector // init colororder vector
for (Led& led : _ledString.leds()) for (const Led& led : _ledString.leds())
{ {
_ledStringColorOrder.push_back(led.colorOrder); _ledStringColorOrder.push_back(led.colorOrder);
} }
@ -190,8 +191,6 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
} }
else if(type == settings::LEDS) else if(type == settings::LEDS)
{ {
QMutexLocker lock(&_changes);
const QJsonArray leds = config.array(); const QJsonArray leds = config.array();
// stop and cache all running effects, as effects depend heavily on ledlayout // stop and cache all running effects, as effects depend heavily on ledlayout
@ -207,7 +206,7 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
_ledBuffer = color; _ledBuffer = color;
_ledStringColorOrder.clear(); _ledStringColorOrder.clear();
for (Led& led : _ledString.leds()) for (const Led& led : _ledString.leds())
{ {
_ledStringColorOrder.push_back(led.colorOrder); _ledStringColorOrder.push_back(led.colorOrder);
} }
@ -224,7 +223,6 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
} }
else if(type == settings::DEVICE) else if(type == settings::DEVICE)
{ {
QMutexLocker lock(&_changes);
QJsonObject dev = config.object(); QJsonObject dev = config.object();
// handle hwLedCount update // handle hwLedCount update
@ -237,7 +235,7 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
_imageProcessor->setLedString(_ledString); _imageProcessor->setLedString(_ledString);
_ledStringColorOrder.clear(); _ledStringColorOrder.clear();
for (Led& led : _ledString.leds()) for (const Led& led : _ledString.leds())
{ {
_ledStringColorOrder.push_back(led.colorOrder); _ledStringColorOrder.push_back(led.colorOrder);
} }
@ -258,7 +256,7 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
update(); update();
} }
QJsonDocument Hyperion::getSetting(const settings::type& type) QJsonDocument Hyperion::getSetting(const settings::type& type) const
{ {
return _settingsManager->getSetting(type); return _settingsManager->getSetting(type);
} }
@ -270,7 +268,7 @@ bool Hyperion::saveSettings(QJsonObject config, const bool& correct)
int Hyperion::getLatchTime() const int Hyperion::getLatchTime() const
{ {
return _ledDeviceWrapper->getLatchTime(); return _ledDeviceWrapper->getLatchTime();
} }
unsigned Hyperion::addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay) unsigned Hyperion::addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay)
@ -308,7 +306,7 @@ void Hyperion::setNewComponentState(const hyperion::Components& component, const
_componentRegister.setNewComponentState(component, state); _componentRegister.setNewComponentState(component, state);
} }
std::map<hyperion::Components, bool> Hyperion::getAllComponents() std::map<hyperion::Components, bool> Hyperion::getAllComponents() const
{ {
return _componentRegister.getRegister(); return _componentRegister.getRegister();
} }
@ -409,7 +407,7 @@ const QStringList & Hyperion::getAdjustmentIds() const
return _raw2ledAdjustment->getAdjustmentIds(); return _raw2ledAdjustment->getAdjustmentIds();
} }
ColorAdjustment * Hyperion::getAdjustment(const QString& id) ColorAdjustment * Hyperion::getAdjustment(const QString& id) const
{ {
return _raw2ledAdjustment->getAdjustment(id); return _raw2ledAdjustment->getAdjustment(id);
} }
@ -457,7 +455,7 @@ QList<int> Hyperion::getActivePriorities() const
return _muxer.getPriorities(); return _muxer.getPriorities();
} }
const Hyperion::InputInfo Hyperion::getPriorityInfo(const int priority) const Hyperion::InputInfo Hyperion::getPriorityInfo(const int priority) const
{ {
return _muxer.getInputInfo(priority); return _muxer.getInputInfo(priority);
} }
@ -477,17 +475,17 @@ const std::list<EffectDefinition> & Hyperion::getEffects() const
return _effectEngine->getEffects(); return _effectEngine->getEffects();
} }
const std::list<ActiveEffectDefinition> & Hyperion::getActiveEffects() const std::list<ActiveEffectDefinition> & Hyperion::getActiveEffects() const
{ {
return _effectEngine->getActiveEffects(); return _effectEngine->getActiveEffects();
} }
const std::list<EffectSchema> & Hyperion::getEffectSchemas() const std::list<EffectSchema> & Hyperion::getEffectSchemas() const
{ {
return _effectEngine->getEffectSchemas(); return _effectEngine->getEffectSchemas();
} }
const QJsonObject& Hyperion::getQJsonConfig() const QJsonObject& Hyperion::getQJsonConfig() const
{ {
return _settingsManager->getSettings(); return _settingsManager->getSettings();
} }
@ -511,7 +509,7 @@ void Hyperion::setLedMappingType(const int& mappingType)
} }
} }
const int & Hyperion::getLedMappingType() int Hyperion::getLedMappingType() const
{ {
return _imageProcessor->getUserLedMappingType(); return _imageProcessor->getUserLedMappingType();
} }
@ -521,12 +519,12 @@ void Hyperion::setVideoMode(const VideoMode& mode)
emit videoMode(mode); emit videoMode(mode);
} }
const VideoMode & Hyperion::getCurrentVideoMode() VideoMode Hyperion::getCurrentVideoMode() const
{ {
return _currVideoMode; return _currVideoMode;
} }
const QString & Hyperion::getActiveDeviceType() QString Hyperion::getActiveDeviceType() const
{ {
return _ledDeviceWrapper->getActiveDeviceType(); return _ledDeviceWrapper->getActiveDeviceType();
} }
@ -540,8 +538,6 @@ void Hyperion::handleVisibleComponentChanged(const hyperion::Components &comp)
void Hyperion::update() void Hyperion::update()
{ {
QMutexLocker lock(&_changes);
// Obtain the current priority channel // Obtain the current priority channel
int priority = _muxer.getCurrentPriority(); int priority = _muxer.getCurrentPriority();
const PriorityMuxer::InputInfo priorityInfo = _muxer.getInputInfo(priority); const PriorityMuxer::InputInfo priorityInfo = _muxer.getInputInfo(priority);
@ -554,7 +550,9 @@ void Hyperion::update()
_ledBuffer = _imageProcessor->process(image); _ledBuffer = _imageProcessor->process(image);
} }
else else
{
_ledBuffer = priorityInfo.ledColors; _ledBuffer = priorityInfo.ledColors;
}
// emit rawLedColors before transform // emit rawLedColors before transform
emit rawLedColors(_ledBuffer); emit rawLedColors(_ledBuffer);

View File

@ -11,10 +11,12 @@
#include <utils/JsonUtils.h> #include <utils/JsonUtils.h>
// qt // qt
#include <QMutexLocker>
#include <QThread> #include <QThread>
#include <QDir> #include <QDir>
LedDeviceRegistry LedDeviceWrapper::_ledDeviceMap = LedDeviceRegistry(); LedDeviceRegistry LedDeviceWrapper::_ledDeviceMap {};
QMutex LedDeviceWrapper::_ledDeviceMapLock {QMutex::Recursive};
LedDeviceWrapper::LedDeviceWrapper(Hyperion* hyperion) LedDeviceWrapper::LedDeviceWrapper(Hyperion* hyperion)
: QObject(hyperion) : QObject(hyperion)
@ -47,18 +49,16 @@ void LedDeviceWrapper::createLedDevice(const QJsonObject& config)
// create thread and device // create thread and device
QThread* thread = new QThread(this); QThread* thread = new QThread(this);
thread->setObjectName("LedDeviceWrapperThread"); thread->setObjectName("LedDeviceThread");
_ledDevice = LedDeviceFactory::construct(config); _ledDevice = LedDeviceFactory::construct(config);
_ledDevice->moveToThread(thread); _ledDevice->moveToThread(thread);
// setup thread management // setup thread management
connect(thread, &QThread::started, _ledDevice, &LedDevice::start); connect(thread, &QThread::started, _ledDevice, &LedDevice::start);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
connect(thread, &QThread::finished, _ledDevice, &LedDevice::deleteLater);
// further signals // further signals
connect(this, &LedDeviceWrapper::updateLeds, _ledDevice, &LedDevice::updateLeds, Qt::QueuedConnection); connect(this, &LedDeviceWrapper::updateLeds, _ledDevice, &LedDevice::updateLeds, Qt::QueuedConnection);
connect(this, &LedDeviceWrapper::setEnable, _ledDevice, &LedDevice::setEnable); connect(this, &LedDeviceWrapper::setEnable, _ledDevice, &LedDevice::setEnable);
connect(this, &LedDeviceWrapper::closeLedDevice, _ledDevice, &LedDevice::stop, Qt::BlockingQueuedConnection); connect(this, &LedDeviceWrapper::closeLedDevice, _ledDevice, &LedDevice::stop, Qt::BlockingQueuedConnection);
connect(_ledDevice, &LedDevice::enableStateChanged, this, &LedDeviceWrapper::handleInternalEnableState, Qt::QueuedConnection); connect(_ledDevice, &LedDevice::enableStateChanged, this, &LedDeviceWrapper::handleInternalEnableState, Qt::QueuedConnection);
@ -73,11 +73,10 @@ const QJsonObject LedDeviceWrapper::getLedDeviceSchemas()
Q_INIT_RESOURCE(LedDeviceSchemas); Q_INIT_RESOURCE(LedDeviceSchemas);
// read the JSON schema from the resource // read the JSON schema from the resource
QDir d(":/leddevices/"); QDir dir(":/leddevices/");
QStringList l = d.entryList();
QJsonObject result, schemaJson; QJsonObject result, schemaJson;
for(QString &item : l) for(QString &item : dir.entryList())
{ {
QString schemaPath(QString(":/leddevices/")+item); QString schemaPath(QString(":/leddevices/")+item);
QString devName = item.remove("schema-"); QString devName = item.remove("schema-");
@ -105,33 +104,46 @@ const QJsonObject LedDeviceWrapper::getLedDeviceSchemas()
int LedDeviceWrapper::addToDeviceMap(QString name, LedDeviceCreateFuncType funcPtr) int LedDeviceWrapper::addToDeviceMap(QString name, LedDeviceCreateFuncType funcPtr)
{ {
QMutexLocker lock(&_ledDeviceMapLock);
_ledDeviceMap.emplace(name,funcPtr); _ledDeviceMap.emplace(name,funcPtr);
return 0; return 0;
} }
const LedDeviceRegistry& LedDeviceWrapper::getDeviceMap() const LedDeviceRegistry& LedDeviceWrapper::getDeviceMap()
{ {
QMutexLocker lock(&_ledDeviceMapLock);
return _ledDeviceMap; return _ledDeviceMap;
} }
int LedDeviceWrapper::getLatchTime() int LedDeviceWrapper::getLatchTime()
{ {
return _ledDevice->getLatchTime(); int value = 0;
QMetaObject::invokeMethod(_ledDevice, "getLatchTime", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, value));
return value;
} }
const QString & LedDeviceWrapper::getActiveDeviceType() QString LedDeviceWrapper::getActiveDeviceType()
{ {
return _ledDevice->getActiveDeviceType(); QString value = 0;
QMetaObject::invokeMethod(_ledDevice, "getActiveDeviceType", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, value));
return value;
} }
const QString & LedDeviceWrapper::getColorOrder() QString LedDeviceWrapper::getColorOrder()
{ {
return _ledDevice->getColorOrder(); QString value;
QMetaObject::invokeMethod(_ledDevice, "getColorOrder", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, value));
return value;
} }
unsigned int LedDeviceWrapper::getLedCount() const unsigned int LedDeviceWrapper::getLedCount() const
{ {
return _ledDevice->getLedCount(); unsigned int value = 0;
QMetaObject::invokeMethod(_ledDevice, "getLedCount", Qt::BlockingQueuedConnection, Q_RETURN_ARG(unsigned int, value));
return value;
} }
bool LedDeviceWrapper::enabled() bool LedDeviceWrapper::enabled()
@ -146,7 +158,8 @@ void LedDeviceWrapper::handleComponentState(const hyperion::Components component
emit setEnable(state); emit setEnable(state);
//Get device's state, considering situations where it is not ready //Get device's state, considering situations where it is not ready
bool deviceState = _ledDevice->componentState(); bool deviceState = false;
QMetaObject::invokeMethod(_ledDevice, "componentState", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, deviceState));
_hyperion->setNewComponentState(hyperion::COMP_LEDDEVICE, deviceState); _hyperion->setNewComponentState(hyperion::COMP_LEDDEVICE, deviceState);
_enabled = deviceState; _enabled = deviceState;
} }
@ -162,7 +175,7 @@ void LedDeviceWrapper::stopDeviceThread()
{ {
// turns the LEDs off & stop refresh timers // turns the LEDs off & stop refresh timers
emit closeLedDevice(); emit closeLedDevice();
std::cout << "[hyperiond LedDeviceWrapper] <INFO> LedDevice \'" << QSTRING_CSTR(_ledDevice->getActiveDeviceType()) << "\' closed" << std::endl; std::cout << "[hyperiond LedDeviceWrapper] <INFO> LedDevice \'" << QSTRING_CSTR(getActiveDeviceType()) << "\' closed" << std::endl;
// get current thread // get current thread
QThread* oldThread = _ledDevice->thread(); QThread* oldThread = _ledDevice->thread();