| helics 3.6.1

Subscriptions.hpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2017-2025,
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>
27 class VectorSubscription {
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 {};
46 VectorSubscription(ValueFederate* valueFed,
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
91 VectorSubscription(VectorSubscription&& vs) noexcept:
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 };
104 VectorSubscription& operator=(VectorSubscription&& vs) noexcept
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>
151 class VectorSubscription2d {
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
212 VectorSubscription2d& operator=(VectorSubscription2d&& vs) noexcept
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
helics::Input
Definition: Inputs.hpp:38
helics::Input::getValue
int getValue(double *data, int maxsize)
Definition: Inputs.cpp:882
helics::ValueFederate
Definition: application_api/ValueFederate.hpp:28
helics::ValueFederate::registerIndexedSubscription
Input & registerIndexedSubscription(std::string_view target, int index1, std::string_view units=std::string_view{})
Definition: application_api/ValueFederate.hpp:257
helics::ValueFederate::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(Input &, Time)> callback)
Definition: ValueFederate.cpp:696
helics::VectorSubscription2d
Definition: Subscriptions.hpp:151
helics::VectorSubscription2d::getVals
const std::vector< X > & getVals() const
Definition: Subscriptions.hpp:231
helics::VectorSubscription2d::operator[]
const X & operator[](int index) const
Definition: Subscriptions.hpp:235
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:175
helics::VectorSubscription2d::operator=
VectorSubscription2d & operator=(VectorSubscription2d &&vs) noexcept
Definition: Subscriptions.hpp:212
helics::VectorSubscription2d::at
const X & at(int index_x, int index_y) const
Definition: Subscriptions.hpp:239
helics::VectorSubscription2d::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(int, Time)> callback)
Definition: Subscriptions.hpp:248
helics::VectorSubscription
Definition: Subscriptions.hpp:27
helics::VectorSubscription::operator=
VectorSubscription & operator=(VectorSubscription &&vs) noexcept
Definition: Subscriptions.hpp:104
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:77
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:46
helics::VectorSubscription::operator[]
const X & operator[](int index) const
Definition: Subscriptions.hpp:125
helics::VectorSubscription::setInputNotificationCallback
void setInputNotificationCallback(std::function< void(int, Time)> callback)
Definition: Subscriptions.hpp:131
helics::VectorSubscription::VectorSubscription
VectorSubscription(VectorSubscription &&vs) noexcept
Definition: Subscriptions.hpp:91
helics::VectorSubscription::getVals
const std::vector< X > & getVals() const
Definition: Subscriptions.hpp:122
helics
the main namespace for the helics co-simulation library User functions will be in the helics namespac...
Definition: AsyncFedCallInfo.hpp:14
helics::Time
TimeRepresentation< count_time< 9 > > Time
Definition: helicsTime.hpp:27