helics  2.8.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 "Inputs.hpp"
10 
11 #include <array>
12 #include <string>
13 #include <utility>
14 #include <vector>
15 
20 namespace helics {
23  const std::string& key,
24  const std::string& units = std::string())
25 {
26  return valueFed->registerSubscription(key, units);
27 }
28 
31  const std::string& key,
32  const std::string& units = std::string())
33 {
34  return valueFed.registerSubscription(key, units);
35 }
36 
38 template<class X>
39 inline InputT<X> make_subscription(ValueFederate* valueFed,
40  const std::string& key,
41  const std::string& units = std::string())
42 {
43  InputT<X> ipt(valueFed, typeNameString<X>(), units);
44  ipt.addTarget(key);
45  return ipt;
46 }
47 
49 template<class X>
50 inline InputT<X> make_subscription(ValueFederate& valueFed,
51  const std::string& key,
52  const std::string& units = std::string())
53 {
54  InputT<X> ipt(&valueFed, typeNameString<X>(), units);
55  ipt.addTarget(key);
56  return ipt;
57 }
58 
66 template<class X>
67 X getValue(ValueFederate& fed, const std::string& key)
68 {
69  return fed.getInput(key).getValue<X>();
70 }
71 
80 template<class X>
81 void getValue(ValueFederate& fed, const std::string& key, X& obj)
82 {
83  fed.getSubscription(key).getValue<X>(obj);
84 }
85 
89 template<class X>
91  private:
92  ValueFederate* fed = nullptr;
93  std::string m_key;
94  std::string m_units;
95  std::vector<Input> ids;
96  std::function<void(int, Time)>
97  update_callback;
98  std::vector<X> vals;
99  public:
100  VectorSubscription() noexcept {};
110  const std::string& key,
111  int startIndex,
112  int count,
113  const X& defValue,
114  const std::string& units = std::string()):
115  fed(valueFed),
116  m_key(key), m_units(units)
117  {
118  ids.reserve(count);
119  vals.resize(count, defValue);
120 
121  for (auto ind = startIndex; ind < startIndex + count; ++ind) {
122  auto id = fed->registerIndexedSubscription(m_key, ind, m_units);
123  ids.push_back(id);
124  }
125 
126  for (auto& id : ids) {
127  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
128  handleCallback(inp, tm);
129  });
130  }
131  }
140  template<class FedPtr>
141  VectorSubscription(FedPtr valueFed,
142  const std::string& key,
143  int startIndex,
144  int count,
145  const X& defValue,
146  const std::string& units = std::string()):
147  VectorSubscription(std::addressof(*valueFed), key, startIndex, count, defValue, units)
148  {
149  static_assert(
150  std::is_base_of<ValueFederate, std::remove_reference_t<decltype(*valueFed)>>::value,
151  "first argument must be a pointer to a ValueFederate");
152  }
153 
156  fed(vs.fed), m_key(std::move(vs.m_key)), m_units(std::move(vs.m_units)),
157  ids(std::move(vs.ids)), update_callback(std::move(vs.update_callback)),
158  vals(std::move(vs.vals))
159  {
160  // need to transfer the callback to the new object
161  for (auto& id : ids) {
162  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
163  handleCallback(inp, tm);
164  });
165  }
166  };
169  {
170  fed = vs.fed;
171  m_key = std::move(vs.m_key);
172  m_units = std::move(vs.m_units);
173  ids = std::move(vs.ids);
174  update_callback = std::move(vs.update_callback);
175  vals = std::move(vs.vals);
176  // need to transfer the callback to the new object
177  for (auto& id : ids) {
178  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
179  handleCallback(inp, tm);
180  });
181  }
182  return *this;
183  }
186  const std::vector<X>& getVals() const { return vals; }
189  const X& operator[](int index) const { return vals[index]; }
195  void setInputNotificationCallback(std::function<void(int, Time)> callback)
196  {
197  update_callback = std::move(callback);
198  }
199 
200  private:
201  void handleCallback(Input& inp, Time time)
202  {
203  auto res = std::lower_bound(ids.begin(), ids.end(), inp);
204  int index = static_cast<int>(res - ids.begin());
205  vals[index] = inp.getValue<X>();
206  if (update_callback) {
207  update_callback(index, time);
208  }
209  }
210 };
211 
214 template<class X>
216  private:
217  ValueFederate* fed = nullptr;
218  std::string m_key;
219  std::string m_units;
220  std::vector<Input> ids;
221  std::function<void(int, Time)>
222  update_callback;
223  std::vector<X> vals;
224  std::array<int, 4> indices{{0, 0, 0, 0}};
225  public:
226  VectorSubscription2d() noexcept {};
227 
238  template<class FedPtr>
239  VectorSubscription2d(FedPtr valueFed,
240  const std::string& key,
241  int startIndex_x,
242  int count_x,
243  int startIndex_y,
244  int count_y,
245  const X& defValue,
246  const std::string& units = std::string()):
247  fed(std::addressof(*valueFed)),
248  m_key(key), m_units(units)
249  {
250  static_assert(
251  std::is_base_of<ValueFederate, std::remove_reference_t<decltype(*valueFed)>>::value,
252  "Second argument must be a pointer to a ValueFederate");
253  ids.reserve(count_x * count_y);
254  vals.resize(count_x * count_y, defValue);
255 
256  for (auto ind_x = startIndex_x; ind_x < startIndex_x + count_x; ++ind_x) {
257  for (auto ind_y = startIndex_y; ind_y < startIndex_y + count_y; ++ind_y) {
258  auto id = fed->registerIndexedSubscription(m_key, ind_x, ind_y, m_units);
259  ids.push_back(id);
260  }
261  }
262 
263  indices[0] = startIndex_x;
264  indices[1] = count_x;
265  indices[2] = startIndex_y;
266  indices[3] = count_y;
267  for (auto& id : ids) {
268  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
269  handleCallback(inp, tm);
270  });
271  }
272  }
273 
276  {
277  fed = vs.fed;
278  m_key = std::move(vs.m_key);
279  m_units = std::move(vs.m_units);
280  ids = std::move(vs.ids);
281  update_callback = std::move(vs.update_callback);
282  vals = std::move(vs.vals);
283  // need to transfer the callback to the new object
284  for (auto& id : ids) {
285  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
286  handleCallback(inp, tm);
287  });
288  }
289  indices = vs.indices;
290  return *this;
291  }
294  const std::vector<X>& getVals() const { return vals; }
298  const X& operator[](int index) const { return vals[index]; }
299 
302  const X& at(int index_x, int index_y) const
303  {
304  return vals[(index_x - indices[0]) * indices[3] + (index_y - indices[2])];
305  }
311  void setInputNotificationCallback(std::function<void(int, Time)> callback)
312  {
313  update_callback = std::move(callback);
314  }
315 
316  private:
317  void handleCallback(const Input& inp, Time time)
318  {
319  auto res = std::lower_bound(ids.begin(), ids.end(), inp);
320  int index = static_cast<int>(res - ids.begin());
321  ids[index].getValue(vals[index]);
322  if (update_callback) {
323  update_callback(index, time);
324  }
325  }
326 };
327 
328 } // namespace helics
helics::Input
Definition: Inputs.hpp:37
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:141
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:109
helics::ValueFederate
Definition: application_api/ValueFederate.hpp:25
helics::VectorSubscription::getVals
const std::vector< X > & getVals() const
Definition: Subscriptions.hpp:186
helics::VectorSubscription::VectorSubscription
VectorSubscription(VectorSubscription &&vs) noexcept
Definition: Subscriptions.hpp:155
helics::Time
TimeRepresentation< count_time< 9 > > Time
Definition: helics-time.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:239
helics::make_subscription
Input & make_subscription(ValueFederate *valueFed, const std::string &key, const std::string &units=std::string())
Definition: Subscriptions.hpp:22
helics::VectorSubscription2d::at
const X & at(int index_x, int index_y) const
Definition: Subscriptions.hpp:302
fed
@ fed
special logging command for message coming from a fed
Definition: loggingHelper.hpp:32
helics::Input::getValue
int getValue(double *data, int maxsize)
Definition: Inputs.cpp:876
helics::VectorSubscription::operator=
VectorSubscription & operator=(VectorSubscription &&vs) noexcept
Definition: Subscriptions.hpp:168
helics::ValueFederate::registerSubscription
Input & registerSubscription(const std::string &target, const std::string &units=std::string())
Definition: ValueFederate.cpp:130
helics::VectorSubscription2d::operator[]
const X & operator[](int index) const
Definition: Subscriptions.hpp:298
helics::VectorSubscription2d::getVals
const std::vector< X > & getVals() const
Definition: Subscriptions.hpp:294
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:90
helics::VectorSubscription2d::operator=
VectorSubscription2d & operator=(VectorSubscription2d &&vs) noexcept
Definition: Subscriptions.hpp:275
helics::VectorSubscription2d::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(int, Time)> callback)
Definition: Subscriptions.hpp:311
helics::getValue
X getValue(ValueFederate &fed, const std::string &key)
Definition: Subscriptions.hpp:67
helics::VectorSubscription2d
Definition: Subscriptions.hpp:215
helics::VectorSubscription::operator[]
const X & operator[](int index) const
Definition: Subscriptions.hpp:189
helics::VectorSubscription::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(int, Time)> callback)
Definition: Subscriptions.hpp:195