use callbacks to process alternate start codes
This commit is contained in:
parent
7802f201e0
commit
dafa95ec76
|
@ -182,52 +182,38 @@ void Universe::setValue(const uint16_t address, const uint8_t value)
|
||||||
void Universe::setData(const std::vector<uint8_t>& data)
|
void Universe::setData(const std::vector<uint8_t>& data)
|
||||||
{
|
{
|
||||||
if (data.empty())
|
if (data.empty())
|
||||||
return; // no data
|
return; // no data
|
||||||
|
switch (data.front()) {
|
||||||
if (data.front() != E111_NULL_START)
|
case E111_NULL_START:
|
||||||
return setAltData(data); // Alternate Start Code
|
rx_dimmer_data_(data);
|
||||||
|
break;
|
||||||
// accept variable lenth input, but never more than the limit
|
default:
|
||||||
const auto max_length = null_start_data.size();
|
if (rx_handlers_.count(data.front()))
|
||||||
const auto length = data.size() < max_length ? data.size() : max_length;
|
if (auto sp = rx_handlers_.at(data.front()).lock())
|
||||||
{
|
(*sp)(data); // the owner is still holding the token
|
||||||
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::setAltData
|
* @brief Universe::onRxData
|
||||||
* @param data
|
* @param code
|
||||||
*
|
* @param cb
|
||||||
* The base class implimentation is to discard the data.
|
* @return
|
||||||
*
|
|
||||||
* \attention re-impliment this method to rx custom alternate start code data.
|
|
||||||
*/
|
*/
|
||||||
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())
|
std::unique_lock lk_ctl(mtx_control);
|
||||||
{
|
// wrap the callback with a shared pointer
|
||||||
case E111_ASC_TEXT_ASCII:
|
auto sp = std::make_shared<std::function<void(const std::vector<uint8_t>&)>>(std::move(cb));
|
||||||
break;
|
// add callback to list (as a weak pointer)
|
||||||
case E111_ASC_TEST:
|
if (rx_handlers_.count(code))
|
||||||
break;
|
rx_handlers_[code] = sp;
|
||||||
case E111_ASC_TEXT_UTF8:
|
else
|
||||||
break;
|
rx_handlers_.insert({code, sp});
|
||||||
case E111_ASC_MANUFACTURER:
|
// return token that caller must keep throughout it's scope
|
||||||
break;
|
return sp;
|
||||||
case E111_ASC_SIP:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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_
|
* @brief Universe::rx_timeout_
|
||||||
* @param add_now
|
* @param add_now
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
@ -58,8 +59,8 @@ class Universe {
|
||||||
const uint8_t* const data);
|
const uint8_t* const data);
|
||||||
virtual void setValue(const uint16_t address, const uint8_t value);
|
virtual void setValue(const uint16_t address, const uint8_t value);
|
||||||
virtual void setData(const std::vector<uint8_t> &);
|
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> onDataChange(const std::function<void(Universe*)>);
|
||||||
std::shared_ptr<void> onStatusChange(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
|
std::chrono::system_clock::time_point last_updated_; //!< time of the latest update
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void rx_dimmer_data_(const std::vector<uint8_t> &);
|
||||||
void rx_timeout_(bool add_now = false);
|
void rx_timeout_(bool add_now = false);
|
||||||
|
|
||||||
const int rx_timeout_period_;
|
const int rx_timeout_period_;
|
||||||
uint8_t status_; //!< the operating state of the universe
|
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::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_dataChange;
|
||||||
std::vector<std::weak_ptr<const std::function<void(Universe*)>>> cb_statusChange;
|
std::vector<std::weak_ptr<const std::function<void(Universe*)>>> cb_statusChange;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user