use callbacks to process alternate start codes
This commit is contained in:
parent
7802f201e0
commit
dafa95ec76
@ -183,51 +183,37 @@ void Universe::setData(const std::vector<uint8_t>& data)
|
||||
{
|
||||
if (data.empty())
|
||||
return; // no data
|
||||
|
||||
if (data.front() != E111_NULL_START)
|
||||
return setAltData(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;
|
||||
{
|
||||
std::unique_lock lk_data(mtx_data);
|
||||
if (length < max_length)
|
||||
null_start_data.fill(0); // wipe old data
|
||||
std::copy_n(data.cbegin(), length, null_start_data.begin()); // copy new data
|
||||
switch (data.front()) {
|
||||
case E111_NULL_START:
|
||||
rx_dimmer_data_(data);
|
||||
break;
|
||||
default:
|
||||
if (rx_handlers_.count(data.front()))
|
||||
if (auto sp = rx_handlers_.at(data.front()).lock())
|
||||
(*sp)(data); // the owner is still holding the token
|
||||
}
|
||||
{
|
||||
std::unique_lock lk_ctl(mtx_control);
|
||||
active_data_slots_ = length;
|
||||
}
|
||||
rx_timeout_(true); // update rx times
|
||||
do_callbacks_(cb_dataChange); // run callbacks
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::setAltData
|
||||
* @param data
|
||||
*
|
||||
* The base class implimentation is to discard the data.
|
||||
*
|
||||
* \attention re-impliment this method to rx custom alternate start code data.
|
||||
* @brief Universe::onRxData
|
||||
* @param code
|
||||
* @param cb
|
||||
* @return
|
||||
*/
|
||||
void Universe::setAltData(const std::vector<uint8_t> & data)
|
||||
std::shared_ptr<void> Universe::onRxData(uint8_t code,
|
||||
const std::function<void(const std::vector<uint8_t>&)> cb)
|
||||
{
|
||||
switch (data.front())
|
||||
{
|
||||
case E111_ASC_TEXT_ASCII:
|
||||
break;
|
||||
case E111_ASC_TEST:
|
||||
break;
|
||||
case E111_ASC_TEXT_UTF8:
|
||||
break;
|
||||
case E111_ASC_MANUFACTURER:
|
||||
break;
|
||||
case E111_ASC_SIP:
|
||||
break;
|
||||
}
|
||||
std::unique_lock lk_ctl(mtx_control);
|
||||
// wrap the callback with a shared pointer
|
||||
auto sp = std::make_shared<std::function<void(const std::vector<uint8_t>&)>>(std::move(cb));
|
||||
// add callback to list (as a weak pointer)
|
||||
if (rx_handlers_.count(code))
|
||||
rx_handlers_[code] = sp;
|
||||
else
|
||||
rx_handlers_.insert({code, sp});
|
||||
// return token that caller must keep throughout it's scope
|
||||
return sp;
|
||||
}
|
||||
|
||||
|
||||
@ -265,6 +251,30 @@ std::shared_ptr<void> Universe::onStatusChange(const std::function<void(Universe
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::rx_dimmer_data_
|
||||
* @param data
|
||||
*/
|
||||
void Universe::rx_dimmer_data_(const std::vector<uint8_t> &data)
|
||||
{
|
||||
// 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;
|
||||
{
|
||||
std::unique_lock lk_data(mtx_data);
|
||||
if (length < max_length)
|
||||
null_start_data.fill(0); // wipe old data
|
||||
std::copy_n(data.cbegin(), length, null_start_data.begin()); // copy new data
|
||||
}
|
||||
{
|
||||
std::unique_lock lk_ctl(mtx_control);
|
||||
active_data_slots_ = length;
|
||||
}
|
||||
rx_timeout_(true); // update rx times
|
||||
do_callbacks_(cb_dataChange); // run callbacks
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universe::rx_timeout_
|
||||
* @param add_now
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <shared_mutex>
|
||||
#include <queue>
|
||||
@ -58,8 +59,8 @@ class Universe {
|
||||
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 setAltData(const std::vector<uint8_t> &);
|
||||
|
||||
std::shared_ptr<void> onRxData(uint8_t, const std::function<void(const std::vector<uint8_t>&)>);
|
||||
std::shared_ptr<void> onDataChange(const std::function<void(Universe*)>);
|
||||
std::shared_ptr<void> onStatusChange(const std::function<void(Universe*)>);
|
||||
|
||||
@ -86,10 +87,12 @@ class Universe {
|
||||
std::chrono::system_clock::time_point last_updated_; //!< time of the latest update
|
||||
|
||||
private:
|
||||
void rx_dimmer_data_(const std::vector<uint8_t> &);
|
||||
void rx_timeout_(bool add_now = false);
|
||||
|
||||
const int rx_timeout_period_;
|
||||
uint8_t status_; //!< the operating state of the universe
|
||||
std::map<uint8_t, std::weak_ptr<const std::function<void(const std::vector<uint8_t>&)>>> rx_handlers_;
|
||||
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
Block a user