/* * Generic module to multiply one value with another */ #ifndef CHIMERATK_APPLICATION_CORE_MULTIPLIER_H #define CHIMERATK_APPLICATION_CORE_MULTIPLIER_H #include <limits> #include <cmath> #include "ApplicationCore.h" namespace ChimeraTK { template<typename InputType, typename OutputType=InputType, size_t NELEMS=1> struct ConstMultiplier : public ApplicationModule { ConstMultiplier(EntityOwner *owner, const std::string &name, const std::string &description, double factor) : ApplicationModule(owner, name, description), _factor(factor) { setEliminateHierarchy(); } ArrayPushInput<InputType> input{this, "input", "", NELEMS, "Input value to be scaled"}; ArrayOutput<OutputType> output{this, "output", "", NELEMS, "Output value after scaling"}; double _factor; void mainLoop() { while(true) { // scale value (with rounding, if integral type) if(!std::numeric_limits<OutputType>::is_integer) { for(size_t i=0; i<NELEMS; ++i) output[i] = input[i] * _factor; } else { for(size_t i=0; i<NELEMS; ++i) output[i] = std::round(input[i] * _factor); } // write scaled value output.write(); // wait for new input value (at the end, since we want to process the initial values first) input.read(); } } }; template<typename InputType, typename OutputType=InputType, size_t NELEMS=1> struct Multiplier : public ApplicationModule { using ApplicationModule::ApplicationModule; Multiplier(EntityOwner *owner, const std::string &name, const std::string &description) : ApplicationModule(owner, name, description) { setEliminateHierarchy(); } ArrayPushInput<InputType> input{this, "input", "", NELEMS, "Input value to be scaled"}; ScalarPushInput<double> factor{this, "factor", "", "Factor to scale the input value with"}; ArrayOutput<OutputType> output{this, "output", "", NELEMS, "Output value after scaling"}; void mainLoop() { while(true) { // scale value (with rounding, if integral type) if(!std::numeric_limits<OutputType>::is_integer) { for(size_t i=0; i<NELEMS; ++i) output[i] = input[i] * factor; } else { for(size_t i=0; i<NELEMS; ++i) output[i] = std::round(input[i] * factor); } // write scaled value output.write(); // wait for new input value (at the end, since we want to process the initial values first) Application::readAny({input, factor}); } } }; template<typename InputType, typename OutputType=InputType, size_t NELEMS=1> struct Divider : public ApplicationModule { using ApplicationModule::ApplicationModule; Divider(EntityOwner *owner, const std::string &name, const std::string &description) : ApplicationModule(owner, name, description) { setEliminateHierarchy(); } ArrayPushInput<InputType> input{this, "input", "", NELEMS, "Input value to be scaled"}; ScalarPushInput<double> divider{this, "divider", "", "Divider to scale the input value with"}; ArrayOutput<OutputType> output{this, "output", "", NELEMS, "Output value after scaling"}; void mainLoop() { while(true) { // scale value (with rounding, if integral type) if(!std::numeric_limits<OutputType>::is_integer) { for(size_t i=0; i<NELEMS; ++i) output[i] = input[i] / divider; } else { for(size_t i=0; i<NELEMS; ++i) output[i] = std::round(input[i] / divider); } // write scaled value output.write(); // wait for new input value (at the end, since we want to process the initial values first) Application::readAny({input, divider}); } } }; } // namespace ChimeraTK #endif /* CHIMERATK_APPLICATION_CORE_MULTIPLIER_H */