9 #include "Federate.hpp"
25 enum MultiInputHandlingMethod : uint16_t {
42 int referenceIndex{-1};
43 void* dataReference{
nullptr};
45 DataType targetType{DataType::HELICS_UNKNOWN};
47 DataType::HELICS_UNKNOWN};
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 std::string_view actName,
83 std::string_view unitsOut = {});
85 Input(ValueFederate* valueFed,
87 std::string_view defaultType =
"def",
88 std::string_view units = {});
90 template<
class FedPtr>
91 Input(FedPtr& valueFed,
93 std::string_view defaultType =
"def",
94 std::string_view units = {}):
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 std::string_view key,
105 std::string_view defaultType =
"def",
106 std::string_view units = {});
108 template<
class FedPtr>
111 std::string_view key,
112 std::string_view defaultType =
"def",
113 std::string_view units = {}):
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 std::string_view key,
124 std::string_view units = {}):
129 template<
class FedPtr>
130 Input(FedPtr& valueFed, std::string_view key,
DataType defType, std::string_view units = {}):
136 ValueFederate* valueFed,
137 std::string_view key,
138 std::string_view units = {}):
139 Input(locality, valueFed, key,
"def", units)
143 template<
class FedPtr>
146 std::string_view key,
147 std::string_view units = {}):
148 Input(locality, valueFed, key,
"def", units)
153 ValueFederate* valueFed,
154 std::string_view key,
156 std::string_view units = {}):
161 template<
class FedPtr>
164 std::string_view key,
166 std::string_view units = {}):
174 Time getLastUpdate()
const;
181 void registerNotificationCallback(std::function<
void(
Time)> callback);
186 return ((injectionType == DataType::HELICS_UNKNOWN) ||
187 (injectionType == DataType::HELICS_CUSTOM)) ?
192 const std::string&
getType()
const {
return getExtractionType(); }
194 const std::string&
getUnits()
const {
return getExtractionUnits(); }
196 void addPublication(std::string_view target);
198 void addTarget(std::string_view target) { addPublication(target); }
204 bool checkUpdate(
bool assumeUpdate =
false);
218 bool isUpdated()
const;
220 virtual void setOption(int32_t option, int32_t value = 1)
override;
221 virtual int32_t getOption(int32_t option)
const override;
231 helicsType<X>() != DataType::HELICS_CUSTOM,
232 "callback type must be a primary helics type one of \"double, int64_t, named_point, bool, Time "
233 "std::vector<double>, std::vector<std::complex<double>>, std::complex<double>\"");
234 value_callback = std::move(callback);
240 void setDefault_impl(std::integral_constant<int, 0> , X&& val)
247 void setDefault_impl(std::integral_constant<int, 1> , X&& val)
253 void setDefault_impl(std::integral_constant<int, 2> , X&& val)
255 auto res = ValueConverter<remove_cv_ref<X>>::convert(std::forward<X>(val));
256 lastValue = std::string(res.to_string());
257 setDefaultBytes(res);
261 void registerCallback();
280 changeDetectionEnabled =
true;
285 changeDetectionEnabled =
false;
295 void handleCallback(
Time time);
297 void getValue_impl(std::integral_constant<int, primaryType> , X& out);
300 void getValue_impl(std::integral_constant<int, primaryType> ,
char& out)
302 out = getValueChar();
306 void getValue_impl(std::integral_constant<int, convertibleType> ,
char& out)
308 out = getValueChar();
312 void getValue_impl(std::integral_constant<int, convertibleType> , X& out)
314 std::conditional_t<std::is_integral<X>::value,
315 std::conditional_t<std::is_same<X, char>::value, char, int64_t>,
318 getValue_impl(std::integral_constant<int, primaryType>(), gval);
319 out =
static_cast<X
>(gval);
323 void getValue_impl(std::integral_constant<int, nonConvertibleType> , X& out)
329 X getValue_impl(std::integral_constant<int, primaryType> )
332 getValue_impl(std::integral_constant<int, primaryType>(), val);
337 X getValue_impl(std::integral_constant<int, convertibleType> )
339 std::conditional_t<std::is_integral<X>::value,
340 std::conditional_t<std::is_same<X, char>::value, char, int64_t>,
343 getValue_impl(std::integral_constant<int, primaryType>(), gval);
344 return static_cast<X
>(gval);
348 X getValue_impl(std::integral_constant<int, nonConvertibleType> )
355 int getValue(
double* data,
int maxsize);
357 int getComplexValue(
double* data,
int maxsize);
359 int getValue(
char* str,
int maxsize);
377 const X& getValueRef();
379 double getDouble() {
return getValue_impl<double>(std::integral_constant<int, primaryType>()); }
381 const std::string&
getString() {
return getValueRef<std::string>(); }
386 size_t getByteCount();
388 size_t getStringSize();
390 size_t getVectorSize();
398 MultiInputHandlingMethod getMultiInputMode()
const {
return inputVectorOp; }
400 bool vectorDataProcess(
const std::vector<std::shared_ptr<const SmallBuffer>>& dataV);
402 const std::string& getTarget()
const
404 return (!givenTarget.empty()) ? givenTarget : getSourceTargets();
409 return (mName.empty()) ? getTarget() : getName();
414 void loadSourceInformation();
418 bool allowDirectFederateUpdate()
const
420 return hasUpdate && !changeDetectionEnabled &&
421 inputVectorOp == MultiInputHandlingMethod::NO_OP;
423 data_view checkAndGetFedUpdate();
424 void forceCoreDataUpdate();
425 friend class ValueFederateManager;
429 HELICS_CXX_EXPORT
double
431 const std::shared_ptr<units::precise_unit>& inputUnits,
432 const std::shared_ptr<units::precise_unit>& outputUnits);
434 HELICS_CXX_EXPORT
void
435 integerExtractAndConvert(
defV& store,
437 const std::shared_ptr<units::precise_unit>& inputUnits,
438 const std::shared_ptr<units::precise_unit>& outputUnits);
441 void Input::getValue_impl(std::integral_constant<int, primaryType> , X& out)
443 auto dv = checkAndGetFedUpdate();
445 if (injectionType == DataType::HELICS_UNKNOWN) {
446 loadSourceInformation();
449 if (injectionType == helics::DataType::HELICS_DOUBLE) {
452 }
else if (injectionType == helics::DataType::HELICS_INT) {
454 integerExtractAndConvert(val, dv, inputUnits, outputUnits);
459 if (changeDetectionEnabled) {
475 inline const X& getValueRefImpl(
defV& val)
477 valueConvert(val, helicsType<X>());
478 return std::get<X>(val);
482 inline const std::string& getValueRefImpl(
defV& val)
485 if ((val.index() == named_point_loc)) {
486 return std::get<NamedPoint>(val).name;
488 valueConvert(val, DataType::HELICS_STRING);
489 return std::get<std::string>(val);
492 HELICS_CXX_EXPORT
bool checkForNeededCoreRetrieval(std::size_t currentIndex,
497 const X& Input::getValueRef()
499 static_assert(std::is_same<typeCategory<X>, std::integral_constant<int, primaryType>>::value,
500 "calling getValue By ref must be with a primary type");
501 auto dv = checkAndGetFedUpdate();
503 if (injectionType == DataType::HELICS_UNKNOWN) {
504 loadSourceInformation();
507 if (changeDetectionEnabled) {
509 if (injectionType == helics::DataType::HELICS_DOUBLE) {
512 }
else if (injectionType == helics::DataType::HELICS_INT) {
514 integerExtractAndConvert(val, dv, inputUnits, outputUnits);
526 if (checkForNeededCoreRetrieval(lastValue.index(),
529 forceCoreDataUpdate();
533 return getValueRefImpl<remove_cv_ref<X>>(lastValue);