diff --git a/example/sACN Explorer/multiverseview.ui b/example/sACN Explorer/multiverseview.ui index 1f42adf..4707e78 100644 --- a/example/sACN Explorer/multiverseview.ui +++ b/example/sACN Explorer/multiverseview.ui @@ -70,6 +70,7 @@ sACN + @@ -226,6 +227,23 @@ Ctrl+D + + + true + + + true + + + false + + + Hold Last Look + + + Retain at least 1 inacitve source. + + diff --git a/protocol/sacn/arbitratinguniverse.cpp b/protocol/sacn/arbitratinguniverse.cpp index 78bcd6e..7bc0bc2 100644 --- a/protocol/sacn/arbitratinguniverse.cpp +++ b/protocol/sacn/arbitratinguniverse.cpp @@ -32,6 +32,7 @@ namespace sACN { ArbitratingUniverse::ArbitratingUniverse() : sACN::Universe() , expectedUniverse(0) + , HoldLastLook(true) { } @@ -44,6 +45,26 @@ ArbitratingUniverse::~ArbitratingUniverse() } +/** + * @brief ArbitratingUniverse::setHoldLastLook + * @param state + */ +void ArbitratingUniverse::setHoldLastLook(const bool state) +{ + HoldLastLook = state; +} + + +/** + * @brief ArbitratingUniverse::getHoldLastLook + * @return + */ +bool ArbitratingUniverse::getHoldLastLook() const +{ + return HoldLastLook; +} + + const std::vector ArbitratingUniverse::sources() const { std::vector keys; @@ -246,8 +267,8 @@ std::shared_ptr ArbitratingUniverse::dominant_() { auto universe = it->second; - if (!ret) - { // anything is better than nothing! + if (!ret && HoldLastLook) + { // anything is better than nothing ++it; ret = universe; continue; diff --git a/protocol/sacn/arbitratinguniverse.h b/protocol/sacn/arbitratinguniverse.h index 97c4d3e..0ff180a 100644 --- a/protocol/sacn/arbitratinguniverse.h +++ b/protocol/sacn/arbitratinguniverse.h @@ -61,6 +61,9 @@ public: uint16_t expectedUniverse; ///< Expected universe number + void setHoldLastLook(const bool); + bool getHoldLastLook() const; + // Source universes: void deleteSourceUniverse(const DATA::data_header&); void dataChangedNotifier(DMX::Universe* universe); @@ -91,6 +94,7 @@ public: private: std::unordered_map> sources_; std::vector> cb_sourceListChange; //!< list of calback functions + bool HoldLastLook; std::shared_ptr dominant_(); bool hasSourceUniverse(const DATA::data_header&) const; diff --git a/protocol/sacn/receiver.cpp b/protocol/sacn/receiver.cpp index a503fee..7a7922a 100644 --- a/protocol/sacn/receiver.cpp +++ b/protocol/sacn/receiver.cpp @@ -36,6 +36,7 @@ namespace sACN { */ Receiver::Receiver(UUID::uuid cid) : Component(cid) + , HoldLastLook(true) { fctn_ = "OpenLCP sACN Receiver"; @@ -56,6 +57,18 @@ Receiver::~Receiver() } +/** + * @brief Receiver::setHoldLastLook + * @param state + */ +void Receiver::setHoldLastLook(const bool state) +{ + HoldLastLook = state; + for (const auto & [_, universe] : universes_) + universe->setHoldLastLook(state); +} + + /** * @brief Receiver::subscribe * @param num @@ -66,6 +79,7 @@ void Receiver::subscribe(const uint16_t num) return; universes_.emplace(num, std::make_shared()); universes_.at(num)->expectedUniverse = num; + universes_.at(num)->setHoldLastLook(HoldLastLook); } @@ -222,7 +236,11 @@ void Receiver::dataFrameHandler(ACN::PDU::Message frame) { /// > Any property values in an E1.31 Data Packet containing this bit /// > shall be ignored. if (source->options.stream_terminated) - return universes_[source->universe]->deleteSourceUniverse(*source); + { + auto universe = universes_.at(source->universe); + if (universe->sources().size() > 1 || !HoldLastLook) + return universes_[source->universe]->deleteSourceUniverse(*source); + } /// > \cite sACN 6.2.4.1 Synchronization Address Usage in an E1.31 Data Packet /// > diff --git a/protocol/sacn/receiver.h b/protocol/sacn/receiver.h index fb3ced7..f298143 100644 --- a/protocol/sacn/receiver.h +++ b/protocol/sacn/receiver.h @@ -69,6 +69,8 @@ public: Receiver(UUID::uuid = UUID::uuid()); ~Receiver(); + void setHoldLastLook(const bool); + virtual void subscribe(const uint16_t); virtual void unsubscribe(const uint16_t); std::shared_ptr universe(const uint16_t); @@ -98,6 +100,7 @@ protected: private: std::unordered_map> universes_; std::vector> discoveryCallbacks_; + bool HoldLastLook; }; };