1
0
Fork 0

Provenance can be a POD struct

This commit is contained in:
Kevin Matz 2021-08-27 12:09:19 -04:00
parent 2a26e7fa49
commit 193899b4d7
6 changed files with 113 additions and 193 deletions

View File

@ -238,7 +238,7 @@ Universe* MergeProxyUniverse::dominant_() const
{
if (uni->rxRate() < (DMX::E111_DATA_LOSS_TIMEOUT / 1000.0))
continue; // stale universes cannot be dominant
if (!ret || uni->source()->priority() > ret->source()->priority())
if (!ret || uni->source()->priority > ret->source()->priority)
ret = uni;
}
return ret;

View File

@ -25,19 +25,18 @@
#include "provenance.h"
#include "rlp/rlp.h"
namespace SACN {
namespace sACN {
/**
* @brief Provenance::Provenance
*/
Provenance::Provenance()
: cid_(UUID::uuid())
, description_(std::string())
, universe_(0)
, priority_(100)
, sync_address_(0)
, options_(0)
: cid(UUID::uuid())
, source_name(std::string())
, priority(100)
, sync_address(0)
, sequence_number(0)
, universe(0)
{}
@ -45,169 +44,58 @@ Provenance::Provenance()
* @brief Construct a Universe Source from an sACN frame PDU
* @param pdu
*/
Provenance::Provenance(std::shared_ptr<DATA::Pdu> pdu)
Provenance::Provenance(ACN::PDU::Message<DATA::Pdu> pdu)
{
auto root_header = static_cast<ACN::RLP::rlp_header*>(pdu->parent()->header());
auto frame_header = static_cast<DATA::data_header*>(pdu->header());
cid_ = root_header->cid;
description_ = frame_header->source_name;
universe_ = frame_header->universe;
priority_ = frame_header->priority;
sync_address_ = frame_header->sync_address;
options_ = frame_header->options;
cid = root_header->cid;
source_name = frame_header->source_name;
universe = frame_header->universe;
priority = frame_header->priority;
sync_address = frame_header->sync_address;
sequence_number = frame_header->sequence_number;
options = frame_header->options;
};
/**
* @brief Provenance::CID
* @return
*/
const UUID::uuid Provenance::CID() const
{
return cid_;
}
/**
* @brief Provenance::description
* @return
*/
const std::string Provenance::description() const
{
return description_;
}
/**
* @brief Provenance::universe
* @return
*/
uint16_t Provenance::universe() const
{
return universe_;
}
/**
* @brief Provenance::priority
* @return
*/
uint8_t Provenance::priority() const
{
return priority_;
}
/**
* @brief Provenance::syncAddress
* @return
*/
uint16_t Provenance::syncAddress() const
{
return sync_address_;
}
/**
* @brief Provenance::isTerminated
* @return
*/
bool Provenance::isTerminated() const
{
return options_ & DATA::STREAM_TERMINATED;
}
/**
* @brief Provenance::isPreview
* @return
*/
bool Provenance::isPreview() const
{
return options_ & DATA::PREVIEW_DATA;
}
/**
* @brief Provenance::isForced
* @return
*/
bool Provenance::isForced() const
{
return options_ & DATA::FORCE_SYNCHRONIZATION;
}
/**
* @brief operator ==
* @brief Metadata is equivalent if the CID, Priority, and Universe match.
* @param a
* @param b
* @return
*/
bool operator== (const Provenance& a, const Provenance& b)
{
return (std::hash<Provenance>{}(a) == std::hash<Provenance>{}(b));
return (a.cid == b.cid &&
a.priority == b.priority &&
a.universe == b.universe);
}
/**
* @brief Provenance::setCID
* @param cid
*/
void Provenance::setCID(UUID::uuid cid)
{
cid_ = cid;
}
/**
* @brief Provenance::setDescription
* @param desc
*/
void Provenance::setDescription(std::string desc)
{
description_ = desc;
}
/**
* @brief Provenance::setOptions
* @param o
*/
void Provenance::setOptions(uint8_t o)
{
options_ = o;
}
/**
* @brief Provenance::setUniverse
* @param n
*/
void Provenance::setUniverse(uint16_t n)
{
if (n >= 1 && n <= 63999) universe_ = n;
}
/**
* @brief Provenance::setSyncAddress
* @brief For matching universe numbers, lower priorities are lesser.
* @param a
* @param b
* @return
*/
void Provenance::setSyncAddress(uint16_t a)
bool operator< (const Provenance& a, const Provenance& b)
{
if (a >= 1 && a <= 63999) sync_address_ = a;
return (a.universe == b.universe &&
a.priority < b.priority);
}
/**
* @brief Provenance::setPriority
* @param p
* @brief For matching universe numbers, higher priorities are greater.
* @param a
* @param b
* @return
*/
void Provenance::setPriority(uint8_t p)
bool operator> (const Provenance& a, const Provenance& b)
{
if (p <= 200) priority_ = p;
return (a.universe == b.universe &&
a.priority > b.priority);
}

View File

@ -29,43 +29,75 @@
#include <cstdint>
#include <string>
namespace SACN {
namespace sACN {
/**
* @brief The Provenance class
* @brief Metadata for a sACN::Universe
*/
class Provenance
struct Provenance
{
public:
Provenance();
Provenance(std::shared_ptr<DATA::Pdu>);
explicit Provenance(ACN::PDU::Message<DATA::Pdu>);
const UUID::uuid CID() const;
const std::string description() const;
uint16_t universe() const;
uint8_t priority() const;
uint16_t syncAddress() const;
bool isTerminated() const;
bool isPreview() const;
bool isForced() const;
/// \cite sACN 5.6 CID (Component Identifier)
///
/// The Root Layer contains a CID. The CID shall be compliant with RFC 4122
/// \cite uuid.
UUID::uuid cid;
/// \cite sACN 6.2.2 E1.31 Data Packet: Source Name
///
/// A user-assigned name provided by the source of the packet for use in
/// displaying the identity of a source to a user.
///
/// If the source component implements ACN discovery as defined in EPI 19
/// \cite epi19, then this name shall be the same as the UACN field specified
/// in EPI 19 \cite epi19. User-Assigned Component Names supply a single name
/// for an entire component, so this Source Name field will exist for each
/// unique CID, but may be the same across multiple universes sourced by the
/// same component.
std::string source_name;
/// \cite sACN 6.2.3 E1.31 Data Packet: Priority
///
/// Sources that do not support variable priority shall transmit a priority
/// of 100. Priority increases with numerical value, e.g., 200 is a higher
/// priority than 100.
uint8_t priority;
/// \cite sACN 6.2.4 E1.31 Data Packet: Synchronization Address
///
/// The Synchronization Address identifies a universe number to be used for
/// universe synchronization.
uint16_t sync_address;
/// \cite sACN 6.2.5 E1.31 Data Packet: Sequence Number
///
/// Sources shall maintain a sequence for each universe they
/// transmit. The sequence number for a universe shall be incremented by one
/// for every packet sent on that universe. There is no implied relationship
/// between the sequence number of an E1.31 Synchronization Packet and the
/// sequence number of an E1.31 Data Packet on that same universe.
uint8_t sequence_number;
/// \cite sACN 6.2.6 E1.31 Data Packet: Options
///
/// This bit-oriented field is used to encode optional flags that control
/// how the packet is used.
DATA::data_options options;
/// \cite sACN 6.2.7 E1.31 Data Packet: Universe
///
/// The Universe is a 16-bit field that defines the universe number of the
/// data carried in the packet. Universe values shall be limited to the range
/// 1 to 63999.
uint16_t universe;
friend bool operator== (const Provenance& a, const Provenance& b);
void setCID(UUID::uuid cid);
void setDescription(std::string desc);
void setOptions(uint8_t o);
void setUniverse(uint16_t n);
void setSyncAddress(uint16_t a);
void setPriority(uint8_t p);
private:
UUID::uuid cid_;
std::string description_;
uint16_t universe_;
uint8_t priority_;
uint16_t sync_address_;
uint8_t options_;
friend bool operator< (const Provenance& a, const Provenance& b);
friend bool operator> (const Provenance& a, const Provenance& b);
};
} // SACN namespace
@ -75,18 +107,18 @@ namespace std
/**
* @brief The hash struct specilizaton for SACN::Provenance
*/
struct hash<SACN::Provenance>
struct hash<sACN::Provenance>
{
/**
* @brief operator ()
* @param src
* @return
*/
size_t operator()(SACN::Provenance const& src) const noexcept
size_t operator()(sACN::Provenance const& src) const noexcept
{
size_t h1 = hash<string>{}(src.description());
size_t h2 = hash<UUID::uuid>{}(src.CID());
size_t h3 = hash<int>{}(src.priority());
size_t h1 = hash<string>{}(src.source_name);
size_t h2 = hash<UUID::uuid>{}(src.cid);
size_t h3 = hash<uint8_t>{}(src.priority);
size_t h = h1 ^ h2 ^ h3; // or use boost::hash_combine
return h;
}

View File

@ -192,9 +192,9 @@ void Receiver::extendedReceiver(ACN::PDU::Message<ACN::RLP::Pdu> root)
void Receiver::dataFrameHandler(ACN::PDU::Message<DATA::Pdu> frame) {
auto source = std::shared_ptr<Provenance>(new Provenance(frame));
if (!universes_.count(source->universe()))
if (!universes_.count(source->universe))
return;
auto universe = universes_.at(source->universe())->sourceUniverse(*source);
auto universe = universes_.at(source->universe)->sourceUniverse(*source);
/// \cite sACN
/// 6.2.6 E1.31 Data Packet: Options
@ -202,7 +202,7 @@ void Receiver::dataFrameHandler(ACN::PDU::Message<DATA::Pdu> frame) {
/// 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())
if (source->options.preview_data)
return;
/// \cite sACN
@ -212,8 +212,8 @@ void Receiver::dataFrameHandler(ACN::PDU::Message<DATA::Pdu> frame) {
/// universe synchronization without waiting for a timeout to occur.
/// Any property values in an E1.31 Data Packet containing this bit
/// shall be ignored.
if (source->isTerminated()) {
universes_[source->universe()]->deleteSourceUniverse(*source);
if (source->options.stream_terminated) {
universes_[source->universe]->deleteSourceUniverse(*source);
return;
}
@ -221,8 +221,8 @@ void Receiver::dataFrameHandler(ACN::PDU::Message<DATA::Pdu> frame) {
/// 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)
subscribe(source->syncAddress());
if (source->sync_address != 0)
subscribe(source->sync_address);
// PDU data will be a block of DMP
auto block = static_cast<ACN::PDU::Block<ACN::DMP::Pdu>*>(frame->data());

View File

@ -47,9 +47,9 @@ void Source::create(const uint16_t num)
universes_.emplace(num, new Universe());
auto source = std::shared_ptr<Provenance>(new Provenance());
source->setCID(this->cid());
source->setDescription(this->name());
source->setUniverse(num);
source->cid = this->cid();
source->source_name = this->name();
source->universe = num;
universes_[num]->setProvenance(source);
}

View File

@ -127,11 +127,11 @@ TEST_F(sACNdataTest, stream_in) {
auto source = universe->source();
ASSERT_TRUE(source) << "stream failure";
EXPECT_EQ(source->CID(), cid) << "UUID mismatch";
EXPECT_EQ(source->description(), desc) << "Source Description mismatch";
EXPECT_EQ(source->universe(), univ) << "universe number mismatch";
EXPECT_EQ(source->priority(), priority) << "priority mismatch";
EXPECT_EQ(source->syncAddress(), 0) << "sync address mismatch";
EXPECT_EQ(source->cid, cid) << "UUID mismatch";
EXPECT_EQ(source->source_name, desc) << "Source Description mismatch";
EXPECT_EQ(source->universe, univ) << "universe number mismatch";
EXPECT_EQ(source->priority, priority) << "priority mismatch";
EXPECT_EQ(source->sync_address, 0) << "sync address mismatch";
EXPECT_EQ(universe->slot(512), (univ & 0xff)) << "slot 512 data mismatch";
node.unsubscribe(univ);