helics  3.5.2
Subscriptions.hpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2017-2024,
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 
26 template<class X>
28  private:
29  ValueFederate* fed = nullptr;
30  std::string m_key;
31  std::string m_units;
32  std::vector<Input> ids;
33  std::function<void(int, Time)>
34  update_callback;
35  std::vector<X> vals;
36  public:
37  VectorSubscription() noexcept {};
47  std::string_view key,
48  int startIndex,
49  int count,
50  const X& defValue,
51  std::string_view units = std::string_view{}):
52  fed(valueFed), m_key(key), m_units(units)
53  {
54  ids.reserve(count);
55  vals.resize(count, defValue);
56 
57  for (auto ind = startIndex; ind < startIndex + count; ++ind) {
58  auto id = fed->registerIndexedSubscription(m_key, ind, m_units);
59  ids.push_back(id);
60  }
61 
62  for (auto& id : ids) {
63  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
64  handleCallback(inp, tm);
65  });
66  }
67  }
76  template<class FedPtr>
77  VectorSubscription(FedPtr valueFed,
78  std::string_view key,
79  int startIndex,
80  int count,
81  const X& defValue,
82  std::string_view units = std::string_view{}):
83  VectorSubscription(std::addressof(*valueFed), key, startIndex, count, defValue, units)
84  {
85  static_assert(
86  std::is_base_of<ValueFederate, std::remove_reference_t<decltype(*valueFed)>>::value,
87  "first argument must be a pointer to a ValueFederate");
88  }
89 
92  fed(vs.fed), m_key(std::move(vs.m_key)), m_units(std::move(vs.m_units)),
93  ids(std::move(vs.ids)), update_callback(std::move(vs.update_callback)),
94  vals(std::move(vs.vals))
95  {
96  // need to transfer the callback to the new object
97  for (auto& id : ids) {
98  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
99  handleCallback(inp, tm);
100  });
101  }
102  };
105  {
106  fed = vs.fed;
107  m_key = std::move(vs.m_key);
108  m_units = std::move(vs.m_units);
109  ids = std::move(vs.ids);
110  update_callback = std::move(vs.update_callback);
111  vals = std::move(vs.vals);
112  // need to transfer the callback to the new object
113  for (auto& id : ids) {
114  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
115  handleCallback(inp, tm);
116  });
117  }
118  return *this;
119  }
122  const std::vector<X>& getVals() const { return vals; }
125  const X& operator[](int index) const { return vals[index]; }
131  void setInputNotificationCallback(std::function<void(int, Time)> callback)
132  {
133  update_callback = std::move(callback);
134  }
135 
136  private:
137  void handleCallback(Input& inp, Time time)
138  {
139  auto res = std::lower_bound(ids.begin(), ids.end(), inp);
140  int index = static_cast<int>(res - ids.begin());
141  vals[index] = inp.getValue<X>();
142  if (update_callback) {
143  update_callback(index, time);
144  }
145  }
146 };
147 
150 template<class X>
152  private:
153  ValueFederate* fed = nullptr;
154  std::string m_key;
155  std::string m_units;
156  std::vector<Input> ids;
157  std::function<void(int, Time)>
158  update_callback;
159  std::vector<X> vals;
160  std::array<int, 4> indices{{0, 0, 0, 0}};
161  public:
162  VectorSubscription2d() noexcept {};
163 
174  template<class FedPtr>
175  VectorSubscription2d(FedPtr valueFed,
176  std::string_view key,
177  int startIndex_x,
178  int count_x,
179  int startIndex_y,
180  int count_y,
181  const X& defValue,
182  std::string_view units = std::string_view()):
183  fed(std::addressof(*valueFed)), m_key(key), m_units(units)
184  {
185  static_assert(
186  std::is_base_of<ValueFederate, std::remove_reference_t<decltype(*valueFed)>>::value,
187  "Second argument must be a pointer to a ValueFederate");
188  std::size_t arrayCount =
189  static_cast<std::size_t>(count_x) * static_cast<std::size_t>(count_y);
190  ids.reserve(arrayCount);
191  vals.resize(arrayCount, defValue);
192 
193  for (auto ind_x = startIndex_x; ind_x < startIndex_x + count_x; ++ind_x) {
194  for (auto ind_y = startIndex_y; ind_y < startIndex_y + count_y; ++ind_y) {
195  auto id = fed->registerIndexedSubscription(m_key, ind_x, ind_y, m_units);
196  ids.push_back(id);
197  }
198  }
199 
200  indices[0] = startIndex_x;
201  indices[1] = count_x;
202  indices[2] = startIndex_y;
203  indices[3] = count_y;
204  for (auto& id : ids) {
205  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
206  handleCallback(inp, tm);
207  });
208  }
209  }
210 
213  {
214  fed = vs.fed;
215  m_key = std::move(vs.m_key);
216  m_units = std::move(vs.m_units);
217  ids = std::move(vs.ids);
218  update_callback = std::move(vs.update_callback);
219  vals = std::move(vs.vals);
220  // need to transfer the callback to the new object
221  for (auto& id : ids) {
222  fed->setInputNotificationCallback(id, [this](Input& inp, Time tm) {
223  handleCallback(inp, tm);
224  });
225  }
226  indices = vs.indices;
227  return *this;
228  }
231  const std::vector<X>& getVals() const { return vals; }
235  const X& operator[](int index) const { return vals[index]; }
236 
239  const X& at(int index_x, int index_y) const
240  {
241  return vals[(index_x - indices[0]) * indices[3] + (index_y - indices[2])];
242  }
248  void setInputNotificationCallback(std::function<void(int, Time)> callback)
249  {
250  update_callback = std::move(callback);
251  }
252 
253  private:
254  void handleCallback(const Input& inp, Time time)
255  {
256  auto res = std::lower_bound(ids.begin(), ids.end(), inp);
257  int index = static_cast<int>(res - ids.begin());
258  ids[index].getValue(vals[index]);
259  if (update_callback) {
260  update_callback(index, time);
261  }
262  }
263 };
264 
265 } // namespace helics
Definition: Inputs.hpp:38
int getValue(double *data, int maxsize)
Definition: Inputs.cpp:880
Definition: application_api/ValueFederate.hpp:28
Input & registerIndexedSubscription(std::string_view target, int index1, std::string_view units=std::string_view{})
Definition: application_api/ValueFederate.hpp:257
void setInputNotificationCallback(std::function< void(Input &, Time)> callback)
Definition: ValueFederate.cpp:694
Definition: Subscriptions.hpp:151
const std::vector< X > & getVals() const
Definition: Subscriptions.hpp:231
const X & operator[](int index) const
Definition: Subscriptions.hpp:235
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:175
VectorSubscription2d & operator=(VectorSubscription2d &&vs) noexcept
Definition: Subscriptions.hpp:212
const X & at(int index_x, int index_y) const
Definition: Subscriptions.hpp:239
void setInputNotificationCallback(std::function< void(int, Time)> callback)
Definition: Subscriptions.hpp:248
Definition: Subscriptions.hpp:27
VectorSubscription & operator=(VectorSubscription &&vs) noexcept
Definition: Subscriptions.hpp:104
VectorSubscription(FedPtr valueFed, std::string_view key, int startIndex, int count, const X &defValue, std::string_view units=std::string_view{})
Definition: Subscriptions.hpp:77
VectorSubscription(ValueFederate *valueFed, std::string_view key, int startIndex, int count, const X &defValue, std::string_view units=std::string_view{})
Definition: Subscriptions.hpp:46
const X & operator[](int index) const
Definition: Subscriptions.hpp:125
void setInputNotificationCallback(std::function< void(int, Time)> callback)
Definition: Subscriptions.hpp:131
VectorSubscription(VectorSubscription &&vs) noexcept
Definition: Subscriptions.hpp:91
const std::vector< X > & getVals() const
Definition: Subscriptions.hpp:122
the main namespace for the helics co-simulation library User functions will be in the helics namespac...
Definition: AsyncFedCallInfo.hpp:14
TimeRepresentation< count_time< 9 > > Time
Definition: helicsTime.hpp:27