1
0
Fork 0

use callbacks to process alternate start codes

This commit is contained in:
Kevin Matz 2023-04-26 09:59:14 -04:00
parent 7802f201e0
commit dafa95ec76
2 changed files with 53 additions and 40 deletions

View File

@ -182,52 +182,38 @@ void Universe::setValue(const uint16_t address, const uint8_t value)
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
return; // no 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

View File

@ -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;