SyDEVS  v0.6.7
Multiscale Simulation and Systems Modeling Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
system_node.h
Go to the documentation of this file.
1 #pragma once
2 #ifndef SYDEVS_SYSTEMS_SYSTEM_NODE_H_
3 #define SYDEVS_SYSTEMS_SYSTEM_NODE_H_
4 
6 #include <sydevs/systems/port.h>
7 #include <sydevs/core/timer.h>
8 
9 namespace sydevs {
10 namespace systems {
11 
12 
42 {
43 public:
44  class error;
45 
46  system_node(const system_node&) = delete;
47  system_node& operator=(const system_node&) = delete;
48  system_node(system_node&&) = delete;
49  system_node& operator=(system_node&&) = delete;
50  virtual ~system_node() = default;
51 
52  const std::string& node_name() const;
53  const std::string& full_name() const;
54  int64 node_index() const;
55 
56  const node_interface& external_interface() const;
57 
58  const timer& event_timer() const;
59 
60  template<typename T>
61  void print(const T& X);
62  void print(const char* raw_text);
63  void print(const std::string& text);
64 
65  void print_on_event(bool flag = true) const;
66 
67  void adopt_print_flags(const system_node& node) const;
68 
69  virtual data_mode node_dmode() const = 0;
70  virtual scale time_precision() const = 0;
71 
75  void process_finalization_event(duration elapsed_dt);
76 
77 protected:
78  std::mt19937& rng;
79 
91  system_node(const std::string& node_name, const node_context& external_context);
92 
93  node_interface& external_IO() const;
94  timer& ET() const;
95 
111  duration scale_planned_dt(duration planned_dt) const;
112 
113 private:
114  virtual void adopt_component_print_flags(const system_node& node) const = 0;
115 
116  virtual duration handle_initialization_event() = 0;
117  virtual duration handle_unplanned_event(duration elapsed_dt) = 0;
118  virtual duration handle_planned_event(duration elapsed_dt) = 0;
119  virtual void handle_finalization_event(duration elapsed_dt) = 0;
120 
121  node_interface external_interface_;
122  timer event_timer_;
123 };
124 
125 
126 
127 class system_node::error : public std::runtime_error
128 {
129 public:
130  explicit error(const std::string& what_arg);
131  explicit error(const char* what_arg);
132 };
133 
134 
135 inline const std::string& system_node::node_name() const
136 {
137  return external_IO().node_name();
138 }
139 
140 
141 inline const std::string& system_node::full_name() const
142 {
143  return external_IO().full_name();
144 }
145 
146 
148 {
149  return external_IO().node_index();
150 }
151 
152 
154 {
155  return const_cast<const node_interface&>(external_interface_);
156 }
157 
158 
159 inline const timer& system_node::event_timer() const
160 {
161  return event_timer_;
162 }
163 
164 
165 template<typename T>
166 inline void system_node::print(const T& X)
167 {
168  print(tostring(X));
169 }
170 
171 
172 inline void system_node::print(const char* raw_text)
173 {
174  print(std::string(raw_text));
175 }
176 
177 
178 inline void system_node::print(const std::string& text)
179 {
180  external_interface_.print_command_text("print", text);
181 }
182 
183 
184 inline void system_node::print_on_event(bool flag) const
185 {
186  external_IO().print_on_event(flag);
187 }
188 
189 
191 {
192  auto planned_dt = duration();
193  try {
194  planned_dt = handle_initialization_event();
195  }
196  catch (error&) {
197  if (ET().timing()) {
198  ET().stop();
199  }
200  throw;
201  }
202  catch (const std::exception& e) {
203  if (ET().timing()) {
204  ET().stop();
205  }
206  external_IO().print_command_text("error", e.what());
207  throw error("Aborting event in node (" + full_name() + ") due to error (\"" + e.what() + "\")");
208  }
209  return planned_dt;
210 }
211 
212 
214 {
215  auto planned_dt = duration();
216  try {
217  planned_dt = handle_unplanned_event(elapsed_dt);
218  }
219  catch (error&) {
220  if (ET().timing()) {
221  ET().stop();
222  }
223  throw;
224  }
225  catch (const std::exception& e) {
226  if (ET().timing()) {
227  ET().stop();
228  }
229  external_IO().print_command_text("error", e.what());
230  throw error("Aborting event in node (" + full_name() + ") due to error (\"" + e.what() + "\")");
231  }
232  return planned_dt;
233 }
234 
235 
237 {
238  auto planned_dt = duration();
239  try {
240  planned_dt = handle_planned_event(elapsed_dt);
241  }
242  catch (error&) {
243  if (ET().timing()) {
244  ET().stop();
245  }
246  throw;
247  }
248  catch (const std::exception& e) {
249  if (ET().timing()) {
250  ET().stop();
251  }
252  external_IO().print_command_text("error", e.what());
253  throw error("Aborting event in node (" + full_name() + ") due to error (\"" + e.what() + "\")");
254  }
255  return planned_dt;
256 }
257 
258 
260 {
261  try {
262  handle_finalization_event(elapsed_dt);
263  }
264  catch (error&) {
265  if (ET().timing()) {
266  ET().stop();
267  }
268  throw;
269  }
270  catch (const std::exception& e) {
271  if (ET().timing()) {
272  ET().stop();
273  }
274  external_IO().print_command_text("error", e.what());
275  throw error("Aborting event in node (" + full_name() + ") due to error (\"" + e.what() + "\")");
276  }
277 }
278 
279 
280 inline system_node::system_node(const std::string& node_name, const node_context& external_context)
281  : rng(const_cast<node_context&>(external_context).rng())
282  , external_interface_(node_name, this, external_context)
283  , event_timer_()
284 {
285 }
286 
287 
289 {
290  return const_cast<node_interface&>(external_interface_);
291 }
292 
293 
294 inline timer& system_node::ET() const
295 {
296  return const_cast<timer&>(event_timer_);
297 }
298 
299 
300 inline system_node::error::error(const std::string& what_arg)
301  : runtime_error(what_arg)
302 {
303 }
304 
305 
306 inline system_node::error::error(const char* what_arg)
307  : runtime_error(what_arg)
308 {
309 }
310 
311 
312 } // namespace
313 } // namespace
314 
315 #endif
void process_finalization_event(duration elapsed_dt)
Processes a finalization event after an elapsed duration elapsed_dt.
Definition: system_node.h:259
std::string tostring(const T &val)
Definition: qualified_type.h:35
const std::string & node_name() const
Returns the name of the node.
Definition: system_node.h:135
int64 node_index() const
Returns the index of the node within the parent node.
Definition: system_node.h:147
int64 node_index()
Definition: node_interface.h:151
data_mode
Indicates the relevant data communication paradigm: dataflow (flow) or message-passing (message)...
Definition: data_mode.h:16
duration stop()
Stops the timer and returns the measured interval of wallclock time.
Definition: timer.h:93
A base class for all nodes from which systems models are constructed.
Definition: system_node.h:41
void print_on_event(bool flag=true)
Definition: node_interface.cpp:356
duration process_initialization_event()
Processes an initialization event; returns a planned duration.
Definition: system_node.h:190
duration process_planned_event(duration elapsed_dt)
Processes a planned event after an elapsed duration elapsed_dt; returns a planned duration...
Definition: system_node.h:236
virtual ~system_node()=default
Destructor.
void print_command_text(const std::string &command, const std::string &text)
Definition: node_interface.cpp:344
const std::string & full_name()
Definition: node_interface.h:145
virtual data_mode node_dmode() const =0
Returns flow if the node has data flow elements only, and message otherwise.
void print_on_event(bool flag=true) const
If flag is true, all event types are printed for this node.
Definition: system_node.h:184
A class for measuring and accumulating intervals of wallclock time.
Definition: timer.h:24
const std::string & full_name() const
Returns the full name of the node, including parent nodes.
Definition: system_node.h:141
system_node & operator=(const system_node &)=delete
No copy assignment.
error(const std::string &what_arg)
Definition: system_node.h:300
A data type which represents the general concept of scale as a dimensionless power of 1000...
Definition: scale.h:70
const std::string & node_name()
Definition: node_interface.h:139
Definition: node_context.h:16
Definition: node_interface.h:16
duration process_unplanned_event(duration elapsed_dt)
Processes an unplanned event after an elapsed duration elapsed_dt; returns a planned duration...
Definition: system_node.h:213
quantity< seconds > duration
Definition: quantity.h:1006
system_node(const system_node &)=delete
No copy constructor.
void print(const T &X)
Prints X while indicating the simulation time and node.
Definition: system_node.h:166
Definition: system_node.h:127
std::mt19937 & rng
Reference to the random number generator.
Definition: system_node.h:78
duration scale_planned_dt(duration planned_dt) const
Adjusts the planned duration obtained from other nodes' event handlers.
Definition: system_node.cpp:46
const timer & event_timer() const
Returns the object that accumulated wallclock event durations.
Definition: system_node.h:159
void adopt_print_flags(const system_node &node) const
Adopts the print flags of node.
Definition: system_node.cpp:7
node_interface & external_IO() const
Returns a non-const reference to the node's external interface.
Definition: system_node.h:288
const node_interface & external_interface() const
Returns the object responsible for exchanging information between the node and its surrounding contex...
Definition: system_node.h:153
timer & ET() const
Returns a non-const reference to the node's event timer.
Definition: system_node.h:294
virtual scale time_precision() const =0
Returns the time precision associated with the node, or no_scale.