smgl 0.11.0
Structured Metadata Engine and Graph Objects Library
Loading...
Searching...
No Matches
PortsImpl.hpp
1namespace smgl
2{
3
7
8// Must know what object will actually store posted values
9template <typename T>
10InputPort<T>::InputPort(T* target) : target_{[target](T v) { *target = v; }}
11{
12}
13
14template <typename T>
15InputPort<T>::InputPort(std::function<void(T)> target) : target_{target}
16{
17}
18
19template <typename T>
20template <class Obj, class ObjMemberFn>
21InputPort<T>::InputPort(Obj* obj, ObjMemberFn&& fn)
22 : target_{[=](T v) { return (*obj.*fn)(v); }}
23{
24}
25
26template <typename T>
28{
29 // TODO: Lock the queue
30 queued_update_ = u;
31 queued_update_.tick = last_updated_ + 1;
32 state_ = State::Queued;
33}
34
35// For testing purposes only
36template <typename T>
37void InputPort<T>::post(T v, bool immediate)
38{
39 post(Update<T>{v, 0});
40 if (immediate) {
41 update();
42 }
43}
44
45template <typename T>
47{
48 post(u);
49}
50
51template <typename T>
52void InputPort<T>::operator()(T v, bool immediate)
53{
54 post(v, immediate);
55}
56
57template <typename T>
59{
60 post(v, false);
61 return *this;
62}
63
64template <typename T>
66{
68 return *this;
69}
70
71// Update target with most recent compute
72template <typename T>
74{
75 // TODO: Lock the queue
76 if (queued_update_.tick > last_updated_) {
77 target_(queued_update_.val);
78 last_updated_ = queued_update_.tick;
79 state_ = State::Idle;
80 return true;
81 }
82 return false;
83}
84
85template <typename T>
87{
88 last_updated_++;
89 state_ = s;
90}
91
92template <typename T>
94{
95 Metadata m;
96 m["uuid"] = uuid_.string();
97 // TODO: STATUS
98 return m;
99}
100
101template <typename T>
103{
104 uuid_ = Uuid::FromString(m["uuid"].get<std::string>());
105}
106
110
111template <typename T, typename... Args>
113{
114 for (auto& c : connections_) {
115 c.second.port->disconnect(this);
116 }
117}
118
119// Object source: constant
120template <typename T, typename... Args>
122 : source_{[source](Args...) { return source; }}
123{
124}
125// Object source: pointer
126template <typename T, typename... Args>
128 : source_{[source](Args...) { return *source; }}
129{
130}
131
132// Member fn source w/optional default arguments
133template <typename T, typename... Args>
135 std::function<T(Args...)> source, Args&&... args)
136 : source_{source}, args_{Arguments(std::forward<Args>(args)...)}
137{
138}
139
140template <typename T, typename... Args>
141template <class Obj, class ObjMemberFn>
142OutputPort<T, Args...>::OutputPort(Obj* obj, ObjMemberFn&& fn, Args&&... args)
143 : source_{[=](Args... a) { return (*obj.*fn)(a...); }}
144 , args_{Arguments(std::forward<Args>(args)...)}
145{
146}
147
148template <typename T, typename... Args>
150{
151 using ThisType = OutputPort<T, Args...>;
153 for (const auto& c : connections_) {
154 cns.emplace_back(
155 parent_, const_cast<ThisType*>(this), c.second.node, c.second.port);
156 }
157 return cns;
158}
159
160template <typename T, typename... Args>
162{
163 return connections_.size();
164}
165
166// Replace the default arguments
167template <typename T, typename... Args>
169{
170 args_ = Arguments(std::forward<Args>(args)...);
171}
172// Get the most recent value
173template <typename T, typename... Args>
175{
176 return run_(args_);
177}
178template <typename T, typename... Args>
180{
181 return val();
182}
183
184// Send queued update to connected input ports
185// Note: This is like calling emit() in Qt
186template <typename T, typename... Args>
188{
189 Update<T> update{val()};
190 for (const auto& c : connections_) {
191 c.second.port->post(update);
192 }
193 return connections_.size() > 0;
194}
195
196template <typename T, typename... Args>
198{
199 for (const auto& c : connections_) {
200 c.second.port->notify(s);
201 }
202}
203
204template <typename T, typename... Args>
206{
207 Metadata m;
208 m["uuid"] = uuid_.string();
209 return m;
210}
211
212template <typename T, typename... Args>
214{
215 uuid_ = Uuid::FromString(m["uuid"].get<std::string>());
216}
217
218// Redirection functions for calling with default args
219template <typename T, typename... Args>
220template <std::size_t... Is>
223{
224 return source_(std::get<Is>(tup)...);
225}
226
227template <typename T, typename... Args>
232
233template <typename T, typename... Args>
235{
236 if (typeid(*ip) != typeid(InputPort<T>)) {
237 throw bad_connection("Ports not of same type");
238 }
239 auto typedIP = static_cast<InputPort<T>*>(ip);
240 connections_[ip->uuid()] = {ip->parent_, typedIP};
241 if (state_ == State::Idle) {
242 Update<T> update{val()};
243 typedIP->post(update);
244 }
245}
246
247template <typename T, typename... Args>
249{
250 if (connections_.erase(ip->uuid()) == 0) {
251 // TODO: Throw error?
252 }
253}
254
255} // namespace smgl
Typed InputPort class.
Definition Ports.hpp:213
bool update() override
Update the target with the most recently posted update.
Definition PortsImpl.hpp:73
void notify(State s) override
Receive a state update from a connected port.
Definition PortsImpl.hpp:86
Metadata serialize() override
Get port metadata.
Definition PortsImpl.hpp:93
void deserialize(const Metadata &m) override
Load port metadata.
InputPort & operator=(const InputPort &)=delete
InputPort(T *target)
Construct with pointer to target object.
Definition PortsImpl.hpp:10
void operator()(const Update< T > &u)
Post an update to the port.
Definition PortsImpl.hpp:46
void post(const Update< T > &u)
Post an update to the port.
Definition PortsImpl.hpp:27
Generic input port interface.
Definition Ports.hpp:132
virtual Input & operator=(Output &op)
Connect an output port to an input port.
Typed OutputPort class.
Definition Ports.hpp:295
void setArgs(Args &&... args)
Set the arguments passed to a function source.
T run_(std::tuple< Args... > &tup, std::index_sequence< Is... >)
~OutputPort() override
OutputPort(T source)
Construct with a copy of source. Source is effectively constant.
bool update() override
Update all active connections with the value of the source.
T operator()()
Get the current value of source.
Metadata serialize() override
Get port metadata.
std::size_t numConnections() const override
Get the number of active connections.
std::vector< Connection > getConnections() const override
Get a list of active connections.
void deserialize(const Metadata &m) override
Load port metadata.
T val()
Get the current value of source.
void notify(State s) override
Notify all active connections of this port's state.
Generic output port interface.
Definition Ports.hpp:175
friend void connect(Output &op, Input &ip)
Connect an output port to an input port.
friend void disconnect(Output &op, Input &ip)
Disconnect an output port and input port.
Node * parent_
Definition Ports.hpp:127
auto uuid() const -> Uuid
static auto FromString(const std::string &str) -> Uuid
Construct a UUID from a string.
T emplace_back(T... args)
T make_shared(T... args)
Project top-level namespace.
nlohmann::ordered_json Metadata
Metadata storage class.
Definition Metadata.hpp:12
ISO C++ top-level namespace.
Describes untyped connections from an output port.
Definition Ports.hpp:71
Typed update sent over connections.
Definition Ports.hpp:34
std::size_t tick
Definition Ports.hpp:38
Exception thrown for port connection failures.
Definition Ports.hpp:18