AdcDeviceCommand is now parameter-less

rewrite AdcDeviceAttribute class, basic tests of AdcDeviceAttribute passed
This commit is contained in:
Timur A. Fatkhullin
2024-05-19 20:28:53 +03:00
parent 2661a60b47
commit 534d98994b
5 changed files with 244 additions and 245 deletions

View File

@@ -7,10 +7,9 @@
*/
#include <memory>
#include <string>
// #include "../common/adc_value_holder.h"
#include "../common/adc_value.h"
#include <functional>
#include "../common/adc_traits.h"
/*
@@ -19,76 +18,32 @@
namespace adc
{
template <typename IdentT, typename SerializedT = std::string>
namespace traits
{
template <typename T>
concept adc_cmd_exec_c = traits::adc_func_traits<T>::arity == 0 && !std::same_as<T, std::nullptr_t>;
} // namespace traits
template <typename IdentT = std::string_view>
class AdcDeviceCommand
{
protected:
IdentT _ident;
std::unique_ptr<AdcSerializingValueHolder<SerializedT>> _commandArgUptr;
std::function<void()> _execFuncWrapper;
std::function<void(std::any&)> _deserializerWrapper;
template <typename T>
constexpr static SerializedT AdcDeviceCommandDummySerializer(const T&)
{
return SerializedT();
}
std::function<void()> _execFunc;
public:
typedef IdentT ident_t;
typedef SerializedT serialized_t;
template <typename ExecFuncT,
typename ARGT = traits::adc_func_arg1_t<ExecFuncT>,
typename DeserializerT = decltype(utils::AdcDefaultValueConverter<>::deserialize<ARGT, SerializedT>),
typename ValidatorT = decltype(AdcValueHolder::AdcValueHolderDummyValidator<ARGT>)>
AdcDeviceCommand(const IdentT& ident,
ExecFuncT&& exec_func,
DeserializerT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize<ARGT, SerializedT>,
ValidatorT&& validator = AdcValueHolder::AdcValueHolderDummyValidator<ARGT>)
: _ident(ident), _commandArgUptr()
template <traits::adc_cmd_exec_c ExecFuncT>
AdcDeviceCommand(const IdentT& ident, ExecFuncT&& exec_func)
: _ident(ident), _execFunc(std::forward<ExecFuncT>(exec_func))
{
using sign_t = traits::adc_func_traits<ExecFuncT>;
static_assert(sign_t::arity > 1, "COMMAND EXECUTION FUNCTION MUST ACCEPT 0 OR EXACTLY 1 ARGUMENT!!!");
if constexpr (sign_t::arity) { // command with argument
using value_t = typename sign_t::arg1_t;
static_assert(std::predicate<ValidatorT, const value_t&>, "INVALID TYPE OF VALIDATOR");
static_assert(std::invocable<DeserializerT, const SerializedT&>, "INVALID TYPE OF DESERIALIZER");
static_assert(std::is_convertible_v<std::invoke_result_t<DeserializerT, const SerializedT&>, value_t>,
"INVALID RETURN TYPE OF DESERIALIZER");
auto command_arg = std::shared_ptr<value_t>(value_t());
_commandArgUptr = std::make_unique<AdcSerializingValueHolder<SerializedT>>(
[command_arg]() { return *command_arg; }, [command_arg](const value_t& value) { *command_arg = value; },
std::forward<ValidatorT>(validator));
_execFuncWrapper = [wrapper = traits::adc_pf_wrapper(std::forward<ExecFuncT>(exec_func)), this]() {
auto& exec_func = std::get<0>(wrapper);
value_t val = std::any_cast<value_t>(*_commandArgUptr);
exec_func(val);
};
_deserializerWrapper =
[wrapper = traits::adc_pf_wrapper(std::forward<DeserializerT>(deserializer))](std::any& val) {
auto& deserializer = std::get<0>(wrapper);
val = std::make_any<value_t>(deserializer(std::any_cast<SerializedT>(val)));
};
// setup only convert-to-native-value function (deserializer)
_commandArgUptr->addConvertFunc<SerializedT>(std::forward<DeserializerT>(deserializer), []() {});
} else { // command without argument (ignore deserializer and validator)
_execFuncWrapper = std::forward<ExecFuncT>(exec_func);
}
}
@@ -100,24 +55,7 @@ public:
IdentT ident() const { return ident; }
template <typename ValueT>
void operator()(const ValueT& value)
{
if (_commandArgUptr) { // command with argument
*_commandArgUptr = value;
}
_execFuncWrapper();
}
void operator()()
{
if (_commandArgUptr) { // command with argument
throw 1;
}
_execFuncWrapper();
}
void operator()() { _execFunc(); }
};