1
0
Fork 0

configurable merge mode for received universes

This commit is contained in:
Kevin Matz 2022-12-11 14:55:05 -05:00
parent b18fb9547f
commit 7676cd54a2
8 changed files with 300 additions and 1 deletions

View File

@ -124,6 +124,16 @@ MultiverseWindow::MultiverseWindow(QWidget *parent, QSacnNode *node)
auto univ = data.value<QSacnUniverse*>();
univ->setHoldLastLook(state);
});
connect(ui->actionMergeModeHTP, &QAction::toggled,
this, [this](bool state) {
auto selected = ui->multiverseView->currentIndex();
auto data = selected.data(Qt::EditRole);
auto univ = data.value<QSacnUniverse*>();
if (state)
univ->setMergeMode(sACN::Universe::MERGE_HTP);
else
univ->setMergeMode(sACN::Universe::MERGE_LTP);
});
connect(ui->actionAbout, &QAction::triggered,
this, [this](){
QString title = tr("About") % " " % qAppName();
@ -187,6 +197,7 @@ void MultiverseWindow::selectionChanged(const QModelIndex &current,
ui->actionUnsubscribe->setEnabled(false);
ui->actionInspect->setEnabled(false);
ui->actionUniverseHoldLastLook->setEnabled(false);
ui->menuMerge_Mode->setEnabled(false);
auto data = current.data(Qt::EditRole);
@ -196,13 +207,26 @@ void MultiverseWindow::selectionChanged(const QModelIndex &current,
auto univ = data.value<QSacnUniverse*>();
ui->actionInspect->setEnabled(true);
ui->actionUniverseHoldLastLook->setChecked(univ->getHoldLastLook());
switch (univ->getMergeMode()){
case sACN::Universe::MERGE_HTP:
ui->actionMergeModeHTP->setChecked(true);
break;
case sACN::Universe::MERGE_LTP:
ui->actionMergeModeLTP->setChecked(true);
break;
default:
break;
}
if (univ->isEditable())
ui->actionTerminate->setEnabled(true);
else
{
ui->actionUnsubscribe->setEnabled(true);
if (univ->hasSources())
ui->actionUniverseHoldLastLook->setEnabled(true);
{
ui->actionUniverseHoldLastLook->setEnabled(true);
ui->menuMerge_Mode->setEnabled(true);
}
}
return;
}

View File

@ -180,6 +180,16 @@ bool QSacnUniverse::getHoldLastLook() const
}
/**
* @brief QSacnUniverse::getMergeMode
* @return
*/
sACN::Universe::MergeMode QSacnUniverse::getMergeMode() const
{
return universe_ ? universe_->getMergeMode() : sACN::Universe::MERGE_OTHER;
}
/**
* @brief QSacnUniverse::setHoldLastLook
* @param state
@ -194,6 +204,20 @@ void QSacnUniverse::setHoldLastLook(bool state)
}
/**
* @brief QSacnUniverse::setMergeMode
* @param mode
*/
void QSacnUniverse::setMergeMode(const sACN::Universe::MergeMode mode)
{
if (isEditable())
return;
if (universe_)
universe_->setMergeMode(mode);
}
/**
* @brief QSacnUniverse::setOptions
* @param o

View File

@ -35,9 +35,11 @@ public:
const QList<sACN::DATA::data_header> sources() const;
QSacnUniverse* sourceUniverse(const sACN::DATA::data_header&) const;
bool getHoldLastLook() const;
sACN::Universe::MergeMode getMergeMode() const;
public slots:
void setHoldLastLook(bool state);
void setMergeMode(const sACN::Universe::MergeMode);
void setOptions(sACN::DATA::data_options o);
void setPriority(uint8_t p);
void setSyncAddress(uint16_t a);

View File

@ -16,6 +16,8 @@ target_sources(${PROJECT_NAME}
extended.h
arbitratinguniverse.cpp
arbitratinguniverse.h
merginguniverse.h
merginguniverse.cpp
node.cpp
receiver.cpp
sacn.h

View File

@ -0,0 +1,160 @@
/*
merginguniverse.cpp
Copyright (c) 2022 Kevin Matz (kevin.matz@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "merginguniverse.h"
namespace sACN {
MergingUniverse::MergingUniverse()
: Universe()
{
}
/**
* @brief MergingUniverse::age
* @return The minimum age of the souce universes.
*/
long MergingUniverse::age() const
{
if (sources_.empty())
return 0;
std::vector<uint16_t> ages;
ages.reserve(sources_.size());
for (const auto& universe: sources_)
ages.push_back(universe->age());
return *std::min_element(ages.begin(), ages.end());
}
/**
* @brief MergingUniverse::rxRate
* @return The maximum rxRate of the source universes.
*/
double MergingUniverse::rxRate()
{
if (sources_.empty())
return -1;
std::vector<uint16_t> rates;
rates.reserve(sources_.size());
for (const auto& universe: sources_)
rates.push_back(universe->rxRate());
return *std::max_element(rates.begin(), rates.end());
}
uint8_t MergingUniverse::status() const
{
if (sources_.empty())
return DMX_NULL;
std::vector<uint16_t> states;
states.reserve(sources_.size());
for (const auto& universe: sources_)
{
switch (universe->status()) {
case DMX_NULL:
continue;
case DMX_ACTIVE:
return DMX_ACTIVE;
default:
states.push_back(universe->status());
break;
}
}
if (states.empty())
return DMX_NULL;
return *std::min_element(states.begin(), states.end());
}
/**
* @brief MergingUniverse::slot
* @param address
* @return An HTP merge of the source slot values.
*/
uint8_t MergingUniverse::slot(const uint16_t address) const
{
if (sources_.empty())
return 0;
std::vector<uint16_t> values;
values.reserve(sources_.size());
for (const auto& universe: sources_)
values.push_back(universe->slot(address));
return *std::max_element(values.begin(), values.end());
}
/**
* @brief MergingUniverse::activeSlots
* @return The largest activeSlots values of the sources.
*/
uint16_t MergingUniverse::activeSlots() const
{
if (sources_.empty())
return 0;
std::vector<uint16_t> sizes;
sizes.reserve(sources_.size());
for (const auto& universe: sources_)
sizes.push_back(universe->activeSlots());
return *std::max_element(sizes.begin(), sizes.end());
}
std::shared_ptr<DATA::data_header> MergingUniverse::metadata() const
{
if (sources_.size() == 1)
return sources_.front()->metadata();
auto metadata = std::make_shared<DATA::data_header>();
metadata->source_name = "HTTP Merged Universe";
metadata->universe = expectedUniverse;
metadata->priority = expectedPriority;
return metadata;
}
/**
* @brief MergingUniverse::addSource
* @param universe
*/
void MergingUniverse::addSource(std::shared_ptr<Universe> universe)
{
sources_.push_back(universe);
}
} // namespace sACN

View File

@ -0,0 +1,55 @@
/*
merginguniverse.h
Copyright (c) 2022 Kevin Matz (kevin.matz@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#include <universe.h>
namespace sACN {
/**
* @brief The MergingUniverse class
*/
class MergingUniverse
: public Universe
{
public:
explicit MergingUniverse();
uint16_t expectedUniverse; //!< Expected universe number
uint8_t expectedPriority; //!< Expected universe priority
virtual long age() const override;
virtual double rxRate() override;
virtual uint8_t status() const override;
virtual uint8_t slot(const uint16_t) const override;
virtual uint16_t activeSlots() const override;
virtual std::shared_ptr<DATA::data_header> metadata() const override;
void addSource(std::shared_ptr<Universe>);
private:
std::vector<std::shared_ptr<Universe>> sources_;
};
} // namespace sACN

