10 #include "ValueFederate.hpp"
24 enum multi_input_handling_method : uint16_t {
42 int referenceIndex{-1};
43 void* dataReference{
nullptr};
45 data_type targetType{data_type::helics_unknown};
47 data_type::helics_unknown};
48 bool changeDetectionEnabled{
false};
49 bool hasUpdate{
false};
50 bool disableAssign{
false};
51 bool useThreshold{
false};
52 bool multiUnits{
false};
53 multi_input_handling_method inputVectorOp{
54 multi_input_handling_method::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<data_type, std::shared_ptr<units::precise_unit>>>
63 double threshold{0.0};
64 std::string actualName;
66 mpark::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& name,
112 const std::string& defaultType =
"def",
113 const std::string& units = std::string{}):
114 Input(locality, std::addressof(*valueFed), name, 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& name,
124 const std::string& units = std::string{}):
129 template<
class FedPtr>
130 Input(FedPtr& valueFed,
131 const std::string& name,
133 const std::string& units = std::string()):
139 ValueFederate* valueFed,
140 const std::string& name,
141 const std::string& units = std::string{}):
142 Input(locality, valueFed, name,
"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& name,
159 const std::string& units = std::string{}):
164 template<
class FedPtr>
167 const std::string& name,
169 const std::string& units = std::string{}):
184 bool isValid()
const {
return handle.isValid(); }
185 bool operator<(
const Input& inp)
const {
return (handle < inp.
handle); }
186 bool operator>(
const Input& inp)
const {
return (handle > inp.handle); }
195 fed->setInputNotificationCallback(
196 *
this, [
this, callback = std::move(callback)](
const Input& ,
Time time) {
204 const std::string&
getName()
const {
return actualName; }
207 const std::string&
getKey()
const {
return fed->getInterfaceName(handle); }
212 return (actualName.empty() ? getTarget() : actualName);
218 return ((injectionType == data_type::helics_unknown) ||
219 (injectionType == data_type::helics_custom)) ?
220 fed->getInjectionType(*
this) :
224 const std::string&
getType()
const {
return fed->getExtractionType(*
this); }
226 const std::string&
getUnits()
const {
return fed->getExtractionUnits(*
this); }
232 void addTarget(
const std::string& newTarget) {
fed->addTarget(*
this, newTarget); }
236 fed->removeTarget(*
this, targetToRemove);
239 const std::string&
getInfo()
const {
return fed->getInfo(handle); }
241 void setInfo(
const std::string& info) {
fed->setInfo(handle, info); }
243 void setOption(int32_t option, int32_t value = 1);
246 int32_t getOption(int32_t option)
const;
252 bool checkUpdate(
bool assumeUpdate =
false);
266 bool isUpdated()
const;
277 helicsType<X>() != data_type::helics_custom,
278 "callback type must be a primary helics type one of \"double, int64_t, named_point, bool, Time "
279 "std::vector<double>, std::vector<std::complex<double>>, std::complex<double>\"");
280 value_callback = std::move(callback);
281 fed->setInputNotificationCallback(*
this, [
this](
Input& ,
Time time) {
282 handleCallback(time);
288 void setDefault_impl(std::integral_constant<int, 0> , X&& val)
295 void setDefault_impl(std::integral_constant<int, 1> , X&& val)
301 void setDefault_impl(std::integral_constant<int, 2> , X&& val)
303 fed->setDefaultValue(*
this,
304 ValueConverter<remove_cv_ref<X>>::convert(std::forward<X>(val)));
323 changeDetectionEnabled =
true;
328 changeDetectionEnabled =
false;
338 void handleCallback(
Time time);
340 void getValue_impl(std::integral_constant<int, primaryType> , X& out);
343 void getValue_impl(std::integral_constant<int, primaryType> ,
char& out)
345 out = getValueChar();
349 void getValue_impl(std::integral_constant<int, convertibleType> ,
char& out)
351 out = getValueChar();
355 void getValue_impl(std::integral_constant<int, convertibleType> , X& out)
357 std::conditional_t<std::is_integral<X>::value,
358 std::conditional_t<std::is_same<X, char>::value, char, int64_t>,
361 getValue_impl(std::integral_constant<int, primaryType>(), gval);
362 out =
static_cast<X
>(gval);
366 void getValue_impl(std::integral_constant<int, nonConvertibleType> , X& out)
372 X getValue_impl(std::integral_constant<int, primaryType> )
375 getValue_impl(std::integral_constant<int, primaryType>(), val);
380 X getValue_impl(std::integral_constant<int, convertibleType> )
382 std::conditional_t<std::is_integral<X>::value,
383 std::conditional_t<std::is_same<X, char>::value, char, int64_t>,
386 getValue_impl(std::integral_constant<int, primaryType>(), gval);
387 return static_cast<X
>(gval);
391 X getValue_impl(std::integral_constant<int, nonConvertibleType> )
400 int getValue(
char* str,
int maxsize);
418 const X& getValueRef();
425 size_t getStringSize();
427 size_t getVectorSize();
438 multi_input_handling_method getMultiInputMode()
const {
return inputVectorOp; }
440 bool vectorDataProcess(
const std::vector<std::shared_ptr<const data_block>>& dataV);
444 void loadSourceInformation();
448 bool allowDirectFederateUpdate()
const
450 return hasUpdate && !changeDetectionEnabled &&
451 inputVectorOp == multi_input_handling_method::no_op;
453 friend class ValueFederateManager;
457 HELICS_CXX_EXPORT
double
459 const std::shared_ptr<units::precise_unit>& inputUnits,
460 const std::shared_ptr<units::precise_unit>& outputUnits);
462 HELICS_CXX_EXPORT
void
463 integerExtractAndConvert(
defV& store,
465 const std::shared_ptr<units::precise_unit>& inputUnits,
466 const std::shared_ptr<units::precise_unit>& outputUnits);
469 HELICS_CXX_EXPORT
double
471 const std::shared_ptr<units::precise_unit>& inputUnits,
472 const std::shared_ptr<units::precise_unit>& outputUnits);
474 HELICS_CXX_EXPORT
void
475 integerExtractAndConvert3(
defV& store,
477 const std::shared_ptr<units::precise_unit>& inputUnits,
478 const std::shared_ptr<units::precise_unit>& outputUnits);
485 std::function<void(X,
Time)> value_callback;
486 std::function<double(
const X& v1,
const X& v2)>
487 changeDetectionOperator;
489 using is_convertible_to_primary_type =
490 std::conditional_t<((helicsType<X>() != data_type::helics_custom) ||
491 (isConvertableType<X>())),
503 const std::string& name,
504 const std::string& units = std::string()):
513 template<
class FedPtr>
514 InputT(FedPtr& valueFed,
const std::string& name,
const std::string& units = std::string()):
534 value_callback = callback;
536 handleCallback(time);
545 void handleCallback(
Time time)
549 value_callback(out, time);
554 void Input::getValue_impl(std::integral_constant<int, primaryType> , X& out)
556 if (
fed->
isUpdated(*
this) || allowDirectFederateUpdate()) {
558 if (injectionType == data_type::helics_unknown) {
559 loadSourceInformation();
561 if (injectionType == helics::data_type::helics_json ||
562 targetType != data_type::helics_json) {
563 if (injectionType == helics::data_type::helics_double) {
566 }
else if (injectionType == helics::data_type::helics_int) {
568 integerExtractAndConvert(val, dv, inputUnits, outputUnits);
574 if (injectionType == helics::data_type::helics_double) {
577 }
else if (injectionType == helics::data_type::helics_int) {
579 integerExtractAndConvert3(val, dv, inputUnits, outputUnits);
583 valueExtract3(dv, injectionType, val);
587 if (changeDetectionEnabled) {
603 inline const X& getValueRefImpl(
defV& val)
605 valueConvert(val, helicsType<X>());
606 return mpark::get<X>(val);
610 inline const std::string& getValueRefImpl(
defV& val)
613 if ((val.index() == named_point_loc)) {
614 return mpark::get<NamedPoint>(val).name;
616 valueConvert(val, data_type::helics_string);
617 return mpark::get<std::string>(val);
621 const X& Input::getValueRef()
623 static_assert(std::is_same<typeCategory<X>, std::integral_constant<int, primaryType>>::value,
624 "calling getValue By ref must be with a primary type");
625 if (
fed->
isUpdated(*
this) || allowDirectFederateUpdate()) {
627 if (injectionType == data_type::helics_unknown) {
628 loadSourceInformation();
630 if (injectionType == helics::data_type::helics_json ||
631 targetType != data_type::helics_json) {
632 if (changeDetectionEnabled) {
634 if (injectionType == helics::data_type::helics_double) {
637 }
else if (injectionType == helics::data_type::helics_int) {
639 integerExtractAndConvert(val, dv, inputUnits, outputUnits);
651 if (changeDetectionEnabled) {
653 if (injectionType == helics::data_type::helics_double) {
656 }
else if (injectionType == helics::data_type::helics_int) {
658 integerExtractAndConvert3(val, dv, inputUnits, outputUnits);
662 valueExtract3(dv, injectionType, val);
669 valueExtract3(dv, injectionType, lastValue);
677 return getValueRefImpl<remove_cv_ref<X>>(lastValue);