#pragma once #include "common.hpp" #include "math.hpp" #include namespace rack { namespace app { struct ParamQuantity; } // namespace app namespace engine { struct ParamQuantityFactory { virtual ~ParamQuantityFactory() {} virtual app::ParamQuantity *create() = 0; }; struct Param { /** Unstable API. Use setValue() and getValue() instead. */ float value = 0.f; /** The minimum allowed value. */ float minValue = 0.f; /** The maximum allowed value. Must be greater than minValue. */ float maxValue = 1.f; /** The initial value. */ float defaultValue = 0.f; /** The name of the parameter, using sentence capitalization. e.g. "Frequency", "Pulse width", "Alternative mode" */ std::string label; /** The numerical unit of measurement appended to the value. Use a space before non-abbreviations to separate the numerical value. e.g. " semitones", "Hz", "%", "V" */ std::string unit; /** Set to 0 for linear, nonzero for exponential. */ float displayBase = 0.f; float displayMultiplier = 1.f; float displayOffset = 0.f; /** An optional one-sentence description of the parameter. */ std::string description; ParamQuantityFactory *paramQuantityFactory = NULL; /** Determines whether this Param will be randomized when the user requests to randomize the Module. */ bool randomizable = true; ~Param() { if (paramQuantityFactory) delete paramQuantityFactory; } template void config(float minValue, float maxValue, float defaultValue, std::string label = "", std::string unit = "", float displayBase = 0.f, float displayMultiplier = 1.f, float displayOffset = 0.f) { this->value = defaultValue; this->minValue = minValue; this->maxValue = maxValue; this->defaultValue = defaultValue; if (!label.empty()) this->label = label; this->unit = unit; this->displayBase = displayBase; this->displayMultiplier = displayMultiplier; this->displayOffset = displayOffset; struct TParamQuantityFactory : ParamQuantityFactory { app::ParamQuantity *create() override {return new TParamQuantity;} }; if (paramQuantityFactory) delete paramQuantityFactory; paramQuantityFactory = new TParamQuantityFactory; } float getValue() { return value; } void setValue(float value) { this->value = math::clamp(value, minValue, maxValue); } /** Returns whether the Param has finite range between minValue and maxValue. */ bool isBounded(); json_t *toJson(); void fromJson(json_t *rootJ); void reset(); void randomize(); }; } // namespace engine } // namespace rack