diff --git a/include/api/JsonAPI.h b/include/api/JsonAPI.h index 6b869966..9c8477c4 100644 --- a/include/api/JsonAPI.h +++ b/include/api/JsonAPI.h @@ -316,4 +316,9 @@ private: /// @param error String describing the error /// void sendErrorReply(const QString & error, const QString &command="", const int tan=0); + + /// + /// @brief Kill all signal/slot connections to stop possible data emitter + /// + void stopDataConnections(void); }; diff --git a/include/api/JsonCB.h b/include/api/JsonCB.h index e57a8445..02cb96bc 100644 --- a/include/api/JsonCB.h +++ b/include/api/JsonCB.h @@ -23,25 +23,38 @@ class JsonCB : public QObject Q_OBJECT public: - JsonCB(Hyperion* hyperion, QObject* parent); + JsonCB(QObject* parent); /// /// @brief Subscribe to future data updates given by cmd - /// @param cmd The cmd which will be subscribed for + /// @param cmd The cmd which will be subscribed for + /// @param unsubscribe Revert subscription /// @return True on success, false if not found /// - bool subscribeFor(const QString& cmd); + bool subscribeFor(const QString& cmd, const bool & unsubscribe = false); /// /// @brief Get all possible commands to subscribe for /// @return The list of commands /// QStringList getCommands() { return _availableCommands; }; + /// /// @brief Get all subscribed commands /// @return The list of commands /// QStringList getSubscribedCommands() { return _subscribedCommands; }; + + /// + /// @brief Reset subscriptions, disconnect all signals + /// + void resetSubscriptions(void); + + /// + /// @brief Re-apply all current subs to a new Hyperion instance, the connections to the old instance will be dropped + /// + void setSubscriptionsTo(Hyperion* hyperion); + signals: /// /// @brief Emits whenever a new json mesage callback is ready to send diff --git a/libsrc/api/JsonAPI.cpp b/libsrc/api/JsonAPI.cpp index fb4091b8..f83ddccc 100644 --- a/libsrc/api/JsonAPI.cpp +++ b/libsrc/api/JsonAPI.cpp @@ -51,7 +51,7 @@ JsonAPI::JsonAPI(QString peerAddress, Logger* log, const bool& localConnection, , _log(log) , _instanceManager(HyperionIManager::getInstance()) , _hyperion(nullptr) - , _jsonCB(nullptr) + , _jsonCB(new JsonCB(this)) , _streaming_logging_activated(false) , _image_stream_timeout(0) , _led_stream_timeout(0) @@ -77,6 +77,9 @@ JsonAPI::JsonAPI(QString peerAddress, Logger* log, const bool& localConnection, // listen for killed instances connect(_instanceManager, &HyperionIManager::instanceStateChanged, this, &JsonAPI::handleInstanceStateChange); + // pipe callbacks from subscriptions to parent + connect(_jsonCB, &JsonCB::newCallback, this, &JsonAPI::callbackMessage); + // init Hyperion pointer handleInstanceSwitch(0); @@ -100,30 +103,8 @@ bool JsonAPI::handleInstanceSwitch(const quint8& inst, const bool& forced) // get new Hyperion pointer _hyperion = _instanceManager->getHyperionInstance(inst); - // the JsonCB creates json messages you can subscribe to e.g. data change events; forward them to the parent client - QStringList cbCmds; - if(_jsonCB != nullptr) - { - cbCmds = _jsonCB->getSubscribedCommands(); - delete _jsonCB; - } - - _jsonCB = new JsonCB(_hyperion, this); - connect(_jsonCB, &JsonCB::newCallback, this, &JsonAPI::callbackMessage); - - // read subs - for(const auto & entry : cbCmds) - { - _jsonCB->subscribeFor(entry); - } - -// // imageStream last state -// if(_ledcolorsImageActive) -// connect(_hyperion, &Hyperion::currentImage, this, &JsonAPI::setImage, Qt::UniqueConnection); -// -// //ledColor stream last state -// if(_ledcolorsLedsActive) -// connect(_hyperion, &Hyperion::rawLedColors, this, &JsonAPI::streamLedcolorsUpdate, Qt::UniqueConnection); + // the JsonCB creates json messages you can subscribe to e.g. data change events + _jsonCB->setSubscriptionsTo(_hyperion); return true; } @@ -1156,6 +1137,8 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject & message, const QString { _authorized = false; _userAuthorized = false; + // disconnect all kind of data callbacks + stopDataConnections(); sendSuccessReply(command+"-"+subc, tan); return; } @@ -1613,3 +1596,10 @@ void JsonAPI::handleInstanceStateChange(const instanceState& state, const quint8 break; } } + +void JsonAPI::stopDataConnections(void) +{ + LoggerManager::getInstance()->disconnect(); + _jsonCB->resetSubscriptions(); + +} diff --git a/libsrc/api/JsonCB.cpp b/libsrc/api/JsonCB.cpp index 4bd8aa43..972a8ef0 100644 --- a/libsrc/api/JsonCB.cpp +++ b/libsrc/api/JsonCB.cpp @@ -27,87 +27,138 @@ using namespace hyperion; -JsonCB::JsonCB(Hyperion* hyperion, QObject* parent) +JsonCB::JsonCB(QObject* parent) : QObject(parent) - , _hyperion(hyperion) - , _componentRegister(& _hyperion->getComponentRegister()) + , _hyperion(nullptr) + , _componentRegister(nullptr) , _bonjour(BonjourBrowserWrapper::getInstance()) - , _prioMuxer(_hyperion->getMuxerInstance()) + , _prioMuxer(nullptr) { _availableCommands << "components-update" << "sessions-update" << "priorities-update" << "imageToLedMapping-update" << "adjustment-update" << "videomode-update" << "effects-update" << "settings-update" << "leds-update" << "instance-update"; } -bool JsonCB::subscribeFor(const QString& type) +bool JsonCB::subscribeFor(const QString& type, const bool & unsubscribe) { if(!_availableCommands.contains(type)) return false; + if(unsubscribe) + _subscribedCommands.removeAll(type); + else + _subscribedCommands << type; + if(type == "components-update") { - _subscribedCommands << type; - connect(_componentRegister, &ComponentRegister::updatedComponentState, this, &JsonCB::handleComponentState, Qt::UniqueConnection); + if(unsubscribe) + disconnect(_componentRegister, &ComponentRegister::updatedComponentState, this, &JsonCB::handleComponentState); + else + connect(_componentRegister, &ComponentRegister::updatedComponentState, this, &JsonCB::handleComponentState, Qt::UniqueConnection); } if(type == "sessions-update") { - _subscribedCommands << type; - connect(_bonjour, &BonjourBrowserWrapper::browserChange, this, &JsonCB::handleBonjourChange, Qt::UniqueConnection); + if(unsubscribe) + disconnect(_bonjour, &BonjourBrowserWrapper::browserChange, this, &JsonCB::handleBonjourChange); + else + connect(_bonjour, &BonjourBrowserWrapper::browserChange, this, &JsonCB::handleBonjourChange, Qt::UniqueConnection); } if(type == "priorities-update") { - _subscribedCommands << type; - connect(_prioMuxer, &PriorityMuxer::prioritiesChanged, this, &JsonCB::handlePriorityUpdate, Qt::UniqueConnection); - connect(_prioMuxer, &PriorityMuxer::autoSelectChanged, this, &JsonCB::handlePriorityUpdate, Qt::UniqueConnection); + if(unsubscribe){ + disconnect(_prioMuxer,0 ,0 ,0); + } else { + connect(_prioMuxer, &PriorityMuxer::prioritiesChanged, this, &JsonCB::handlePriorityUpdate, Qt::UniqueConnection); + connect(_prioMuxer, &PriorityMuxer::autoSelectChanged, this, &JsonCB::handlePriorityUpdate, Qt::UniqueConnection); + } } if(type == "imageToLedMapping-update") { - _subscribedCommands << type; - connect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCB::handleImageToLedsMappingChange, Qt::UniqueConnection); + if(unsubscribe) + disconnect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCB::handleImageToLedsMappingChange); + else + connect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCB::handleImageToLedsMappingChange, Qt::UniqueConnection); } if(type == "adjustment-update") { - _subscribedCommands << type; - connect(_hyperion, &Hyperion::adjustmentChanged, this, &JsonCB::handleAdjustmentChange, Qt::UniqueConnection); + if(unsubscribe) + disconnect(_hyperion, &Hyperion::adjustmentChanged, this, &JsonCB::handleAdjustmentChange); + else + connect(_hyperion, &Hyperion::adjustmentChanged, this, &JsonCB::handleAdjustmentChange, Qt::UniqueConnection); } if(type == "videomode-update") { - _subscribedCommands << type; - connect(_hyperion, &Hyperion::newVideoMode, this, &JsonCB::handleVideoModeChange, Qt::UniqueConnection); + if(unsubscribe) + disconnect(_hyperion, &Hyperion::newVideoMode, this, &JsonCB::handleVideoModeChange); + else + connect(_hyperion, &Hyperion::newVideoMode, this, &JsonCB::handleVideoModeChange, Qt::UniqueConnection); } if(type == "effects-update") { - _subscribedCommands << type; - connect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCB::handleEffectListChange, Qt::UniqueConnection); + if(unsubscribe) + disconnect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCB::handleEffectListChange); + else + connect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCB::handleEffectListChange, Qt::UniqueConnection); } if(type == "settings-update") { - _subscribedCommands << type; - connect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleSettingsChange, Qt::UniqueConnection); + if(unsubscribe) + disconnect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleSettingsChange); + else + connect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleSettingsChange, Qt::UniqueConnection); } if(type == "leds-update") { - _subscribedCommands << type; - connect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleLedsConfigChange, Qt::UniqueConnection); + if(unsubscribe) + disconnect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleLedsConfigChange); + else + connect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleLedsConfigChange, Qt::UniqueConnection); } if(type == "instance-update") { - _subscribedCommands << type; - connect(HyperionIManager::getInstance(), &HyperionIManager::change, this, &JsonCB::handleInstanceChange, Qt::UniqueConnection); + if(unsubscribe) + disconnect(HyperionIManager::getInstance(), &HyperionIManager::change, this, &JsonCB::handleInstanceChange); + else + connect(HyperionIManager::getInstance(), &HyperionIManager::change, this, &JsonCB::handleInstanceChange, Qt::UniqueConnection); } return true; } +void JsonCB::resetSubscriptions(void){ + for(const auto & entry : getSubscribedCommands()){ + subscribeFor(entry, true); + } +} + +void JsonCB::setSubscriptionsTo(Hyperion* hyperion){ + // get current subs + QStringList currSubs(getSubscribedCommands()); + + // stop subs + resetSubscriptions(); + + // update pointer + _hyperion = hyperion; + _componentRegister = &_hyperion->getComponentRegister(); + _prioMuxer = _hyperion->getMuxerInstance(); + + // re-apply subs + for(const auto & entry : currSubs) + { + subscribeFor(entry); + } +} + void JsonCB::doCallback(const QString& cmd, const QVariant& data) { QJsonObject obj;