helics  3.3.0
Subscriptions.hpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2017-2022,
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 <algorithm>
12 #include <array>
13 #include <string>
14 #include <utility>
15 #include <vector>
16 
21 namespace helics {
22 
30 template<class X>
31 X getValue(ValueFederate& fed, std::string_view key)
32 {
33  return fed.getInput(key).getValue<X>();
34 }
35 
44 template<class X>
45 void getValue(ValueFederate& fed, std::string_view key, X& obj)
46 {
47  fed.getSubscription(key).getValue<X>(obj);
48 }
49 
53 template<class X>
55  private:
56  ValueFederate* fed = nullptr;
57  std::string m_key;
58  std::string m_units;
59  std::vector<Input> ids;
60  std::function<void(int, Time)>
61  update_callback;
62  std::vector<X> vals;
63  public:
64  VectorSubscription() noexcept {};
74  std::string_view key,
75  int startIndex,
76  int count,
77  const X& defValue,
78  std::string_view units = std::string_view{}):
79  fed(valueFed),
80  m_key(key), m_units(units)
81  {
82  ids.reserve(count);
83  vals.resize(count, defValue);
84 
85  for (auto ind = startIndex; ind < startIndex + count; ++ind) {
86  auto id = fed->registerIndexedSubscription(m_key, ind, m_units);
87  ids.push_back(id);
88  }
89 
90  for (auto& id : ids) {
91  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
92  handleCallback(inp, tm);
93  });
94  }
95  }
104  template<class FedPtr>
105  VectorSubscription(FedPtr valueFed,
106  std::string_view key,
107  int startIndex,
108  int count,
109  const X& defValue,
110  std::string_view units = std::string_view{}):
111  VectorSubscription(std::addressof(*valueFed), key, startIndex, count, defValue, units)
112  {
113  static_assert(
114  std::is_base_of<ValueFederate, std::remove_reference_t<decltype(*valueFed)>>::value,
115  "first argument must be a pointer to a ValueFederate");
116  }
117 
120  fed(vs.fed), m_key(std::move(vs.m_key)), m_units(std::move(vs.m_units)),
121  ids(std::move(vs.ids)), update_callback(std::move(vs.update_callback)),
122  vals(std::move(vs.vals))
123  {
124  // need to transfer the callback to the new object
125  for (auto& id : ids) {
126  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
127  handleCallback(inp, tm);
128  });
129  }
130  };
133  {
134  fed = vs.fed;
135  m_key = std::move(vs.m_key);
136  m_units = std::move(vs.m_units);
137  ids = std::move(vs.ids);
138  update_callback = std::move(vs.update_callback);
139  vals = std::move(vs.vals);
140  // need to transfer the callback to the new object
141  for (auto& id : ids) {
142  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
143  handleCallback(inp, tm);
144  });
145  }
146  return *this;
147  }
150  const std::vector<X>& getVals() const { return vals; }
153  const X& operator[](int index) const { return vals[index]; }
159  void setInputNotificationCallback(std::function<void(int, Time)> callback)
160  {
161  update_callback = std::move(callback);
162  }
163 
164  private:
165  void handleCallback(Input& inp, Time time)
166  {
167  auto res = std::lower_bound(ids.begin(), ids.end(), inp);
168  int index = static_cast<int>(res - ids.begin());
169  vals[index] = inp.getValue<X>();
170  if (update_callback) {
171  update_callback(index, time);
172  }
173  }
174 };
175 
178 template<class X>
180  private:
181  ValueFederate* fed = nullptr;
182  std::string m_key;
183  std::string m_units;
184  std::vector<Input> ids;
185  std::function<void(int, Time)>
186  update_callback;
187  std::vector<X> vals;
188  std::array<int, 4> indices{{0, 0, 0, 0}};
189  public:
190  VectorSubscription2d() noexcept {};
191 
202  template<class FedPtr>
203  VectorSubscription2d(FedPtr valueFed,
204  std::string_view key,
205  int startIndex_x,
206  int count_x,
207  int startIndex_y,
208  int count_y,
209  const X& defValue,
210  std::string_view units = std::string_view()):
211  fed(std::addressof(*valueFed)),
212  m_key(key), m_units(units)
213  {
214  static_assert(
215  std::is_base_of<ValueFederate, std::remove_reference_t<decltype(*valueFed)>>::value,
216  "Second argument must be a pointer to a ValueFederate");
217  ids.reserve(count_x * count_y);
218  vals.resize(count_x * count_y, defValue);
219 
220  for (auto ind_x = startIndex_x; ind_x < startIndex_x + count_x; ++ind_x) {
221  for (auto ind_y = startIndex_y; ind_y < startIndex_y + count_y; ++ind_y) {
222  auto id = fed->registerIndexedSubscription(m_key, ind_x, ind_y, m_units);
223  ids.push_back(id);
224  }
225  }
226 
227  indices[0] = startIndex_x;
228  indices[1] = count_x;
229  indices[2] = startIndex_y;
230  indices[3] = count_y;
231  for (auto& id : ids) {
232  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
233  handleCallback(inp, tm);
234  });
235  }
236  }
237 
240  {
241  fed = vs.fed;
242  m_key = std::move(vs.m_key);
243  m_units = std::move(vs.m_units);
244  ids = std::move(vs.ids);
245  update_callback = std::move(vs.update_callback);
246  vals = std::move(vs.vals);
247  // need to transfer the callback to the new object
248  for (auto& id : ids) {
249  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
250  handleCallback(inp, tm);
251  });
252  }
253  indices = vs.indices;
254  return *this;
255  }
258  const std::vector<X>& getVals() const { return vals; }
262  const X& operator[](int index) const { return vals[index]; }
263 
266  const X& at(int index_x, int index_y) const
267  {
268  return vals[(index_x - indices[0]) * indices[3] + (index_y - indices[2])];
269  }
275  void setInputNotificationCallback(std::function<void(int, Time)> callback)
276  {
277  update_callback = std::move(callback);
278  }
279 
280  private:
281  void handleCallback(const Input& inp, Time time)
282  {
283  auto res = std::lower_bound(ids.begin(), ids.end(), inp);
284  int index = static_cast<int>(res - ids.begin());
285  ids[index].getValue(vals[index]);
286  if (update_callback) {
287  update_callback(index, time);
288  }
289  }
290 };
291 
292 } // namespace helics
helics::Input
Definition: Inputs.hpp:38
helics::ValueFederate::getSubscription
const Input & getSubscription(std::string_view target) const
Definition: ValueFederate.cpp:579
helics::ValueFederate
Definition: application_api/ValueFederate.hpp:26
helics::VectorSubscription::VectorSubscription
VectorSubscription(FedPtr valueFed, std::string_view key, int startIndex, int count, const X &defValue, std::string_view units=std::string_view{})
Definition: Subscriptions.hpp:105
helics::VectorSubscription::getVals
const std::vector< X > & getVals() const
Definition: Subscriptions.hpp:150
helics::VectorSubscription::VectorSubscription
VectorSubscription(VectorSubscription &&vs) noexcept
Definition: Subscriptions.hpp:119
helics::VectorSubscription2d::VectorSubscription2d
VectorSubscription2d(FedPtr valueFed, std::string_view key, int startIndex_x, int count_x, int startIndex_y, int count_y, const X &defValue, std::string_view units=std::string_view())
Definition: Subscriptions.hpp:203
helics::getValue
X getValue(ValueFederate &fed, std::string_view key)
Definition: Subscriptions.hpp:31
helics::Time
TimeRepresentation< count_time< 9 > > Time
Definition: helicsTime.hpp:27
helics::ValueFederate::getInput
const Input & getInput(std::string_view name) const
Definition: ValueFederate.cpp:540
helics::ValueFederate::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(Input &, Time)> callback)
Definition: ValueFederate.cpp:629
helics::VectorSubscription2d::at
const X & at(int index_x, int index_y) const
Definition: Subscriptions.hpp:266
helics::ValueFederate::registerIndexedSubscription
Input & registerIndexedSubscription(std::string_view target, int index1, std::string_view units=std::string_view{})
Definition: application_api/ValueFederate.hpp:255
helics::Input::getValue
int getValue(double *data, int maxsize)
Definition: Inputs.cpp:850
helics::VectorSubscription::operator=
VectorSubscription & operator=(VectorSubscription &&vs) noexcept
Definition: Subscriptions.hpp:132
helics::VectorSubscription2d::operator[]
const X & operator[](int index) const
Definition: Subscriptions.hpp:262
helics::VectorSubscription2d::getVals
const std::vector< X > & getVals() const
Definition: Subscriptions.hpp:258
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:54
helics::VectorSubscription2d::operator=
VectorSubscription2d & operator=(VectorSubscription2d &&vs) noexcept
Definition: Subscriptions.hpp:239
helics::VectorSubscription2d::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(int, Time)> callback)
Definition: Subscriptions.hpp:275
helics::VectorSubscription::VectorSubscription
VectorSubscription(ValueFederate *valueFed, std::string_view key, int startIndex, int count, const X &defValue, std::string_view units=std::string_view{})
Definition: Subscriptions.hpp:73
helics::VectorSubscription2d
Definition: Subscriptions.hpp:179
helics::VectorSubscription::operator[]
const X & operator[](int index) const
Definition: Subscriptions.hpp:153
helics::VectorSubscription::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(int, Time)> callback)
Definition: Subscriptions.hpp:159