97 lines
2.9 KiB
C++
97 lines
2.9 KiB
C++
#pragma once
|
|
|
|
#include <cmath>
|
|
#include <limits>
|
|
#include <QCborMap>
|
|
|
|
#include "data/node.h"
|
|
#include "data/porttypes.h"
|
|
|
|
//namespace Xybrid::Data { class ParameterPort; }
|
|
namespace Xybrid::NodeLib {
|
|
/// Plugin parameter with associated metadata and automation faculties
|
|
class Param {
|
|
//
|
|
Param() = default;
|
|
public:
|
|
class Reader {
|
|
friend class Param;
|
|
Param* p;
|
|
size_t pos = 0;
|
|
bool r;
|
|
Reader(Param* p, bool r) : p(p), r(r) { }
|
|
public:
|
|
double next() {
|
|
if (r) {
|
|
auto v = p->port->data[pos++];
|
|
if (!std::isnan(v)) {
|
|
if (p->min == -p->max) // "signed" logic if symmetrical around zero
|
|
v = std::clamp(v, -1.0, 1.0) * p->max;
|
|
else // extents 0.0 .. 1.0 scaled across parameter range
|
|
v = std::clamp(p->min + v * (p->max - p->min), p->min, p->max);
|
|
|
|
p->vt = v;
|
|
}
|
|
}
|
|
if (!std::isnan(p->vt)) return p->vt;
|
|
return p->value;
|
|
}
|
|
};
|
|
|
|
enum Flags : uint8_t {
|
|
ResetOnTick = 0b00000001,
|
|
};
|
|
|
|
QString name;
|
|
double min, max, def;
|
|
|
|
double value;
|
|
double vt = std::numeric_limits<double>::quiet_NaN();
|
|
|
|
Flags flags;
|
|
|
|
Data::ParameterPort* port = nullptr;
|
|
|
|
Param(const QString& name, double min, double max, double def, Flags flags = {}) : Param() {
|
|
this->name = name;
|
|
this->min = min;
|
|
this->max = max;
|
|
this->def = def;
|
|
this->value = def;
|
|
this->flags = flags;
|
|
}
|
|
|
|
Data::ParameterPort* makePort(Data::Node*, const QString& name = { });
|
|
|
|
Reader start() {
|
|
bool r = port && port->isConnected();
|
|
if (r) port->pull();
|
|
if (flags & ResetOnTick) vt = std::numeric_limits<double>::quiet_NaN();
|
|
return Reader(this, r);
|
|
}
|
|
|
|
inline QString saveName() {
|
|
return name.toLower().remove(' ');
|
|
}
|
|
|
|
inline void save(QCborMap& m, QString id = { }) {
|
|
if (id.isEmpty()) id = saveName();
|
|
m[id] = value;
|
|
}
|
|
|
|
inline void load(QCborMap& m, QString id = { }) {
|
|
if (id.isEmpty()) id = saveName();
|
|
value = m.value(id).toDouble(value);
|
|
vt = std::numeric_limits<double>::quiet_NaN();
|
|
}
|
|
|
|
// - give it a Reader abstraction (grab from a "startTick" thing, call its next() function for tracking and values)
|
|
// - functions to automatically save/load from QCborMap
|
|
// binding a knobgadget automatically populates range+defaults(+label)
|
|
// - figure out how to do range stuff
|
|
// - "signed" extents only if min == -max
|
|
|
|
// meta info for parameter ports?
|
|
};
|
|
}
|