View File

@ -35,6 +35,7 @@ Universe::Universe(Source* src)
: DMX::Universe(E131_NETWORK_DATA_LOSS_TIMEOUT)
, ACN::DMP::Component(UUID::uuid(), "OpenLCP sACN Universe")
, sender_(src ? new UniverseSender(src, this) : nullptr)
, mergeMode_(MERGE_LTP)
, metadata_(std::make_shared<DATA::data_header>())
, sync_data_(nullptr)
, active_data_slots_(1) // start code
@ -236,6 +237,26 @@ bool Universe::getHoldLastLook() const
}
/**
* @brief Universe::setMergeMode
* @param mode
*/
void Universe::setMergeMode(const MergeMode mode)
{
mergeMode_ = mode;
}
/**
* @brief Universe::getMergeMode
* @return
*/
Universe::MergeMode Universe::getMergeMode() const
{
return mergeMode_;
}
void Universe::setValue (const uint16_t start, const uint16_t footprint,
const uint8_t* data)
{

View File

@ -71,6 +71,16 @@ public:
virtual std::shared_ptr<void> onSourceListChange(std::function<void()>);
virtual void setHoldLastLook(const bool);
virtual bool getHoldLastLook() const;
/**
* @brief The MergeMode enum
*/
enum MergeMode {
MERGE_OTHER,
MERGE_HTP,
MERGE_LTP
};
virtual void setMergeMode(const MergeMode);
virtual MergeMode getMergeMode() const;
// DMX::Universe overrides
virtual void setValue (const uint16_t start, const uint16_t footprint,
@ -103,6 +113,7 @@ protected:
private:
UniverseSender * sender_;
MergeMode mergeMode_;
std::shared_ptr<DATA::data_header> metadata_;
std::vector<uint8_t> * sync_data_;