helics  3.0.1
Subscriptions.hpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2017-2021,
3 Battelle Memorial Institute; Lawrence Livermore National Security, LLC; Alliance for Sustainable
4 Energy, LLC. See the top-level NOTICE for additional details. All rights reserved.
5 SPDX-License-Identifier: BSD-3-Clause
6 */
7 #pragma once
8 
9 #include "ValueFederate.hpp"
10 
11 #include <array>
12 #include <string>
13 #include <utility>
14 #include <vector>
15 
20 namespace helics {
21 
29 template<class X>
30 X getValue(ValueFederate& fed, const std::string& key)
31 {
32  return fed.getInput(key).getValue<X>();
33 }
34 
43 template<class X>
44 void getValue(ValueFederate& fed, const std::string& key, X& obj)
45 {
46  fed.getSubscription(key).getValue<X>(obj);
47 }
48 
52 template<class X>
54  private:
55  ValueFederate* fed = nullptr;
56  std::string m_key;
57  std::string m_units;
58  std::vector<Input> ids;
59  std::function<void(int, Time)>
60  update_callback;
61  std::vector<X> vals;
62  public:
63  VectorSubscription() noexcept {};
73  const std::string& key,
74  int startIndex,
75  int count,
76  const X& defValue,
77  const std::string& units = std::string()):
78  fed(valueFed),
79  m_key(key), m_units(units)
80  {
81  ids.reserve(count);
82  vals.resize(count, defValue);
83 
84  for (auto ind = startIndex; ind < startIndex + count; ++ind) {
85  auto id = fed->registerIndexedSubscription(m_key, ind, m_units);
86  ids.push_back(id);
87  }
88 
89  for (auto& id : ids) {
90  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
91  handleCallback(inp, tm);
92  });
93  }
94  }
103  template<class FedPtr>
104  VectorSubscription(FedPtr valueFed,
105  const std::string& key,
106  int startIndex,
107  int count,
108  const X& defValue,
109  const std::string& units = std::string()):
110  VectorSubscription(std::addressof(*valueFed), key, startIndex, count, defValue, units)
111  {
112  static_assert(
113  std::is_base_of<ValueFederate, std::remove_reference_t<decltype(*valueFed)>>::value,
114  "first argument must be a pointer to a ValueFederate");
115  }
116 
119  fed(vs.fed), m_key(std::move(vs.m_key)), m_units(std::move(vs.m_units)),
120  ids(std::move(vs.ids)), update_callback(std::move(vs.update_callback)),
121  vals(std::move(vs.vals))
122  {
123  // need to transfer the callback to the new object
124  for (auto& id : ids) {
125  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
126  handleCallback(inp, tm);
127  });
128  }
129  };
132  {
133  fed = vs.fed;
134  m_key = std::move(vs.m_key);
135  m_units = std::move(vs.m_units);
136  ids = std::move(vs.ids);
137  update_callback = std::move(vs.update_callback);
138  vals = std::move(vs.vals);
139  // need to transfer the callback to the new object
140  for (auto& id : ids) {
141  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
142  handleCallback(inp, tm);
143  });
144  }
145  return *this;
146  }
149  const std::vector<X>& getVals() const { return vals; }
152  const X& operator[](int index) const { return vals[index]; }
158  void setInputNotificationCallback(std::function<void(int, Time)> callback)
159  {
160  update_callback = std::move(callback);
161  }
162 
163  private:
164  void handleCallback(Input& inp, Time time)
165  {
166  auto res = std::lower_bound(ids.begin(), ids.end(), inp);
167  int index = static_cast<int>(res - ids.begin());
168  vals[index] = inp.getValue<X>();
169  if (update_callback) {
170  update_callback(index, time);
171  }
172  }
173 };
174 
177 template<class X>
179  private:
180  ValueFederate* fed = nullptr;
181  std::string m_key;
182  std::string m_units;
183  std::vector<Input> ids;
184  std::function<void(int, Time)>
185  update_callback;
186  std::vector<X> vals;
187  std::array<int, 4> indices{{0, 0, 0, 0}};
188  public:
189  VectorSubscription2d() noexcept {};
190 
201  template<class FedPtr>
202  VectorSubscription2d(FedPtr valueFed,
203  const std::string& key,
204  int startIndex_x,
205  int count_x,
206  int startIndex_y,
207  int count_y,
208  const X& defValue,
209  const std::string& units = std::string()):
210  fed(std::addressof(*valueFed)),
211  m_key(key), m_units(units)
212  {
213  static_assert(
214  std::is_base_of<ValueFederate, std::remove_reference_t<decltype(*valueFed)>>::value,
215  "Second argument must be a pointer to a ValueFederate");
216  ids.reserve(count_x * count_y);
217  vals.resize(count_x * count_y, defValue);
218 
219  for (auto ind_x = startIndex_x; ind_x < startIndex_x + count_x; ++ind_x) {
220  for (auto ind_y = startIndex_y; ind_y < startIndex_y + count_y; ++ind_y) {
221  auto id = fed->registerIndexedSubscription(m_key, ind_x, ind_y, m_units);
222  ids.push_back(id);
223  }
224  }
225 
226  indices[0] = startIndex_x;
227  indices[1] = count_x;
228  indices[2] = startIndex_y;
229  indices[3] = count_y;
230  for (auto& id : ids) {
231  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
232  handleCallback(inp, tm);
233  });
234  }
235  }
236 
239  {
240  fed = vs.fed;
241  m_key = std::move(vs.m_key);
242  m_units = std::move(vs.m_units);
243  ids = std::move(vs.ids);
244  update_callback = std::move(vs.update_callback);
245  vals = std::move(vs.vals);
246  // need to transfer the callback to the new object
247  for (auto& id : ids) {
248  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
249  handleCallback(inp, tm);
250  });
251  }
252  indices = vs.indices;
253  return *this;
254  }
257  const std::vector<X>& getVals() const { return vals; }
261  const X& operator[](int index) const { return vals[index]; }
262 
265  const X& at(int index_x, int index_y) const
266  {
267  return vals[(index_x - indices[0]) * indices[3] + (index_y - indices[2])];
268  }
274  void setInputNotificationCallback(std::function<void(int, Time)> callback)
275  {
276  update_callback = std::move(callback);
277  }
278 
279  private:
280  void handleCallback(const Input& inp, Time time)
281  {
282  auto res = std::lower_bound(ids.begin(), ids.end(), inp);
283  int index = static_cast<int>(res - ids.begin());
284  ids[index].getValue(vals[index]);
285  if (update_callback) {
286  update_callback(index, time);
287  }
288  }
289 };
290 
291 } // namespace helics
helics::Input
Definition: Inputs.hpp:38
helics::VectorSubscription::VectorSubscription
VectorSubscription(FedPtr valueFed, const std::string &key, int startIndex, int count, const X &defValue, const std::string &units=std::string())
Definition: Subscriptions.hpp:104
helics::VectorSubscription::VectorSubscription
VectorSubscription(ValueFederate *valueFed, const std::string &key, int startIndex, int count, const X &defValue, const std::string &units=std::string())
Definition: Subscriptions.hpp:72
helics::ValueFederate
Definition: application_api/ValueFederate.hpp:25
helics::VectorSubscription::getVals
const std::vector< X > & getVals() const
Definition: Subscriptions.hpp:149
helics::VectorSubscription::VectorSubscription
VectorSubscription(VectorSubscription &&vs) noexcept
Definition: Subscriptions.hpp:118
helics::Time
TimeRepresentation< count_time< 9 > > Time
Definition: helicsTime.hpp:27
helics::VectorSubscription2d::VectorSubscription2d
VectorSubscription2d(FedPtr valueFed, const std::string &key, int startIndex_x, int count_x, int startIndex_y, int count_y, const X &defValue, const std::string &units=std::string())
Definition: Subscriptions.hpp:202
helics::ValueFederate::registerIndexedSubscription
Input & registerIndexedSubscription(const std::string &target, int index1, const std::string &units=std::string())
Definition: application_api/ValueFederate.hpp:255
helics::ValueFederate::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(Input &, Time)> callback)
Definition: ValueFederate.cpp:616
helics::VectorSubscription2d::at
const X & at(int index_x, int index_y) const
Definition: Subscriptions.hpp:265
helics::Input::getValue
int getValue(double *data, int maxsize)
Definition: Inputs.cpp:847
helics::ValueFederate::getSubscription
const Input & getSubscription(const std::string &target) const
Definition: ValueFederate.cpp:566
helics::VectorSubscription::operator=
VectorSubscription & operator=(VectorSubscription &&vs) noexcept
Definition: Subscriptions.hpp:131
helics::VectorSubscription2d::operator[]
const X & operator[](int index) const
Definition: Subscriptions.hpp:261
helics::VectorSubscription2d::getVals
const std::vector< X > & getVals() const
Definition: Subscriptions.hpp:257
helics
the main namespace for the helics co-simulation library User functions will be in the helics namespac...
Definition: AsyncFedCallInfo.hpp:14
helics::VectorSubscription
Definition: Subscriptions.hpp:53
helics::VectorSubscription2d::operator=
VectorSubscription2d & operator=(VectorSubscription2d &&vs) noexcept
Definition: Subscriptions.hpp:238
helics::VectorSubscription2d::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(int, Time)> callback)
Definition: Subscriptions.hpp:274
helics::getValue
X getValue(ValueFederate &fed, const std::string &key)
Definition: Subscriptions.hpp:30
helics::VectorSubscription2d
Definition: Subscriptions.hpp:178
helics::VectorSubscription::operator[]
const X & operator[](int index) const
Definition: Subscriptions.hpp:152
helics::ValueFederate::getInput
const Input & getInput(const std::string &name) const
Definition: ValueFederate.cpp:528
helics::VectorSubscription::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(int, Time)> callback)
Definition: Subscriptions.hpp:158