9 #include "Federate.hpp"
25 enum MultiInputHandlingMethod : uint16_t {
42 int referenceIndex{-1};
43 void* dataReference{
nullptr};
48 bool changeDetectionEnabled{
false};
49 bool hasUpdate{
false};
50 bool disableAssign{
false};
51 bool useThreshold{
false};
52 bool multiUnits{
false};
53 MultiInputHandlingMethod inputVectorOp{
54 MultiInputHandlingMethod::NO_OP};
55 int32_t prevInputCount{0};
56 size_t customTypeHash{0U};
58 std::shared_ptr<units::precise_unit> outputUnits;
59 std::shared_ptr<units::precise_unit> inputUnits;
60 std::vector<std::pair<DataType, std::shared_ptr<units::precise_unit>>>
62 std::string givenTarget;
64 double threshold{0.0};
66 std::variant<std::function<void(
const double&,
Time)>,
67 std::function<void(
const int64_t&,
Time)>,
68 std::function<void(
const std::string&,
Time)>,
69 std::function<void(
const std::complex<double>&,
Time)>,
70 std::function<void(
const std::vector<double>&,
Time)>,
71 std::function<void(
const std::vector<std::complex<double>>&,
Time)>,
72 std::function<void(
const NamedPoint&,
Time)>,
73 std::function<void(
const bool&,
Time)>,
74 std::function<void(
const Time&,
Time)>>
80 Input(ValueFederate* valueFed,
82 const std::string& actName,
83 const std::string& unitsOut = std::string{});
85 Input(ValueFederate* valueFed,
86 const std::string& key,
87 const std::string& defaultType =
"def",
88 const std::string& units = std::string{});
90 template<
class FedPtr>
91 Input(FedPtr& valueFed,
92 const std::string& key,
93 const std::string& defaultType =
"def",
94 const std::string& units = std::string{}):
95 Input(std::addressof(*valueFed), key, defaultType, units)
98 std::is_base_of<ValueFederate, std::remove_reference_t<decltype(*valueFed)>>::value,
99 "first argument must be a pointer to a ValueFederate");
103 ValueFederate* valueFed,
104 const std::string& key,
105 const std::string& defaultType =
"def",
106 const std::string& units = std::string{});
108 template<
class FedPtr>
111 const std::string& key,
112 const std::string& defaultType =
"def",
113 const std::string& units = std::string{}):
114 Input(locality, std::addressof(*valueFed), key, defaultType, units)
117 std::is_base_of<ValueFederate, std::remove_reference_t<decltype(*valueFed)>>::value,
118 "first argument must be a pointer to a ValueFederate");
121 Input(ValueFederate* valueFed,
122 const std::string& key,
124 const std::string& units = std::string{}):
129 template<
class FedPtr>
130 Input(FedPtr& valueFed,
131 const std::string& key,
133 const std::string& units = std::string()):
139 ValueFederate* valueFed,
140 const std::string& key,
141 const std::string& units = std::string{}):
142 Input(locality, valueFed, key,
"def", units)
146 template<
class FedPtr>
149 const std::string& key,
150 const std::string& units = std::string{}):
151 Input(locality, valueFed, key,
"def", units)
156 ValueFederate* valueFed,
157 const std::string& key,
159 const std::string& units = std::string{}):
164 template<
class FedPtr>
167 const std::string& key,
169 const std::string& units = std::string{}):
177 Time getLastUpdate()
const;
184 void registerNotificationCallback(std::function<
void(
Time)> callback);
190 (injectionType == DataType::HELICS_CUSTOM)) ?
195 const std::string&
getType()
const {
return getExtractionType(); }
197 const std::string&
getUnits()
const {
return getExtractionUnits(); }
199 void addTarget(
const std::string& target);
206 bool checkUpdate(
bool assumeUpdate =
false);
220 bool isUpdated()
const;
222 virtual void setOption(int32_t option, int32_t value = 1)
override;
223 virtual int32_t getOption(int32_t option)
const override;
233 helicsType<X>() != DataType::HELICS_CUSTOM,
234 "callback type must be a primary helics type one of \"double, int64_t, named_point, bool, Time "
235 "std::vector<double>, std::vector<std::complex<double>>, std::complex<double>\"");
236 value_callback = std::move(callback);
242 void setDefault_impl(std::integral_constant<int, 0> , X&& val)
249 void setDefault_impl(std::integral_constant<int, 1> , X&& val)
255 void setDefault_impl(std::integral_constant<int, 2> , X&& val)
257 auto res = ValueConverter<remove_cv_ref<X>>::convert(std::forward<X>(val));
258 lastValue = std::string(res.to_string());
259 setDefaultBytes(res);
263 void registerCallback();
282 changeDetectionEnabled =
true;
287 changeDetectionEnabled =
false;
297 void handleCallback(
Time time);
299 void getValue_impl(std::integral_constant<int, primaryType> , X& out);
302 void getValue_impl(std::integral_constant<int, primaryType> ,
char& out)
304 out = getValueChar();
308 void getValue_impl(std::integral_constant<int, convertibleType> ,
char& out)
310 out = getValueChar();
314 void getValue_impl(std::integral_constant<int, convertibleType> , X& out)
316 std::conditional_t<std::is_integral<X>::value,
317 std::conditional_t<std::is_same<X, char>::value, char, int64_t>,
320 getValue_impl(std::integral_constant<int, primaryType>(), gval);
321 out =
static_cast<X
>(gval);
325 void getValue_impl(std::integral_constant<int, nonConvertibleType> , X& out)
331 X getValue_impl(std::integral_constant<int, primaryType> )
334 getValue_impl(std::integral_constant<int, primaryType>(), val);
339 X getValue_impl(std::integral_constant<int, convertibleType> )
341 std::conditional_t<std::is_integral<X>::value,
342 std::conditional_t<std::is_same<X, char>::value, char, int64_t>,
345 getValue_impl(std::integral_constant<int, primaryType>(), gval);
346 return static_cast<X
>(gval);
350 X getValue_impl(std::integral_constant<int, nonConvertibleType> )
357 int getValue(
double* data,
int maxsize);
359 int getComplexValue(
double* data,
int maxsize);
361 int getValue(
char* str,
int maxsize);
379 const X& getValueRef();
381 double getDouble() {
return getValue_impl<double>(std::integral_constant<int, primaryType>()); }
383 const std::string&
getString() {
return getValueRef<std::string>(); }
388 size_t getByteCount();
390 size_t getStringSize();
392 size_t getVectorSize();
400 MultiInputHandlingMethod getMultiInputMode()
const {
return inputVectorOp; }
402 bool vectorDataProcess(
const std::vector<std::shared_ptr<const SmallBuffer>>& dataV);
404 const std::string& getTarget()
const
406 return (!givenTarget.empty()) ? givenTarget : getSourceTargets();
411 return (mName.empty()) ? getTarget() : getName();
416 void loadSourceInformation();
420 bool allowDirectFederateUpdate()
const
422 return hasUpdate && !changeDetectionEnabled &&
423 inputVectorOp == MultiInputHandlingMethod::NO_OP;
425 data_view checkAndGetFedUpdate();
426 void forceCoreDataUpdate();
427 friend class ValueFederateManager;
431 HELICS_CXX_EXPORT
double
433 const std::shared_ptr<units::precise_unit>& inputUnits,
434 const std::shared_ptr<units::precise_unit>& outputUnits);
436 HELICS_CXX_EXPORT
void
437 integerExtractAndConvert(
defV& store,
439 const std::shared_ptr<units::precise_unit>& inputUnits,
440 const std::shared_ptr<units::precise_unit>& outputUnits);
443 void Input::getValue_impl(std::integral_constant<int, primaryType> , X& out)
445 auto dv = checkAndGetFedUpdate();
448 loadSourceInformation();
451 if (injectionType == helics::DataType::HELICS_DOUBLE) {
454 }
else if (injectionType == helics::DataType::HELICS_INT) {
456 integerExtractAndConvert(val, dv, inputUnits, outputUnits);
461 if (changeDetectionEnabled) {
477 inline const X& getValueRefImpl(
defV& val)
479 valueConvert(val, helicsType<X>());
480 return std::get<X>(val);
484 inline const std::string& getValueRefImpl(
defV& val)
487 if ((val.index() == named_point_loc)) {
488 return std::get<NamedPoint>(val).name;
490 valueConvert(val, DataType::HELICS_STRING);
491 return std::get<std::string>(val);
494 HELICS_CXX_EXPORT
bool checkForNeededCoreRetrieval(std::size_t currentIndex,
499 const X& Input::getValueRef()
501 static_assert(std::is_same<typeCategory<X>, std::integral_constant<int, primaryType>>::value,
502 "calling getValue By ref must be with a primary type");
503 auto dv = checkAndGetFedUpdate();
506 loadSourceInformation();
509 if (changeDetectionEnabled) {
511 if (injectionType == helics::DataType::HELICS_DOUBLE) {
514 }
else if (injectionType == helics::DataType::HELICS_INT) {
516 integerExtractAndConvert(val, dv, inputUnits, outputUnits);
528 if (checkForNeededCoreRetrieval(lastValue.index(),
531 forceCoreDataUpdate();
535 return getValueRefImpl<remove_cv_ref<X>>(lastValue);