SensESP 3.3.0
Universal Signal K sensor toolkit ESP32
Loading...
Searching...
No Matches
valueproducer.h
Go to the documentation of this file.
1#ifndef SENSESP_SYSTEM_VALUE_PRODUCER_H_
2#define SENSESP_SYSTEM_VALUE_PRODUCER_H_
3
4#include <ArduinoJson.h>
5#include <memory>
6
7#include "observable.h"
8#include "valueconsumer.h"
9
10namespace sensesp {
11
12// The Transform class is defined in transforms/transform.h
13template <typename C, typename P>
14class Transform;
15
24template <typename T>
25class ValueProducer : virtual public Observable {
26 public:
28 ValueProducer(const T& initial_value) : output_(initial_value) {}
29
33 virtual const T& get() const { return output_; }
34
46 template <typename VConsumer>
47 typename std::enable_if<
48 std::is_base_of<ValueConsumer<typename VConsumer::input_type>, VConsumer>::value &&
49 std::is_convertible<T, typename VConsumer::input_type>::value,
50 std::shared_ptr<VConsumer>
51 >::type
52 connect_to(std::shared_ptr<VConsumer> consumer) {
53 using CInput = typename VConsumer::input_type;
54 // Strong reference: the observer lambda owns the shared_ptr, keeping the
55 // consumer alive. This assumes acyclic signal chains (no A→B→A loops).
56 this->attach([this, consumer]() {
57 consumer->set(static_cast<CInput>(this->get()));
58 });
59 return consumer;
60 }
61
62 template <typename VConsumer>
63 typename std::enable_if<
64 std::is_base_of<ValueConsumer<typename VConsumer::input_type>, VConsumer>::value &&
65 std::is_convertible<T, typename VConsumer::input_type>::value,
66 VConsumer*
67 >::type
68 connect_to(VConsumer* consumer) {
69 using CInput = typename VConsumer::input_type;
70 this->attach([this, consumer]() {
71 consumer->set(static_cast<CInput>(this->get()));
72 });
73 return consumer;
74 }
75
76 template <typename VConsumer>
77 typename std::enable_if<
78 std::is_base_of<ValueConsumer<typename VConsumer::input_type>, VConsumer>::value &&
79 std::is_convertible<T, typename VConsumer::input_type>::value,
80 VConsumer*
81 >::type
82 connect_to(VConsumer& consumer) {
83 return connect_to(&consumer);
84 }
85
86 /*
87 * Set a new output value and notify consumers about it
88 */
89 void emit(const T& new_value) {
90 this->output_ = new_value;
92 }
93
94 protected:
100};
101
106
107} // namespace sensesp
108
109#endif // SENSESP_SYSTEM_VALUE_PRODUCER_H_
int attach(std::function< void()> observer)
Attach an observer callback.
Definition observable.h:40
The main Transform class. A transform is identified primarily by the type of value that is produces (...
Definition transform.h:53
A base class for any sensor or piece of code that outputs a value for consumption elsewhere.
std::enable_if< std::is_base_of< ValueConsumer< typenameVConsumer::input_type >, VConsumer >::value &&std::is_convertible< T, typenameVConsumer::input_type >::value, VConsumer * >::type connect_to(VConsumer &consumer)
virtual const T & get() const
void emit(const T &new_value)
std::enable_if< std::is_base_of< ValueConsumer< typenameVConsumer::input_type >, VConsumer >::value &&std::is_convertible< T, typenameVConsumer::input_type >::value, VConsumer * >::type connect_to(VConsumer *consumer)
ValueProducer(const T &initial_value)
std::enable_if< std::is_base_of< ValueConsumer< typenameVConsumer::input_type >, VConsumer >::value &&std::is_convertible< T, typenameVConsumer::input_type >::value, std::shared_ptr< VConsumer > >::type connect_to(std::shared_ptr< VConsumer > consumer)
Connect a producer to a transform with a different input type.
ValueProducer< bool > BoolProducer
ValueProducer< float > FloatProducer
ValueProducer< int > IntProducer
ValueProducer< String > StringProducer