rearrange header
This commit is contained in:
parent
f9f0d1298e
commit
39a6bcbfbf
|
@ -39,10 +39,47 @@ Universe::Universe(int timeout_period)
|
|||
|
||||
|
||||
/**
|
||||
* @brief Universe::~Universe
|
||||
* @brief milliseconds since the last update
|
||||
* @return
|
||||
*/
|
||||
Universe::~Universe()
|
||||
long Universe::age()
|
||||
{
|
||||
if (!last_updated_.time_since_epoch().count())
|
||||
return -1; // universe has never been seen
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_updated_);
|
||||
|
||||
return elapsed.count();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::rxRate Rate (in Hz) at which the universe is being recv'd.
|
||||
* @return Hz
|
||||
*
|
||||
* Calculated as the rolling mean of (the number of frames in
|
||||
* the last rx_timeout_peroid ms) / rx_timeout_period seconds.
|
||||
*/
|
||||
double Universe::rxRate()
|
||||
{
|
||||
rx_timeout_();
|
||||
// updates per second
|
||||
return rx_times_.size() / (rx_timeout_period_ / 1000.0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::status
|
||||
* @return
|
||||
*
|
||||
* Like Schrödinger's cat, the status of the universe may exist in a superpostion
|
||||
* of states. Only by observing it will it collaps into a single status.
|
||||
*/
|
||||
uint8_t Universe::status()
|
||||
{
|
||||
rx_timeout_(); // many things may have happened since the last observation
|
||||
return status_;
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,33 +100,53 @@ uint8_t Universe::slot(const uint16_t address)
|
|||
|
||||
|
||||
/**
|
||||
* @brief Universe::rxRate Rate (in Hz) at which the universe is being recv'd.
|
||||
* @return Hz
|
||||
*
|
||||
* Calculated as the rolling mean of (the number of frames in
|
||||
* the last rx_timeout_peroid ms) / rx_timeout_period seconds.
|
||||
* @brief Universe::setStatus
|
||||
* @param val
|
||||
*/
|
||||
double Universe::rxRate()
|
||||
void Universe::setStatus(uint8_t val)
|
||||
{
|
||||
rx_timeout_();
|
||||
// updates per second
|
||||
return rx_times_.size() / (rx_timeout_period_ / 1000.0);
|
||||
if (val == RX_TIMEOUT)
|
||||
val = DMX_LOST;
|
||||
|
||||
if (val == status_)
|
||||
return;
|
||||
|
||||
status_ = val;
|
||||
do_callbacks_(cb_statusChange);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief milliseconds since the last update
|
||||
* @return
|
||||
* @brief Universe::setValue
|
||||
* @param start
|
||||
* @param footprint
|
||||
* @param data
|
||||
*/
|
||||
long Universe::age()
|
||||
void Universe::setValue(const uint16_t start, const uint16_t footprint,
|
||||
const uint8_t * const data)
|
||||
{
|
||||
if (!last_updated_.time_since_epoch().count())
|
||||
return -1; // universe has never been seen
|
||||
// start and footprint valid?
|
||||
if (start < 1 || start + footprint > null_start_data.size())
|
||||
return;
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_updated_);
|
||||
null_start_mutex.lock();
|
||||
std::copy_n(data, footprint, null_start_data.begin() + start);
|
||||
null_start_mutex.unlock();
|
||||
|
||||
return elapsed.count();
|
||||
setStatus(DMX_ACTIVE);
|
||||
last_updated_ = std::chrono::system_clock::now();
|
||||
do_callbacks_(cb_dataChange);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::setValue
|
||||
* @param address
|
||||
* @param value
|
||||
*/
|
||||
void Universe::setValue(const uint16_t address, const uint8_t value)
|
||||
{
|
||||
setValue(address, 1, &value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,17 +158,16 @@ long Universe::age()
|
|||
*/
|
||||
void Universe::setData(const std::vector<uint8_t>& data)
|
||||
{
|
||||
// no data?
|
||||
if (data.empty())
|
||||
return;
|
||||
return; // no data
|
||||
|
||||
// Alternate Start Code
|
||||
if (data.front() != E111_NULL_START)
|
||||
return altSCdata(data);
|
||||
return altSCdata(data); // Alternate Start Code
|
||||
|
||||
// accept variable lenth input, but never more than the limit
|
||||
const auto max_length = null_start_data.size();
|
||||
const auto length = data.size() < max_length ? data.size() : max_length;
|
||||
|
||||
null_start_mutex.lock(); // take the lock
|
||||
if (length < max_length)
|
||||
null_start_data.fill(0); // wipe old data
|
||||
|
@ -147,87 +203,6 @@ void Universe::altSCdata(const std::vector<uint8_t> & data)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::status
|
||||
* @return
|
||||
*
|
||||
* Like Schrödinger's cat, the status of the universe may exist in a superpostion
|
||||
* of states. Only by observing it will it collaps into a single status.
|
||||
*/
|
||||
uint8_t Universe::status()
|
||||
{
|
||||
rx_timeout_(); // many things may have happened since the last observation
|
||||
return status_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::setStatus
|
||||
* @param val
|
||||
*/
|
||||
void Universe::setStatus(uint8_t val)
|
||||
{
|
||||
if (val == RX_TIMEOUT)
|
||||
val = DMX_LOST;
|
||||
|
||||
if (val == status_)
|
||||
return;
|
||||
|
||||
status_ = val;
|
||||
do_callbacks_(cb_statusChange);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::onStatusChange
|
||||
* @param cb
|
||||
* @return
|
||||
*/
|
||||
std::shared_ptr<void> Universe::onStatusChange(const std::function<void(Universe*)> cb)
|
||||
{
|
||||
// wrap the callback with a shared pointer
|
||||
auto sp = std::make_shared<std::function<void(Universe*)>>(std::move(cb));
|
||||
// add callback to list (as a weak pointer)
|
||||
cb_statusChange.push_back(sp);
|
||||
// return token that caller must keep throughout it's scope
|
||||
return sp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::setValue
|
||||
* @param address
|
||||
* @param value
|
||||
*/
|
||||
void Universe::setValue(const uint16_t address, const uint8_t value)
|
||||
{
|
||||
setValue(address, 1, &value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::setValue
|
||||
* @param start
|
||||
* @param footprint
|
||||
* @param data
|
||||
*/
|
||||
void Universe::setValue(const uint16_t start, const uint16_t footprint,
|
||||
const uint8_t* data)
|
||||
{
|
||||
// start and footprint valid?
|
||||
if (start < 1 || start + footprint > null_start_data.size())
|
||||
return;
|
||||
|
||||
null_start_mutex.lock();
|
||||
std::copy_n(data, footprint, null_start_data.begin() + start);
|
||||
null_start_mutex.unlock();
|
||||
|
||||
setStatus(DMX_ACTIVE);
|
||||
last_updated_ = std::chrono::system_clock::now();
|
||||
do_callbacks_(cb_dataChange);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::onData
|
||||
* @param cb
|
||||
|
@ -245,23 +220,18 @@ std::shared_ptr<void> Universe::onDataChange(const std::function<void(Universe*)
|
|||
|
||||
|
||||
/**
|
||||
* @brief Universe::doCallbacks
|
||||
* @param callbacks
|
||||
* @brief Universe::onStatusChange
|
||||
* @param cb
|
||||
* @return
|
||||
*/
|
||||
void Universe::do_callbacks_(std::vector<std::weak_ptr<const std::function<void(Universe*)>>> & callbacks)
|
||||
std::shared_ptr<void> Universe::onStatusChange(const std::function<void(Universe*)> cb)
|
||||
{
|
||||
for (auto it = callbacks.begin(); it != callbacks.end();)
|
||||
{
|
||||
if (auto sp = it->lock())
|
||||
{ // the owner is still holding the token
|
||||
(*sp)(this);
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{ // the owner has released the token
|
||||
it = callbacks.erase(it);
|
||||
}
|
||||
}
|
||||
// wrap the callback with a shared pointer
|
||||
auto sp = std::make_shared<std::function<void(Universe*)>>(std::move(cb));
|
||||
// add callback to list (as a weak pointer)
|
||||
cb_statusChange.push_back(sp);
|
||||
// return token that caller must keep throughout it's scope
|
||||
return sp;
|
||||
}
|
||||
|
||||
|
||||
|
@ -301,4 +271,24 @@ void Universe::rx_timeout_(bool add_now)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::doCallbacks
|
||||
* @param callbacks
|
||||
*/
|
||||
void Universe::do_callbacks_(std::vector<std::weak_ptr<const std::function<void(Universe*)>>> & callbacks)
|
||||
{
|
||||
for (auto it = callbacks.begin(); it != callbacks.end();)
|
||||
{
|
||||
if (auto sp = it->lock())
|
||||
{ // the owner is still holding the token
|
||||
(*sp)(this);
|
||||
++it;
|
||||
}
|
||||
else
|
||||
// the owner has released the token
|
||||
it = callbacks.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace DMX
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
namespace DMX {
|
||||
|
||||
using DimmerData = std::array<uint8_t, E111_LAST_SLOT + 1>; //!< Array of 513 bytes for basic data.
|
||||
using DimmerData = std::array<uint8_t, E111_LAST_SLOT + 1>; //!< Array of 513 bytes for basic data.
|
||||
|
||||
/**
|
||||
* @brief The Universe class
|
||||
|
@ -47,33 +47,29 @@ using DimmerData = std::array<uint8_t, E111_LAST_SLOT + 1>; //!< Array of 513 b
|
|||
class Universe {
|
||||
public:
|
||||
Universe (int timeout_period = E111_DATA_LOSS_TIMEOUT);
|
||||
virtual ~Universe ();
|
||||
|
||||
virtual uint8_t slot (const uint16_t);
|
||||
virtual double rxRate();
|
||||
virtual long age();
|
||||
virtual double rxRate();
|
||||
virtual uint8_t status();
|
||||
virtual uint8_t slot(const uint16_t);
|
||||
|
||||
virtual void setValue (const uint16_t address, const uint8_t value);
|
||||
virtual void setValue (const uint16_t start, const uint16_t footprint,
|
||||
const uint8_t* data);
|
||||
|
||||
void setData (const std::vector<uint8_t> &);
|
||||
|
||||
virtual void setStatus(uint8_t);
|
||||
virtual void setValue(const uint16_t start, const uint16_t footprint,
|
||||
const uint8_t* const data);
|
||||
virtual void setValue(const uint16_t address, const uint8_t value);
|
||||
virtual void setData(const std::vector<uint8_t> &);
|
||||
virtual void altSCdata(const std::vector<uint8_t> &);
|
||||
|
||||
std::shared_ptr<void> onDataChange(const std::function<void(Universe*)>);
|
||||
/**
|
||||
* @brief The Status enum
|
||||
*/
|
||||
std::shared_ptr<void> onStatusChange(const std::function<void(Universe*)>);
|
||||
|
||||
/// Known states of the universe Status value
|
||||
enum Status : uint8_t {
|
||||
DMX_NULL = 0, //!< uninitialized
|
||||
DMX_ACTIVE = 1, //!< actively sending/receiving data
|
||||
DMX_LOST = 2, //!< no activity in E111_DATA_LOSS_TIMEOUT
|
||||
RX_TIMEOUT = 250 //!< no activity in the constructed timeout period
|
||||
};
|
||||
virtual void setStatus(uint8_t);
|
||||
virtual uint8_t status();
|
||||
|
||||
protected:
|
||||
void doDataCallbacks() {do_callbacks_(cb_dataChange);} //!< Run Data Change Callbacks
|
||||
|
@ -84,13 +80,12 @@ class Universe {
|
|||
std::chrono::system_clock::time_point last_updated_; //!< time of the latest update
|
||||
|
||||
private:
|
||||
std::queue<std::chrono::time_point<std::chrono::system_clock>> rx_times_;
|
||||
|
||||
void rx_timeout_(bool add_now = false);
|
||||
void do_callbacks_(std::vector<std::weak_ptr<const std::function<void(Universe*)>>>&);
|
||||
const int rx_timeout_period_;
|
||||
|
||||
const int rx_timeout_period_;
|
||||
uint8_t status_; //!< the operating state of the universe
|
||||
std::queue<std::chrono::time_point<std::chrono::system_clock>> rx_times_;
|
||||
std::vector<std::weak_ptr<const std::function<void(Universe*)>>> cb_dataChange;
|
||||
std::vector<std::weak_ptr<const std::function<void(Universe*)>>> cb_statusChange;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue