SyDEVS  v0.7
Simulation-based analysis of complex systems involving people, devices, physical elements, and dynamic environments.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
port.h
Go to the documentation of this file.
1 #pragma once
2 #ifndef SYDEVS_SYSTEMS_PORT_H_
3 #define SYDEVS_SYSTEMS_PORT_H_
4 
6 
7 namespace sydevs {
8 namespace systems {
9 
10 
17 template<data_mode dmode, data_goal dgoal, typename T>
18 class port_base
19 {
20 public:
21  port_base(const port_base&) = delete;
22  port_base& operator=(const port_base&) = delete;
23  port_base(port_base&&) = default;
24  port_base& operator=(port_base&&) = default;
25  virtual ~port_base() = default;
26 
27  const std::string& port_name() const;
28 
29  int64 port_index() const;
30  int64 node_index() const;
31 
33 
34 protected:
36 
37 private:
38  const std::string port_name_;
39  const int64 port_index_;
40  node_interface& external_interface_;
41 };
42 
43 
52 template<data_mode dmode, data_goal dgoal, typename T>
53 class port : public port_base<dmode, dgoal, T>
54 {
55 };
56 
57 
67 template<typename T>
68 class port<flow, input, T> : public port_base<flow, input, T>
69 {
70 public:
84  port(const std::string& port_name, const node_interface& external_interface);
85 
86  port(port&&) = default;
87  port& operator=(port&&) = default;
88  ~port() = default;
89 
90  const T& value() const;
91 
92  void print_on_use(bool flag = true) const;
93 };
94 
95 
105 template<typename T>
106 class port<message, input, T> : public port_base<message, input, T>
107 {
108 public:
122  port(const std::string& port_name, const node_interface& external_interface);
123 
124  port(port&&) = default;
125  port& operator=(port&&) = default;
126  ~port() = default;
127 
128  bool received() const;
129  const T& value() const;
130 
131  void print_on_use(bool flag = true) const;
132 };
133 
134 
144 template<typename T>
145 class port<message, output, T> : public port_base<message, output, T>
146 {
147 public:
161  port(const std::string& port_name, const node_interface& external_interface);
162 
163  port(port&&) = default;
164  port& operator=(port&&) = default;
165  ~port() = default;
166 
167  void send(const T& val);
168 
169  void print_on_use(bool flag = true) const;
170 };
171 
172 
182 template<typename T>
183 class port<flow, output, T> : public port_base<flow, output, T>
184 {
185 public:
199  port(const std::string& port_name, const node_interface& external_interface);
200 
201  port(port&&) = default;
202  port& operator=(port&&) = default;
203  ~port() = default;
204 
205  void assign(const T& val);
206 
207  void print_on_use(bool flag = true) const;
208 };
209 
210 
211 template<data_mode dmode, data_goal dgoal, typename T>
212 const std::string& port_base<dmode, dgoal, T>::port_name() const
213 {
214  return port_name_;
215 }
216 
217 
218 template<data_mode dmode, data_goal dgoal, typename T>
220 {
221  return port_index_;
222 }
223 
224 
225 template<data_mode dmode, data_goal dgoal, typename T>
227 {
228  return external_interface_.node_index();
229 }
230 
231 
232 template<data_mode dmode, data_goal dgoal, typename T>
234 {
235  return external_interface_;
236 }
237 
238 
239 template<data_mode dmode, data_goal dgoal, typename T>
240 port_base<dmode, dgoal, T>::port_base(const std::string& port_name, int64 port_index, node_interface& external_interface)
241  : port_name_(port_name)
242  , port_index_(port_index)
243  , external_interface_(external_interface)
244 {
246  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
247  throw std::logic_error("Invalid data type for port (" + this->port_name() + ") " +
248  "of node (" + full_node_name + ")");
249  }
250 }
251 
252 
253 template<typename T>
254 port<flow, input, T>::port(const std::string& port_name, const node_interface& external_interface)
255  : port_base<flow, input, T>(
256  port_name,
257  const_cast<node_interface&>(external_interface).add_flow_input_port(port_name),
258  const_cast<node_interface&>(external_interface))
259 {
260 }
261 
262 
263 template<typename T>
265 {
266  if (!this->external_interface().active()) {
267  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
268  throw std::logic_error("Attempt to get value on flow input port (" + this->port_name() + ") " +
269  "of inactive node (" + full_node_name + ")");
270  }
271  const auto& val = const_cast<node_interface&>(this->external_interface()).flow_input_port_value(this->port_index());
272  return const_cast<const T&>(val.template dereference<T>());
273 }
274 
275 
276 template<typename T>
278 {
279  auto tostring_func = flag ? tostring_converter<T>() : nullptr;
280  const_cast<node_interface&>(this->external_interface()).set_flow_input_printable(this->port_index(), tostring_func);
281 }
282 
283 
284 template<typename T>
285 port<message, input, T>::port(const std::string& port_name, const node_interface& external_interface)
286  : port_base<message, input, T>(
287  port_name,
288  const_cast<node_interface&>(external_interface).add_message_input_port(port_name),
289  const_cast<node_interface&>(external_interface))
290 {
291 }
292 
293 
294 template<typename T>
296 {
297  if (!this->external_interface().active()) {
298  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
299  throw std::logic_error("Attempt to check message input port (" + this->port_name() + ") " +
300  "of inactive node (" + full_node_name + ")");
301  }
302  if (this->external_interface().dmode() != message || this->external_interface().dgoal() != input) {
303  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
304  throw std::logic_error("Attempt to check message input port (" + this->port_name() + ") " +
305  "of node (" + full_node_name + ") outside of unplanned event");
306  }
307  return const_cast<node_interface&>(this->external_interface()).message_input_port_index() == this->port_index();
308 }
309 
310 
311 template<typename T>
313 {
314  if (!this->external_interface().active()) {
315  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
316  throw std::logic_error("Attempt to get value on message input port (" + this->port_name() + ") " +
317  "of inactive node (" + full_node_name + ")");
318  }
319  if (this->external_interface().dmode() != message || this->external_interface().dgoal() != input) {
320  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
321  throw std::logic_error("Attempt to get value on message input port (" + this->port_name() + ") " +
322  "of node (" + full_node_name + ") outside of unplanned event");
323  }
324  if (const_cast<node_interface&>(this->external_interface()).message_input_port_index() != this->port_index()) {
325  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
326  throw std::logic_error("Attempt to get value on message input port (" + this->port_name() + ") " +
327  "of node (" + full_node_name + "), which was not the port that received the message.");
328  }
329  const auto& val = const_cast<node_interface&>(this->external_interface()).message_input_port_value(this->port_index());
330  return const_cast<const T&>(val.template dereference<T>());
331 }
332 
333 
334 template<typename T>
336 {
337  auto tostring_func = flag ? tostring_converter<T>() : nullptr;
338  const_cast<node_interface&>(this->external_interface()).set_message_input_printable(this->port_index(), tostring_func);
339 }
340 
341 
342 template<typename T>
343 port<message, output, T>::port(const std::string& port_name, const node_interface& external_interface)
344  : port_base<message, output, T>(
345  port_name,
346  const_cast<node_interface&>(external_interface).add_message_output_port(port_name),
347  const_cast<node_interface&>(external_interface))
348 {
349 }
350 
351 
352 template<typename T>
354 {
355  if (!this->external_interface().active()) {
356  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
357  throw std::logic_error("Attempt to send value on message output port (" + this->port_name() + ") " +
358  "of inactive node (" + full_node_name + ")");
359  }
360  if (this->external_interface().dmode() != message || this->external_interface().dgoal() != output) {
361  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
362  throw std::logic_error("Attempt to send value on message output port (" + this->port_name() + ") " +
363  "of node (" + full_node_name + ") outside of planned event");
364  }
365  const_cast<node_interface&>(this->external_interface()).append_message_output(this->port_index(), qualified_type<T>::copy(val));
366 }
367 
368 
369 template<typename T>
371 {
372  auto tostring_func = flag ? tostring_converter<T>() : nullptr;
373  const_cast<node_interface&>(this->external_interface()).set_message_output_printable(this->port_index(), tostring_func);
374 }
375 
376 
377 template<typename T>
378 port<flow, output, T>::port(const std::string& port_name, const node_interface& external_interface)
379  : port_base<flow, output, T>(
380  port_name,
381  const_cast<node_interface&>(external_interface).add_flow_output_port(port_name),
382  const_cast<node_interface&>(external_interface))
383 {
384 }
385 
386 
387 template<typename T>
389 {
390  if (!this->external_interface().active()) {
391  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
392  throw std::logic_error("Attempt to assign value on flow output port (" + this->port_name() + ") " +
393  "of inactive node (" + full_node_name + ")");
394  }
395  if (this->external_interface().dmode() != flow) {
396  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
397  throw std::logic_error("Attempt to assign value on flow output port (" + this->port_name() + ") " +
398  "of node (" + full_node_name + ") outside of initialization or finalization event");
399  }
400  const_cast<node_interface&>(this->external_interface()).assign_flow_output(this->port_index(), qualified_type<T>::copy(val));
401 }
402 
403 
404 template<typename T>
406 {
407  auto tostring_func = flag ? tostring_converter<T>() : nullptr;
408  const_cast<node_interface&>(this->external_interface()).set_flow_output_printable(this->port_index(), tostring_func);
409 }
410 
411 
412 } // namespace
413 } // namespace
414 
415 #endif
Definition: node_interface.h:17
port & operator=(port &&)=default
Move assignment.
port(port &&)=default
Move constructor.
port & operator=(port &&)=default
Move assignment.
port(port &&)=default
Move constructor.
port(port &&)=default
Move constructor.
port & operator=(port &&)=default
Move assignment.
port & operator=(port &&)=default
Move assignment.
port(port &&)=default
Move constructor.
A base class template for all port classes.
Definition: port.h:19
port_base(port_base &&)=default
Move constructor.
port_base & operator=(const port_base &)=delete
No copy assignment.
const node_interface & external_interface() const
Returns the encomassing node_interface object.
Definition: port.h:233
port_base & operator=(port_base &&)=default
Move assignment.
const std::string & port_name() const
Returns the name of the port.
Definition: port.h:212
int64 node_index() const
Returns the index of the node within the encompassing node_structure object.
Definition: port.h:226
int64 port_index() const
Returns the index of the port within the encompassing node_interface object.
Definition: port.h:219
port_base(const std::string &port_name, int64 port_index, node_interface &external_interface)
Definition: port.h:240
port_base(const port_base &)=delete
No copy constructor.
virtual ~port_base()=default
Destructor.
A generic port class template declaration.
Definition: port.h:54
const auto message
Equivalent to data_mode::message.
Definition: data_mode.h:23
const auto output
Equivalent to data_goal::output.
Definition: data_goal.h:22
const auto input
Equivalent to data_goal::input.
Definition: data_goal.h:21
const auto flow
Equivalent to data_mode::flow.
Definition: data_mode.h:22
Definition: arraynd.h:8
int64_t int64
Definition: number_types.h:15
Definition: qualified_type.h:24
static pointer copy(const T &X)
If T is a qualified type, returns a deep copy of X.
Definition: qualified_type.h:174