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;
};
};