1
0
Fork 0

support universe syncronization

This commit is contained in:
Kevin Matz 2021-08-06 12:36:04 -04:00
parent d7eb23a120
commit 7ad1962d3b
5 changed files with 83 additions and 35 deletions

View File

@ -50,7 +50,7 @@ Universe::~Universe()
@param uint16_t address of the requested slot.
@return const uint8_t value of the slot.
*/
uint8_t Universe::slot(const uint16_t address) const
uint8_t Universe::slot(const uint16_t address)
{
if (address == 0) return 0;
if (address > null_start_data_.size() - 1) return 0;

View File

@ -57,7 +57,7 @@ class Universe {
virtual ~Universe ();
virtual const DimmerData * data() const { return &null_start_data_; }
virtual uint8_t slot (const uint16_t) const;
virtual uint8_t slot (const uint16_t);
virtual double rxRate();
void setValue (const uint16_t, const uint8_t);

View File

@ -23,6 +23,7 @@
*/
#include "receiver.h"
#include "build/has_rtti.h"
namespace SACN {
@ -198,11 +199,12 @@ void Receiver::dataFrameHandler(std::shared_ptr<DATA::Pdu> frame) {
// 6.2.6 E1.31 Data Packet: Options
// Preview_Data: Bit 7 (most significant bit)
// This bit, when set to 1, indicates that the data in this packet is intended for use in visualization or media server preview applications and shall not be used to generate live output.
// This bit, when set to 1, indicates that the data in this packet is
// intended for use in visualization or media server preview applications and
// shall not be used to generate live output.
if (source->isPreview())
return;
// 6.2.6 E1.31 Data Packet: Options
// Stream_Terminated: Bit 6
// allow E1.31 sources to terminate transmission of a stream or of
@ -214,32 +216,11 @@ void Receiver::dataFrameHandler(std::shared_ptr<DATA::Pdu> frame) {
return;
}
// 6.2.6 E1.31 Data Packet: Options
// Force_Synchronization: Bit 5
// This bit indicates whether to lock or revert to an unsynchronized state
// when synchronization is lost. When set to 0, components that had been
// operating in a synchronized state shall not update with any new packets
// until synchronization resumes. When set to 1, once synchronization has
// been lost, components that had been operating in a synchronized state need
// not wait for a new E1.31 Synchronization Packet in order to update to the
// next E1.31 Data Packet.
if (!source->isForced() &&
universe->isSyncronized()) {
return; // operate in synchronized state?
}
// 6.2.4.1 Synchronization Address Usage in an E1.31 Data Packet
// a value of 0 in the Synchronization Address indicates that the universe
// data is not synchronized.
if (source->syncAddress() != 0) {
/// TODO: do somthing to engage synchronization
}
// If a receiver is presented with an E1.31 Data Packet containing a
// Synchronization Address of 0, it shall discard any data waiting to be
// processed and immediately act on that Data Packet.
if (source->syncAddress() == 0 && universe->isSyncronized()) {
/// TODO:: do something to break synchronization
}
if (source->syncAddress() != 0)
subscribe(source->syncAddress());
// PDU data will be a block of DMP
auto block = PDU::Block<DMP::Pdu>();
@ -266,9 +247,14 @@ void Receiver::dataFrameHandler(std::shared_ptr<DATA::Pdu> frame) {
* @brief Receiver::syncFrameHandler
* @param frame
*/
void Receiver::syncFrameHandler(__attribute__((unused)) std::shared_ptr<EXTENDED::Pdu> frame)
void Receiver::syncFrameHandler(std::shared_ptr<EXTENDED::Pdu> frame)
{
/// TODO: Universe sync
#if defined(RTTI_ENABLED)
auto header = dynamic_cast<EXTENDED::frame_sync_header*>(frame->header());
#else
auto header = static_cast<EXTENDED::frame_sync_header*>(frame->header());
#endif
universes_.at(header->sync_address)->synchronize();
}

View File

@ -82,8 +82,8 @@ bool operator== (const UniverseSource& a, const UniverseSource& b)
*/
Universe::Universe()
: DMX::Universe()
, synchronized_(false)
{
sync_data_.clear();
};
@ -150,7 +150,16 @@ void Universe::set(std::shared_ptr<DMP::Pdu> dmp,
// 7.7 Property Values (DMX512-A Data)
// The DMP Layer's Property values field is used to encode the
// DMX512-A [DMX] START Code and data.
DMX::Universe::setData(data);
// 6.2.4.1 If a receiver is presented with an E1.31 Data Packet containing a
// Synchronization Address of 0, it shall discard any data waiting to be
// processed and immediately act on that Data Packet.
if (source->syncAddress() == 0) {
sync_data_.clear();
DMX::Universe::setData(data);
}
else
sync_data_ = data;
}
@ -164,17 +173,56 @@ void Universe::setSource(std::shared_ptr<UniverseSource> source)
}
uint8_t Universe::slot(const uint16_t addr)
{
// 6.2.6 E1.31 Data Packet: Options
// Force_Synchronization: Bit 5
// This bit indicates whether to lock or revert to an unsynchronized state
// when synchronization is lost. When set to 0, components that had been
// operating in a synchronized state shall not update with any new packets
// until synchronization resumes. When set to 1, once synchronization has
// been lost, components that had been operating in a synchronized state need
// not wait for a new E1.31 Synchronization Packet in order to update to the
// next E1.31 Data Packet.
if (isSyncronized() && source()->isForced() && rxRate() == 0)
synchronize();
return DMX::Universe::slot(addr);
}
/**
* @brief Universe::synchronize
*/
void Universe::synchronize()
{
if (!isSyncronized())
return;
DMX::Universe::setData(sync_data_);
sync_data_.clear();
}
/**
* @brief MergeProxyUniverse::MergeProxyUniverse
*/
MergeProxyUniverse::MergeProxyUniverse()
: SACN::Universe()
{
}
/**
* @brief MergeProxyUniverse::~MergeProxyUniverse
*/
MergeProxyUniverse::~MergeProxyUniverse()
{
for (auto& [_, universe] : sources_)
delete universe;
}
/**
* @brief MergeProxyUniverse::sources
* @return
@ -305,6 +353,16 @@ void MergeProxyUniverse::set(std::shared_ptr<DMP::Pdu> pdu,
}
/**
* @brief MergeProxyUniverse::synchronize
*/
void MergeProxyUniverse::synchronize()
{
for ( auto& [_, uni] : sources_)
uni->synchronize();
}
/**
* @brief MergeProxyUniverse::data
* @return
@ -322,7 +380,7 @@ const DMX::DimmerData * MergeProxyUniverse::data() const
* @param s
* @return
*/
uint8_t MergeProxyUniverse::slot(const uint16_t s) const
uint8_t MergeProxyUniverse::slot(const uint16_t s)
{
auto universe = dominant_();
if (!universe) return 0;

View File

@ -108,15 +108,18 @@ public:
Universe();
~Universe();
virtual bool isSyncronized() const { return synchronized_; };
virtual bool isSyncronized() const { return (sync_data_.size() > 0); };
virtual std::shared_ptr<UniverseSource> source() const { return source_; }
virtual uint8_t slot (const uint16_t) override;
virtual void set(std::shared_ptr<DMP::Pdu>, std::shared_ptr<UniverseSource>);
virtual void setSource(std::shared_ptr<UniverseSource>);
virtual void synchronize();
private:
bool synchronized_;
std::shared_ptr<UniverseSource> source_;
std::vector<uint8_t> sync_data_;
};
@ -148,10 +151,11 @@ public:
std::shared_ptr<UniverseSource> source() const override;
void set(std::shared_ptr<DMP::Pdu>, std::shared_ptr<UniverseSource>) override;
void setSource(std::shared_ptr<UniverseSource>) override {};
void synchronize() override;
// DMX::Universe Overrides:
const DMX::DimmerData *data() const override;
uint8_t slot(const uint16_t) const override;
uint8_t slot(const uint16_t) override;
double rxRate() override;
private: