SyDEVS  v0.6.7
Multiscale Simulation and Systems Modeling Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
interactive_system.h
Go to the documentation of this file.
1 #pragma once
2 #ifndef SYDEVS_SYSTEMS_INTERACTIVE_SYSTEM_H_
3 #define SYDEVS_SYSTEMS_INTERACTIVE_SYSTEM_H_
4 
6 
7 namespace sydevs {
8 namespace systems {
9 
10 
48 template<typename AgentID, typename Node, typename InjData, typename ObsData>
49 class interactive_system : public collection_node<int64, Node>
50 {
51 public:
52  using injection_type = InjData;
53  using observation_type = ObsData;
54 
55  class interaction_data;
56 
57  virtual ~interactive_system() = default;
58 
59  std::unique_ptr<interaction_data> acquire_interaction_data();
60 
61  int64 frame_index() const;
62  duration planned_duration() const;
63 
64 protected:
75  interactive_system(const std::string& node_name, const node_context& external_context);
76 
77 private:
78  void validate();
79 
80  duration macro_initialization_event();
81  duration macro_unplanned_event(duration elapsed_dt);
82  duration micro_planned_event(const AgentID& agent_id, duration elapsed_dt);
83  duration macro_planned_event(duration elapsed_dt);
84  void macro_finalization_event(duration elapsed_dt);
85 
86  virtual duration macro_initialization_update(InjData& injection) = 0;
87  virtual void micro_planned_update(const AgentID& agent_id, duration elapsed_dt) = 0;
88  virtual duration macro_planned_update(duration elapsed_dt, const InjData& injection, ObsData& observation) = 0;
89  virtual void macro_finalization_update(duration elapsed_dt) = 0;
90 
91  InjData injection_;
92  ObsData observation_;
93  int64 frame_index_;
94  duration planned_dt_;
95  std::unique_ptr<interaction_data> interaction_data_;
96 };
97 
98 
99 template<typename AgentID, typename Node, typename InjData, typename ObsData>
100 class interactive_system<AgentID, Node, InjData, ObsData>::interaction_data
101 {
102 friend class interactive_system;
103 public:
104  InjData& injection();
105  const ObsData& observation();
106 
107 private:
108  interaction_data(InjData& inj, ObsData& obs);
109 
110  InjData& injection_;
111  ObsData& observation_;
112 };
113 
114 
115 template<typename AgentID, typename Node, typename InjData, typename ObsData>
116 std::unique_ptr<typename interactive_system<AgentID, Node, InjData, ObsData>::interaction_data> interactive_system<AgentID, Node, InjData, ObsData>::acquire_interaction_data()
117 {
118  return std::move(interaction_data_);
119 }
120 
121 
122 template<typename AgentID, typename Node, typename InjData, typename ObsData>
124 {
125  return frame_index_;
126 }
127 
128 
129 template<typename AgentID, typename Node, typename InjData, typename ObsData>
131 {
132  return planned_dt_;
133 }
134 
135 
136 template<typename AgentID, typename Node, typename InjData, typename ObsData>
138 {
139  if (this->external_IO().flow_input_port_count() != 0 ||
140  this->external_IO().message_input_port_count() != 0 ||
141  this->external_IO().message_output_port_count() != 0 ||
142  this->external_IO().flow_output_port_count() != 0) {
143  throw std::invalid_argument("Interactive node (" + this->full_name() + ") must have no ports");
144  }
145 }
146 
147 
148 template<typename AgentID, typename Node, typename InjData, typename ObsData>
149 interactive_system<AgentID, Node, InjData, ObsData>::interactive_system(const std::string& node_name, const node_context& external_context)
150  : collection_node<int64, Node>(node_name, external_context)
151  , injection_()
152  , observation_()
153  , frame_index_(-1)
154  , planned_dt_()
155  , interaction_data_(new interaction_data(injection_, observation_))
156 {
157  validate();
158 }
159 
160 
161 template<typename AgentID, typename Node, typename InjData, typename ObsData>
163 {
164  planned_dt_ = macro_initialization_update(injection_);
165  return planned_dt_;
166 }
167 
168 
169 template<typename AgentID, typename Node, typename InjData, typename ObsData>
170 duration interactive_system<AgentID, Node, InjData, ObsData>::macro_unplanned_event(duration elapsed_dt)
171 {
172  return duration();
173 }
174 
175 
176 template<typename AgentID, typename Node, typename InjData, typename ObsData>
177 duration interactive_system<AgentID, Node, InjData, ObsData>::micro_planned_event(const AgentID& agent_id, duration elapsed_dt)
178 {
179  micro_planned_update(agent_id, elapsed_dt);
180  planned_dt_ -= elapsed_dt;
181  return planned_dt_;
182 }
183 
184 
185 template<typename AgentID, typename Node, typename InjData, typename ObsData>
186 duration interactive_system<AgentID, Node, InjData, ObsData>::macro_planned_event(duration elapsed_dt)
187 {
188  ++frame_index_;
189  planned_dt_ = macro_planned_update(elapsed_dt, injection_, observation_);
190  if (planned_dt_ <= 0_s) throw std::logic_error("Planned duration between interact events in interactive system (" + this->full_name() + ") must be positive.");
191  return planned_dt_;
192 }
193 
194 
195 template<typename AgentID, typename Node, typename InjData, typename ObsData>
196 void interactive_system<AgentID, Node, InjData, ObsData>::macro_finalization_event(duration elapsed_dt)
197 {
198  macro_finalization_update(elapsed_dt);
199 }
200 
201 
202 template<typename AgentID, typename Node, typename InjData, typename ObsData>
204 {
205  return injection_;
206 }
207 
208 
209 template<typename AgentID, typename Node, typename InjData, typename ObsData>
211 {
212  return observation_;
213 }
214 
215 
216 template<typename AgentID, typename Node, typename InjData, typename ObsData>
218  : injection_(inj)
219  , observation_(obs)
220 {
221 }
222 
223 
224 } // namespace
225 } // namespace
226 
227 #endif
const std::string & node_name() const
Returns the name of the node.
Definition: system_node.h:135
const ObsData & observation()
Definition: interactive_system.h:210
std::unique_ptr< interaction_data > acquire_interaction_data()
Transfers ownership of the interaction data object to the caller.
Definition: interactive_system.h:116
interactive_system(const std::string &node_name, const node_context &external_context)
Constructs an interactive_system node.
Definition: interactive_system.h:149
virtual ~interactive_system()=default
Destructor.
duration planned_duration() const
Returns the planned duration until the next frame is to be processed.
Definition: interactive_system.h:130
constexpr auto _s
Definition: units.h:128
InjData injection_type
Definition: interactive_system.h:52
int64 frame_index() const
Returns the index of the most recently processed frame.
Definition: interactive_system.h:123
Definition: node_context.h:16
A base class template for all collection nodes.
Definition: collection_node.h:55
quantity< seconds > duration
Definition: quantity.h:1006
Definition: interactive_system.h:100
InjData & injection()
Definition: interactive_system.h:203
A base class template for all interactive closed system nodes intended to be used at the highest leve...
Definition: interactive_system.h:49
ObsData observation_type
Definition: interactive_system.h:53