44 #ifndef CLOE_DATA_BROKER_HPP_
45 #define CLOE_DATA_BROKER_HPP_
54 #include <string_view>
58 #include <fmt/format.h>
60 #include <sol/sol.hpp>
64 namespace databroker {
71 template <
typename T,
typename =
void>
78 T, std::void_t<decltype(to_lua(std::declval<sol::state_view>(), std::declval<T*>()))>>
91 if constexpr (has_to_lua_v<T>) {
92 to_lua(lua,
static_cast<T*
>(
nullptr));
105 template <
typename T,
bool condition>
110 template <
typename T>
119 template <
typename T>
131 template <
typename T>
137 template <
typename T>
143 template <
typename T>
153 template <
typename... TArgs>
156 using EventHandler = std::function<void(TArgs...)>;
159 std::vector<EventHandler> eventhandlers_{};
165 void add(EventHandler handler) { eventhandlers_.emplace_back(std::move(handler)); }
170 [[nodiscard]] std::size_t
count()
const {
return eventhandlers_.size(); }
176 void raise(TArgs&&... args)
const {
177 for (
const auto& eventhandler : eventhandlers_) {
179 eventhandler(std::forward<decltype(args)>(args)...);
190 template <
typename T>
191 class BasicContainer;
198 template <
typename T>
200 static_assert(!
static_cast<bool>(databroker::is_incompatible_type_v<T>),
201 "Incompatible-Datatype-Error.\n"
203 "Please find the offending LOC in above line 'require from here'.\n"
205 "Explanation/Reasoning:\n"
206 "- references & void are fundamentally incompatible");
209 using SignalPtr = std::shared_ptr<Signal>;
215 std::function<void(
const SignalPtr&, sol::state_view, std::string_view)>;
222 template <
typename T>
225 template <
typename T>
234 struct access_token {
235 explicit access_token(
int ){};
248 : value_(), on_value_changed_(std::move(on_value_changed)), signal_(signal) {
249 update_accessor_functions(
this);
257 value_ = std::move(rhs.value_);
258 on_value_changed_ = std::move(rhs.on_value_changed_);
259 signal_ = std::move(rhs.signal_);
260 update_accessor_functions(
this);
262 rhs.signal_ =
nullptr;
268 if (on_value_changed_) {
269 on_value_changed_(value_);
274 const value_type& value()
const {
return value_; }
275 value_type& value() {
return value_; }
278 [[nodiscard]]
bool has_subscriber()
const;
279 [[nodiscard]] std::size_t subscriber_count()
const;
282 constexpr
const value_type* operator->()
const noexcept {
return &value_; }
283 constexpr value_type* operator->() noexcept {
return &value_; }
284 constexpr
const value_type& operator*()
const noexcept {
return value_; }
285 constexpr value_type& operator*() noexcept {
return value_; }
295 template <
typename T,
typename U>
299 template <
typename T,
typename U>
300 constexpr
bool operator!=(
const BasicContainer<T>& lhs,
const BasicContainer<U>& rhs) {
303 template <
typename T,
typename U>
304 constexpr
bool operator<(
const BasicContainer<T>& lhs,
const BasicContainer<U>& rhs) {
307 template <
typename T,
typename U>
308 constexpr
bool operator<=(
const BasicContainer<T>& lhs,
const BasicContainer<U>& rhs) {
311 template <
typename T,
typename U>
312 constexpr
bool operator>(
const BasicContainer<T>& lhs,
const BasicContainer<U>& rhs) {
315 template <
typename T,
typename U>
316 constexpr
bool operator>=(
const BasicContainer<T>& lhs,
const BasicContainer<U>& rhs) {
322 template <
typename T,
typename U>
323 constexpr
bool operator==(
const BasicContainer<T>& lhs,
const U& rhs) {
326 template <
typename T,
typename U>
327 constexpr
bool operator==(
const T& lhs,
const BasicContainer<U>& rhs) {
330 template <
typename T,
typename U>
331 constexpr
bool operator!=(
const BasicContainer<T>& lhs,
const U& rhs) {
334 template <
typename T,
typename U>
335 constexpr
bool operator!=(
const T& lhs,
const BasicContainer<U>& rhs) {
338 template <
typename T,
typename U>
339 constexpr
bool operator<(
const BasicContainer<T>& lhs,
const U& rhs) {
342 template <
typename T,
typename U>
343 constexpr
bool operator<(
const T& lhs,
const BasicContainer<U>& rhs) {
346 template <
typename T,
typename U>
347 constexpr
bool operator<=(
const BasicContainer<T>& lhs,
const U& rhs) {
350 template <
typename T,
typename U>
351 constexpr
bool operator<=(
const T& lhs,
const BasicContainer<U>& rhs) {
354 template <
typename T,
typename U>
355 constexpr
bool operator>(
const BasicContainer<T>& lhs,
const U& rhs) {
358 template <
typename T,
typename U>
359 constexpr
bool operator>(
const T& lhs,
const BasicContainer<U>& rhs) {
362 template <
typename T,
typename U>
363 constexpr
bool operator>=(
const BasicContainer<T>& lhs,
const U& rhs) {
366 template <
typename T,
typename U>
367 constexpr
bool operator>=(
const T& lhs,
const BasicContainer<U>& rhs) {
386 using metainformation_map_t = std::unordered_map<std::type_index, std::any>;
387 metainformation_map_t metainformations_;
393 template <
typename T>
404 template <
typename T>
405 constexpr
void assert_static_type() {
407 static_assert(std::is_reference_v<typename T::tag_type> ==
false,
408 "References are unsupported.");
412 template <
typename T>
418 auto tindex = std::type_index(
typeid(T));
419 auto iter = metainformations_.find(tindex);
420 if (iter != metainformations_.end()) {
421 metainformations_.erase(iter);
429 template <
typename T>
431 auto tindex = std::type_index(
typeid(T));
432 auto iter = metainformations_.find(tindex);
433 if (iter != metainformations_.end()) {
435 metainformations_[tindex] = std::move(metainformation_any);
442 template <
typename T>
444 auto tindex = std::type_index(
typeid(T));
445 auto iter = metainformations_.find(tindex);
446 if (iter != metainformations_.end()) {
447 const std::any& metainformation_any = iter->second;
448 return &metainformation_any;
458 template <
typename T>
459 std::enable_if_t<!std::is_void_v<typename T::tag_type>,
const typename T::tag_type>*
get()
const {
460 const std::any* metainformation_any = get_any<T>();
461 return (metainformation_any !=
nullptr)
462 ? std::any_cast<typename T::tag_type>(metainformation_any)
470 template <
typename T>
471 std::enable_if_t<std::is_void_v<typename T::tag_type>,
bool>
get()
const {
472 const std::any* metainformation_any = get_any<T>();
473 return (metainformation_any !=
nullptr);
482 template <
typename T>
485 !std::is_void_v<typename T::tag_type>
486 && !std::is_base_of_v< Tag< T >, T >
487 && std::is_move_constructible_v<typename T::tag_type>
490 add(
typename T::tag_type metainformation) {
491 assert_static_type<T>();
493 std::any metainformation_any = std::move(metainformation);
494 add_any<T>(std::move(metainformation_any));
502 template <
typename T>
505 !std::is_void_v<typename T::tag_type>
506 && !std::is_base_of_v< Tag< T >, T >
507 && std::is_copy_constructible_v<typename T::tag_type>
508 && !std::is_move_constructible_v<typename T::tag_type>
511 add(
const typename T::tag_type& metainformation) {
512 assert_static_type<T>();
514 std::any metainformation_any = metainformation;
515 add_any<T>(std::move(metainformation_any));
522 template <
typename T>
525 std::is_void_v<typename T::tag_type>
529 std::any metainformation_any;
530 add_any<T>(std::move(metainformation_any));
550 template <
typename T>
553 std::is_base_of_v< Tag< T >, T >
554 && std::is_same_v<T, typename T::tag_type>
558 assert_static_type<T>();
560 std::any metainformation_any = std::move(metainformation);
561 add_any<T>(std::move(metainformation_any));
578 template <
typename T,
typename... TArgs>
581 std::is_base_of_v< Tag< T >, T >
582 && std::is_same_v<T, typename T::tag_type>
586 assert_static_type<T>();
587 T metainformation(std::forward<TArgs>(args)...);
588 std::any metainformation_any = std::move(metainformation);
589 add_any<T>(std::move(metainformation_any));
612 #define LUADATATYPE_LIST \
617 enum class LuaDatatype {
618 #define X(name, value) name = value,
623 friend std::string to_string(LuaDatatype type) {
625 #define X(name, value) \
626 case LuaDatatype::name: \
634 #undef LUADATATYPE_LIST
639 #define PHYSICALQUANTITIES_LIST \
640 X(Dimensionless, "[]") \
645 X(Temperature, "[K]") \
646 X(ElectricCurrent, "[A]") \
647 X(Velocity, "[m/s]") \
648 X(Acceleration, "[m/s^2]") \
650 X(Jounce, "[m/s^4]") \
651 X(Crackle, "[m/s^5]")
653 enum class PhysicalQuantity {
654 #define X(name, value) name,
659 friend std::string to_string(PhysicalQuantity type) {
661 #define X(name, value) \
662 case PhysicalQuantity::name: \
670 #undef PHYSICALQUANTITIES_LIST
687 :
datatype{std::move(datatype_)},
unit{std::move(unit_)},
text{std::move(text_)} {}
708 struct access_token {
709 explicit access_token(
int ){};
727 template <
typename T>
729 using type_erased_get_value_function_t = std::any;
734 template <
typename T>
736 using type_erased_set_value_function_t = std::any;
740 template <
typename T>
742 using type_erased_value_changed_event_t = std::any;
746 template <
typename T>
749 using type_erased_on_value_change_event_function_t = std::any;
753 std::vector<std::string> names_{};
755 const std::type_info* type_{
nullptr};
757 type_erased_get_value_function_t get_value_{};
759 type_erased_set_value_function_t set_value_{};
761 type_erased_value_changed_event_t value_changed_event_{};
763 type_erased_on_value_change_event_function_t on_value_changed_{};
765 std::function<std::size_t()> subscriber_count_{};
767 MetaInformation metainformations_;
783 virtual ~
Signal() =
default;
790 constexpr
const std::type_info*
type()
const {
return type_; }
798 template <
typename T>
799 constexpr
void assert_dynamic_type()
const {
800 const std::type_info* static_type = &
typeid(T);
801 const std::type_info* dynamic_type =
type();
802 if ((dynamic_type ==
nullptr) || (!(*dynamic_type == *static_type))) {
803 throw std::logic_error(
804 fmt::format(
"mismatch between dynamic-/actual-type and static-/requested-type; "
805 "signal type: {}, requested type: {}",
806 dynamic_type !=
nullptr ? dynamic_type->name() :
"", static_type->name()));
824 template <
typename T>
826 assert_static_type<T>();
827 assert_dynamic_type<T>();
830 std::any_cast<typed_get_value_function_t<T>>(&get_value_);
854 template <
typename T>
856 assert_static_type<T>();
857 assert_dynamic_type<T>();
859 get_value_ = std::move(get_value_fn);
869 template <
typename T>
871 assert_static_type<T>();
872 assert_dynamic_type<T>();
876 if (getter_fn && (*getter_fn)) {
880 throw std::logic_error(
881 fmt::format(
"unable to get value for signal without getter-function: {}", names_.front()));
890 template <
typename T>
892 assert_static_type<T>();
893 assert_dynamic_type<T>();
896 std::any_cast<typed_set_value_function_t<T>>(&set_value_);
906 template <
typename T>
908 assert_static_type<T>();
909 assert_dynamic_type<T>();
911 set_value_ = std::move(set_value_fn);
920 template <
typename T>
922 assert_static_type<T>();
923 assert_dynamic_type<T>();
927 if (setter_fn && *setter_fn) {
928 setter_fn->operator()(
value);
931 throw std::logic_error(
932 fmt::format(
"unable to set value for signal without setter-function: {}", names_.front()));
941 template <
typename T>
943 assert_static_type<T>();
944 assert_dynamic_type<T>();
947 std::any_cast<typed_on_value_change_event_function_t<T>>(&on_value_changed_);
959 template <
typename T>
960 std::enable_if_t<!std::is_void_v<typename T::tag_type>>
add(
typename T::tag_type
metadata) {
961 static_assert(std::is_reference_v<typename T::tag_type> ==
false);
972 template <
typename T,
typename... TArgs>
973 std::enable_if_t<!std::is_void_v<typename T::tag_type>>
add(TArgs&&... args) {
974 static_assert(std::is_reference_v<typename T::tag_type> ==
false);
975 metainformations_.add<T>(std::forward<TArgs>(args)...);
983 template <
typename T>
986 std::is_void_v<typename T::tag_type>
990 metainformations_.add<T>();
999 template <
typename T>
1000 auto metadata() -> decltype(metainformations_.get<T>()) {
1001 return metainformations_.get<T>();
1016 template <
typename T>
1017 void subscribe_impl(
1019 typed_value_changed_event_t<T>* value_changed_event =
1020 std::any_cast<typed_value_changed_event_t<T>>(&value_changed_event_);
1022 assert(value_changed_event);
1023 callback(*value_changed_event);
1034 template <
typename T>
1036 assert_static_type<T>();
1037 assert_dynamic_type<T>();
1041 value_changed_event.
add(std::move(callback));
1064 const std::vector<std::string>&
names()
const {
return names_; }
1072 if (names_.empty()) {
1073 throw std::logic_error(
"signal does not have a name");
1075 return names_.front();
1084 if (names_.empty()) {
1087 return names_.front();
1106 template <
typename T>
1107 static std::unique_ptr<Signal> make() {
1108 assert_static_type<T>();
1111 auto signal = std::make_unique<Signal>(access_token(0));
1112 signal->initialize<compatible_type>();
1123 template <
typename T>
1124 BasicContainer<T> create_container() {
1125 assert_static_type<T>();
1127 typed_value_changed_event_t<T>* value_changed_event =
1128 std::any_cast<typed_value_changed_event_t<T>>(&value_changed_event_);
1130 BasicContainer<T> result = BasicContainer<T>(
1132 [value_changed_event](databroker::signal_type_cref_t<T>
value) {
1133 value_changed_event->raise(std::move(
value));
1135 typename BasicContainer<T>::access_token(0));
1141 template <
typename T>
1143 assert_static_type<T>();
1147 value_changed_event_ = typed_value_changed_event_t<T>();
1148 typed_value_changed_event_t<T>* value_changed_event =
1149 &std::any_cast<typed_value_changed_event_t<T>&>(value_changed_event_);
1151 typed_on_value_change_event_function_t<T> on_value_changed =
1152 [value_changed_event](databroker::signal_type_cref_t<T>
value) {
1153 value_changed_event->raise(std::move(
value));
1155 on_value_changed_ = on_value_changed;
1157 subscriber_count_ = [value_changed_event]() {
return value_changed_event->count(); };
1160 template <
typename T>
1161 friend class BasicContainer;
1165 template <
typename T>
1166 void BasicContainer<T>::update_accessor_functions(BasicContainer* container) {
1167 if (signal_ !=
nullptr) {
1170 signal_->template set_getter<T>(
1171 [container]() -> databroker::signal_type_cref_t<T> {
return container->value(); });
1172 signal_->template set_setter<T>(
1173 [container](databroker::signal_type_cref_t<T>
value) { container->set_value(
value); });
1175 signal_->template set_getter<T>(Signal::typed_get_value_function_t<T>());
1176 signal_->template set_setter<T>(Signal::typed_set_value_function_t<T>());
1181 template <
typename T>
1182 bool BasicContainer<T>::has_subscriber()
const {
1183 return signal_ !=
nullptr && signal_->has_subscriber();
1186 template <
typename T>
1187 std::size_t BasicContainer<T>::subscriber_count()
const {
1188 return signal_ !=
nullptr ? signal_->subscriber_count() : 0;
1194 template <
typename T>
1200 TypedSignal(SignalPtr signal) : signal_{signal} {}
1203 operator SignalPtr&() {
return signal_; }
1204 operator const SignalPtr&()
const {
return signal_; }
1206 const T& value()
const {
return signal_->template value<T>(); }
1208 template <
typename TSetter>
1209 void set_setter(TSetter setter) {
1210 signal_->template set_setter<T>(std::move(setter));
1219 using SignalContainer = std::map<std::string, SignalPtr, std::less<>>;
1222 SignalContainer signals_{};
1223 std::unordered_map<std::type_index, lua_signal_adapter_t> bindings_{};
1224 std::unordered_map<std::type_index, bool> lua_declared_types_{};
1228 explicit DataBroker(
const sol::state_view& lua) : lua_(lua), signals_object_(*lua_) {}
1239 class SignalsObject {
1244 using lua_getter_fn = std::function<sol::object(sol::this_state&)>;
1248 using lua_setter_fn = std::function<void(sol::stack_object&)>;
1252 struct lua_accessor {
1259 using accessors = std::unordered_map<std::string, lua_accessor>;
1263 accessors accessors_;
1267 sol::usertype<SignalsObject> signals_table_;
1270 SignalsObject(sol::state_view& lua)
1272 , signals_table_(lua.new_usertype<SignalsObject>(
1273 "SignalsObject", sol::meta_function::new_index, &SignalsObject::set_property_lua,
1274 sol::meta_function::index, &SignalsObject::get_property_lua)) {}
1281 sol::object get_property_lua(
const char* name, sol::this_state s) {
1282 auto iter = accessors_.find(name);
1283 if (iter != accessors_.end()) {
1284 auto result = iter->second.getter(s);
1287 throw std::out_of_range(
1288 fmt::format(
"Failure to access signal '{}' from Lua since it is not bound.", name));
1296 void set_property_lua(
const char* name, sol::stack_object
object) {
1297 auto iter = accessors_.find(name);
1298 if (iter != accessors_.end()) {
1299 iter->second.setter(
object);
1301 throw std::out_of_range(
1302 fmt::format(
"Failure to access signal '{}' from Lua since it is not bound.", name));
1308 template <
typename T>
1311 using value_type = T;
1312 static lua_accessor make(
const SignalPtr&
signal) {
1313 lua_accessor result;
1314 result.getter = [
signal](sol::this_state& state) -> sol::object {
1315 const value_type&
value =
signal->value<value_type>();
1316 return sol::make_object(state,
value);
1318 result.setter = [
signal](sol::stack_object& obj) ->
void {
1319 T
value = obj.as<value_type>();
1329 template <
typename T>
1331 using type = std::optional<T>;
1332 using value_type = T;
1333 static lua_accessor make(
const SignalPtr&
signal) {
1334 lua_accessor result;
1335 result.getter = [
signal](sol::this_state& state) -> sol::object {
1338 return sol::make_object(state,
value.value());
1340 return sol::make_object(state, sol::lua_nil);
1343 result.setter = [
signal](sol::stack_object& obj) ->
void {
1345 if (obj != sol::lua_nil) {
1346 value = obj.as<value_type>();
1359 template <
typename T>
1360 void bind(
const SignalPtr&
signal, std::string_view lua_name) {
1362 auto inserted = accessors_.try_emplace(std::string(lua_name), std::move(accessor));
1363 if (!inserted.second) {
1364 throw std::out_of_range(fmt::format(
1365 "Failure adding lua-accessor for signal {}. Name already exists.", lua_name));
1372 std::optional<sol::state_view> lua_{};
1376 std::optional<SignalsObject> signals_object_{};
1383 template <
typename T>
1385 assert_static_type<T>();
1388 if (lua_.has_value()) {
1389 std::type_index type{
typeid(compatible_type)};
1390 auto iter = lua_declared_types_.find(type);
1391 if (iter == lua_declared_types_.end()) {
1392 lua_declared_types_[type] =
true;
1394 type_declarator(*lua_);
1404 template <
typename T>
1406 assert_static_type<T>();
1408 if (lua_.has_value()) {
1410 std::type_index type{
typeid(compatible_type)};
1411 auto iter = bindings_.find(type);
1412 if (iter == bindings_.end()) {
1414 auto declared_types_iter = lua_declared_types_.find(type);
1415 if (declared_types_iter == lua_declared_types_.end()) {
1416 lua_declared_types_[type] =
true;
1417 ::cloe::databroker::detail::to_lua<T>(*lua_);
1422 std::string_view lua_name) {
1425 signal->subscribe<T>([](
const T&) {});
1427 signals_object_->bind<T>(
signal, lua_name);
1430 bindings_.emplace(type, std::move(adapter));
1442 void bind_signal(std::string_view signal_name, std::string_view lua_name) {
1443 if (!lua_.has_value()) {
1444 throw std::logic_error(
1445 "DataBroker: Binding a signal to Lua must not happen, before binding the Lua "
1450 auto type = std::type_index(*
signal->type());
1452 auto iter = bindings_.find(type);
1453 if (iter == bindings_.end()) {
1454 throw std::runtime_error(
1455 "DataBroker: <internal logic error>: Lua type binding not implemented");
1458 adapter(
signal, (*lua_), lua_name);
1473 void bind(std::string_view signals_name, sol::table parent) {
1474 parent[signals_name] = &(*signals_object_);
1477 void bind(std::string_view signals_name) { (*lua_)[signals_name] = &(*signals_object_); }
1486 [[nodiscard]]
const SignalContainer::const_iterator
operator[](std::string_view name)
const {
1487 SignalContainer::const_iterator iter = signals_.find(name);
1497 [[nodiscard]] SignalContainer::iterator
operator[](std::string_view name) {
1498 SignalContainer::iterator iter = signals_.find(name);
1511 if (new_name.empty()) {
1512 throw std::invalid_argument(
1513 fmt::format(
"alias for signal must not be empty: {}",
signal->name_or(
"<unnamed>")));
1517 std::pair<SignalContainer::iterator, bool> inserted =
1518 signals_.try_emplace(std::string(new_name), std::move(
signal));
1519 if (!inserted.second) {
1520 throw std::out_of_range(fmt::format(
"cannot alias signal '{}' to '{}': name already exists",
1521 signal->name_or(
"<unnamed>"), new_name));
1525 SignalPtr result = inserted.first->second;
1526 result->add_name(new_name);
1530 signals_.erase(inserted.first);
1544 SignalPtr
alias(std::string_view old_name, std::string_view new_name,
1545 std::regex::flag_type f = std::regex_constants::ECMAScript) {
1546 std::regex regex = std::regex(std::string(old_name), f);
1550 const auto predicate = [&](
const auto& item) ->
bool {
1552 return std::regex_match(item.first, match, regex);
1554 it1 = (it1 != end) ? std::find_if(it1, end, predicate) : end;
1555 it2 = (it1 != end) ? std::find_if(std::next(it1), end, predicate) : end;
1557 throw std::out_of_range(
1558 fmt::format(
"regex pattern matches multiple signals: '{}'; matches: '{}', '{}'", old_name,
1559 it1->first, it2->first));
1562 throw std::out_of_range(fmt::format(
"regex pattern matches zero signals: {}", old_name));
1565 SignalPtr result =
alias(it1->second, new_name);
1576 template <
typename T>
1578 assert_static_type<T>();
1581 declare<compatible_type>();
1583 SignalPtr
signal = Signal::make<compatible_type>();
1596 template <
typename T>
1597 SignalPtr
declare(std::string_view name, T* value_ptr) {
1598 assert(value_ptr !=
nullptr);
1599 auto signal = this->declare<T>(name);
1600 signal->template set_getter<T>([value_ptr]() ->
const T& {
1603 signal->template set_setter<T>([value_ptr](
const T&
value) {
1609 template <
typename T>
1610 SignalPtr declare(std::string_view name, std::function<T()>
getter, std::function<
void(T)>
setter) {
1611 auto signal = this->declare<T>(name);
1628 template <
typename T>
1630 assert_static_type<T>();
1633 declare<compatible_type>();
1635 SignalPtr
signal = declare<compatible_type>(new_name);
1645 [[nodiscard]] SignalPtr
signal(std::string_view name)
const {
1646 auto iter = (*this)[name];
1647 if (iter != signals_.end()) {
1648 return iter->second;
1650 throw std::out_of_range(fmt::format(
"signal not found: {}", name));
1659 [[nodiscard]] SignalPtr
signal(std::string_view name) {
1660 auto iter = (*this)[name];
1661 if (iter != signals_.end()) {
1662 return iter->second;
1664 throw std::out_of_range(fmt::format(
"signal not found: {}", name));
1670 [[nodiscard]]
const SignalContainer&
signals()
const {
return signals_; }
1677 return const_cast<SignalContainer&
>(
const_cast<const DataBroker*
>(
this)->
signals());
1687 template <
typename T>
1689 assert_static_type<T>();
1692 signal(name)->template subscribe<compatible_type>(std::move(callback));
1702 template <
typename T>
1704 assert_static_type<T>();
1718 template <
typename T>
1720 assert_static_type<T>();
1723 return signal(name)->value<compatible_type>();
1733 template <
typename T>
1735 assert_static_type<T>();
1739 signal(name)->getter<compatible_type>();
1741 throw std::logic_error(fmt::format(
"getter for signal not provided: {}", name));
1752 template <
typename T>
1754 assert_static_type<T>();
1757 signal(name)->set_getter<compatible_type>(getter_fn);
1767 template <
typename T>
1769 assert_static_type<T>();
1773 signal(name)->setter<compatible_type>();
1775 throw std::logic_error(fmt::format(
"setter for signal not provided: {}", name));
1786 template <
typename T>
1788 assert_static_type<T>();
1791 signal(name)->set_setter<compatible_type>(setter_fn);
1795 namespace databroker {
1798 static constexpr
bool STATIC =
false;
1805 const std::string& name()
const {
return name_; }
1808 template <const
char* NAME>
1810 static constexpr
bool STATIC =
true;
1811 static constexpr
const char* name() {
return NAME; }
1821 template <
typename T,
typename TNAME,
bool = TNAME::STATIC>
1830 template <
typename T,
typename TNAME>
1869 db.
set_getter<T>(name(), std::move(get_value_fn));
1885 db.
set_setter<T>(name(), std::move(set_value_fn));
1909 template <
typename T,
typename TNAME>
1948 db.
set_getter<T>(name(), std::move(get_value_fn));
1964 db.
set_setter<T>(name(), std::move(set_value_fn));
1988 template <
typename T, const
char* NAME>
1997 template <
typename T>
2013 template <
typename T, const
char* NAME =
nullptr>
2018 template <
typename T, const
char* NAME>
2021 template <
template <
typename>
class TARGET,
typename... ARGS>
2022 static auto format(ARGS&&... args) {
2024 return TARGET<T>(name);
2028 template <
typename... ARGS>
2029 static auto specialize(ARGS&&... args) {
2030 return format<SignalDescriptor>(std::forward<ARGS>(args)...);
2033 template <
typename... ARGS>
2034 static auto partial(ARGS&&... args) {
2035 return format<SignalTemplate>(std::forward<ARGS>(args)...);
2060 #define CLOE_DATABROKER_TEMPLATE_INSTANTIATION(elem) \
2061 extern template class BasicContainer<elem>; \
2062 extern template const Signal::typed_get_value_function_t<elem>* Signal::getter<elem>() const; \
2063 extern template void Signal::set_getter<elem>(Signal::typed_get_value_function_t<elem>); \
2064 extern template databroker::signal_type_cref_t<elem> Signal::value<elem>() const; \
2065 extern template const Signal::typed_set_value_function_t<elem>* Signal::setter<elem>() const; \
2066 extern template void Signal::set_setter<elem>(Signal::typed_set_value_function_t<elem>); \
2067 extern template void Signal::set_value<elem>(databroker::signal_type_cref_t<elem> value) const; \
2068 extern template const Signal::typed_on_value_change_event_function_t<elem>& \
2069 Signal::trigger<elem>() const; \
2070 extern template void Signal::subscribe_impl<elem>( \
2071 const std::function<void(databroker::Event<databroker::signal_type_cref_t<elem>>&)>&); \
2072 extern template void Signal::subscribe<elem>(databroker::on_value_changed_callback_t<elem>); \
2073 extern template std::unique_ptr<Signal> Signal::make<elem>(); \
2074 extern template BasicContainer<elem> Signal::create_container<elem>(); \
2075 extern template void Signal::initialize<elem>(); \
2076 extern template SignalPtr DataBroker::declare<elem>(std::string_view); \
2077 extern template BasicContainer<elem> DataBroker::implement<elem>(std::string_view); \
2078 extern template void DataBroker::subscribe<elem>(std::string_view, \
2079 databroker::on_value_changed_callback_t<elem>); \
2080 extern template databroker::signal_type_cref_t<elem> DataBroker::value<elem>(std::string_view); \
2081 extern template const Signal::typed_get_value_function_t<elem>& DataBroker::getter<elem>( \
2082 std::string_view name); \
2083 extern template void DataBroker::set_value<elem>(std::string_view, \
2084 databroker::signal_type_cref_t<elem>); \
2085 extern template const Signal::typed_set_value_function_t<elem>& DataBroker::setter<elem>( \
2086 std::string_view name);
2088 #define CLOE_DATABROKER_TEMPLATE_INSTANTATION_TYPES()
2090 CLOE_DATABROKER_TEMPLATE_INSTANTATION_TYPES()
Definition: data_broker.hpp:226
Definition: data_broker.hpp:1217
void set_value(std::string_view name, databroker::signal_type_cref_t< T > value)
Definition: data_broker.hpp:1703
const Signal::typed_set_value_function_t< T > & setter(std::string_view name) const
Definition: data_broker.hpp:1768
SignalPtr declare(std::string_view name)
Definition: data_broker.hpp:1577
SignalPtr alias(SignalPtr signal, std::string_view new_name)
Definition: data_broker.hpp:1510
SignalContainer & signals()
Definition: data_broker.hpp:1675
void bind(std::string_view signals_name, sol::table parent)
Binds the signals-object to Lua.
Definition: data_broker.hpp:1473
const SignalContainer & signals() const
Definition: data_broker.hpp:1670
const Signal::typed_get_value_function_t< T > & getter(std::string_view name) const
Definition: data_broker.hpp:1734
void bind_signal(std::string_view signal_name, std::string_view lua_name)
Binds a signal to the Lua-VM.
Definition: data_broker.hpp:1442
SignalPtr signal(std::string_view name)
Definition: data_broker.hpp:1659
void set_getter(std::string_view name, const Signal::typed_get_value_function_t< T > &getter_fn)
Definition: data_broker.hpp:1753
SignalPtr declare(std::string_view name, T *value_ptr)
Definition: data_broker.hpp:1597
SignalPtr alias(std::string_view old_name, std::string_view new_name, std::regex::flag_type f=std::regex_constants::ECMAScript)
Definition: data_broker.hpp:1544
void declare_type(lua_signal_declarator_t type_declarator)
Declares a DataType to Lua (if not yet done)
Definition: data_broker.hpp:1384
SignalContainer::iterator operator[](std::string_view name)
Definition: data_broker.hpp:1497
void set_setter(std::string_view name, const Signal::typed_set_value_function_t< T > &setter_fn)
Definition: data_broker.hpp:1787
void bind_signal(std::string_view signal_name)
Binds a signal to the Lua-VM.
Definition: data_broker.hpp:1466
databroker::signal_type_cref_t< T > value(std::string_view name) const
Definition: data_broker.hpp:1719
const SignalContainer::const_iterator operator[](std::string_view name) const
Definition: data_broker.hpp:1486
Container< databroker::compatible_base_t< T > > implement(std::string_view new_name)
Definition: data_broker.hpp:1629
SignalPtr signal(std::string_view name) const
Definition: data_broker.hpp:1645
void subscribe(std::string_view name, databroker::on_value_changed_callback_t< T > callback)
Definition: data_broker.hpp:1688
Definition: data_broker.hpp:703
std::enable_if_t<!std::is_void_v< typename T::tag_type > > add(TArgs &&... args)
Definition: data_broker.hpp:973
bool has_subscriber() const
Definition: data_broker.hpp:1057
const MetaInformation & metadatas() const
Definition: data_broker.hpp:1006
const typed_on_value_change_event_function_t< T > & trigger() const
Definition: data_broker.hpp:942
std::function< void(databroker::signal_type_cref_t< T >)> typed_on_value_change_event_function_t
Definition: data_broker.hpp:748
void set_getter(typed_get_value_function_t< T > get_value_fn)
Definition: data_broker.hpp:855
const typed_set_value_function_t< T > * setter() const
Definition: data_broker.hpp:891
const typed_get_value_function_t< T > * getter() const
Definition: data_broker.hpp:825
void set_setter(typed_set_value_function_t< T > set_value_fn)
Definition: data_broker.hpp:907
void add_name(std::string_view name)
Definition: data_broker.hpp:1095
std::function< void(databroker::signal_type_cref_t< T >)> typed_set_value_function_t
Definition: data_broker.hpp:735
std::function< databroker::signal_type_cref_t< T >()> typed_get_value_function_t
Definition: data_broker.hpp:728
const std::vector< std::string > & names() const
Definition: data_broker.hpp:1064
std::enable_if_t< std::is_void_v< typename T::tag_type > > add()
Definition: data_broker.hpp:989
std::size_t subscriber_count() const
Definition: data_broker.hpp:1050
const std::string & name() const
Definition: data_broker.hpp:1071
void set_value(databroker::signal_type_cref_t< T > value) const
Definition: data_broker.hpp:921
auto metadata() -> decltype(metainformations_.get< T >())
Definition: data_broker.hpp:1000
Signal(access_token)
Definition: data_broker.hpp:780
constexpr const std::type_info * type() const
Definition: data_broker.hpp:790
std::enable_if_t<!std::is_void_v< typename T::tag_type > > add(typename T::tag_type metadata)
Definition: data_broker.hpp:960
databroker::signal_type_cref_t< T > value() const
Definition: data_broker.hpp:870
void subscribe(databroker::on_value_changed_callback_t< T > callback)
Definition: data_broker.hpp:1035
std::string name_or(std::string def) const
Definition: data_broker.hpp:1083
Definition: data_broker.hpp:1195
Definition: data_broker.hpp:154
std::size_t count() const
Definition: data_broker.hpp:170
void add(EventHandler handler)
Definition: data_broker.hpp:165
constexpr bool is_incompatible_type_v
Definition: data_broker.hpp:120
std::function< void(const SignalPtr &, sol::state_view, std::string_view)> lua_signal_adapter_t
Definition: data_broker.hpp:215
#define PHYSICALQUANTITIES_LIST
Definition: data_broker.hpp:639
void to_lua(sol::state_view lua)
Definition: data_broker.hpp:90
constexpr void assert_static_type()
Definition: data_broker.hpp:199
#define LUADATATYPE_LIST
Definition: data_broker.hpp:612
typename type_t_or_int_if< T, !is_incompatible_type_v< T > >::type compatible_base_t
Definition: data_broker.hpp:132
std::function< void(signal_type_cref_t< T >)> on_value_changed_callback_t
Definition: data_broker.hpp:144
std::function< void(sol::state_view)> lua_signal_declarator_t
Definition: data_broker.hpp:220
constexpr bool has_to_lua_v
Definition: data_broker.hpp:84
databroker::compatible_base_t< T > const & signal_type_cref_t
Definition: data_broker.hpp:138
Definition: data_broker.hpp:1309
Definition: data_broker.hpp:608
LuaDatatype datatype
Definition: data_broker.hpp:675
PhysicalQuantity unit
Definition: data_broker.hpp:679
std::string text
Definition: data_broker.hpp:684
Definition: data_broker.hpp:593
std::string text
Definition: data_broker.hpp:598
Definition: data_broker.hpp:1797
void set_setter(DataBroker &db, Signal::typed_set_value_function_t< T > set_value_fn)
Definition: data_broker.hpp:1963
auto set_value(DataBroker &db, const T &value)
Definition: data_broker.hpp:1980
auto value(const DataBroker &db) const
Definition: data_broker.hpp:1973
auto setter(const DataBroker &db) const
Definition: data_broker.hpp:1956
void declare(DataBroker &db)
Definition: data_broker.hpp:1926
auto getter(const DataBroker &db) const
Definition: data_broker.hpp:1940
auto signal(const DataBroker &db) const
Definition: data_broker.hpp:1933
auto implement(DataBroker &db)
Definition: data_broker.hpp:1919
void set_getter(DataBroker &db, Signal::typed_get_value_function_t< T > get_value_fn)
Definition: data_broker.hpp:1947
static auto value(DataBroker &db)
Definition: data_broker.hpp:1894
static auto setter(const DataBroker &db)
Definition: data_broker.hpp:1877
static void set_setter(DataBroker &db, Signal::typed_set_value_function_t< T > set_value_fn)
Definition: data_broker.hpp:1884
static auto set_value(DataBroker &db, const T &value)
Definition: data_broker.hpp:1901
static auto implement(DataBroker &db)
Definition: data_broker.hpp:1840
static void set_getter(DataBroker &db, Signal::typed_get_value_function_t< T > get_value_fn)
Definition: data_broker.hpp:1868
static auto getter(const DataBroker &db)
Definition: data_broker.hpp:1861
static auto signal(const DataBroker &db)
Definition: data_broker.hpp:1854
static void declare(DataBroker &db)
Definition: data_broker.hpp:1847
Definition: data_broker.hpp:1822
Definition: data_broker.hpp:1989
Definition: data_broker.hpp:2014
Definition: data_broker.hpp:2019
Definition: data_broker.hpp:1809
Definition: data_broker.hpp:72
Definition: data_broker.hpp:106