Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
binding.hpp
Go to the documentation of this file.
1#pragma once
2
5
8#include <functional>
9#include <vector>
10#include <cmath>
11
12namespace pulp::state {
13
43class Binding {
44public:
45 Binding() = default;
46
50 Binding(StateStore& store, ParamID param_id)
51 : store_(&store), param_id_(param_id) {}
52
54 float get() const {
55 return store_ ? store_->get_value(param_id_) : 0.0f;
56 }
57
59 void set(float value) {
60 if (!store_) return;
61 float old_value = store_->get_value(param_id_);
62 store_->set_value(param_id_, value);
63 float new_value = store_->get_value(param_id_); // clamped
64 if (std::abs(new_value - old_value) > 1e-7f) {
65 notify(new_value);
66 }
67 }
68
70 float get_normalized() const {
71 return store_ ? store_->get_normalized(param_id_) : 0.0f;
72 }
73
75 void set_normalized(float normalized) {
76 if (!store_) return;
77 float old_value = store_->get_value(param_id_);
78 store_->set_normalized(param_id_, normalized);
79 float new_value = store_->get_value(param_id_);
80 if (std::abs(new_value - old_value) > 1e-7f) {
81 notify(new_value);
82 }
83 }
84
89 if (store_) {
90 gesture_start_value_ = store_->get_value(param_id_);
91 store_->begin_gesture(param_id_);
92 }
93 }
94
97 void end_gesture() {
98 if (store_) {
99 store_->end_gesture(param_id_);
100 // Push to edit history if available
101 float end_value = store_->get_value(param_id_);
102 if (edit_history_ && std::abs(end_value - gesture_start_value_) > 1e-7f) {
103 auto pid = param_id_;
104 auto* s = store_;
105 float sv = gesture_start_value_;
106 float ev = end_value;
107 edit_history_->perform(
108 [s, pid, ev]() { s->set_value(pid, ev); },
109 [s, pid, sv]() { s->set_value(pid, sv); },
110 info() ? info()->name : "param change");
111 }
112 }
113 }
114
126 void set_from_background(float value) {
127 if (!store_) return;
128 store_->run_gesture_on_main([s = store_, pid = param_id_, value] {
129 s->begin_gesture(pid);
130 s->set_value(pid, value);
131 s->end_gesture(pid);
132 });
133 }
134
136 void set_edit_history(state::EditHistory* h) { edit_history_ = h; }
137 state::EditHistory* edit_history() const { return edit_history_; }
138
141 const ParamInfo* info() const {
142 return store_ ? store_->info(param_id_) : nullptr;
143 }
144
146 ParamID id() const { return param_id_; }
147
149 using ChangeCallback = std::function<void(float new_value)>;
150
152 void on_change(ChangeCallback callback) {
153 callbacks_.push_back(std::move(callback));
154 }
155
169 bool poll() {
170 if (!store_) return false;
171 float current = store_->get_value(param_id_);
172 if (std::abs(current - last_polled_) > 1e-7f) {
173 last_polled_ = current;
174 notify(current);
175 return true;
176 }
177 return false;
178 }
179
181 void reset() {
182 if (store_ && info()) {
183 store_->reset_to_default(param_id_);
184 notify(store_->get_value(param_id_));
185 }
186 }
187
189 bool is_bound() const { return store_ != nullptr; }
190
191private:
192 void notify(float value) {
193 for (auto& cb : callbacks_) {
194 if (cb) cb(value);
195 }
196 }
197
198 StateStore* store_ = nullptr;
199 ParamID param_id_ = 0;
200 float last_polled_ = 0.0f;
201 float gesture_start_value_ = 0.0f;
202 state::EditHistory* edit_history_ = nullptr;
203 std::vector<ChangeCallback> callbacks_;
204};
205
208inline std::vector<Binding> create_bindings(StateStore& store) {
209 std::vector<Binding> bindings;
210 for (const auto& param : store.all_params()) {
211 bindings.emplace_back(store, param.id);
212 }
213 return bindings;
214}
215
216} // namespace pulp::state
bool is_bound() const
True if this Binding is associated with a StateStore.
Definition binding.hpp:189
float get_normalized() const
Read the parameter's value mapped to [0, 1].
Definition binding.hpp:70
void set_from_background(float value)
Perform a complete parameter gesture (begin → set → end) from ANY thread — the thread-safe entry poin...
Definition binding.hpp:126
const ParamInfo * info() const
Get the immutable metadata for the bound parameter.
Definition binding.hpp:141
void reset()
Reset the parameter to its default value and fire change callbacks.
Definition binding.hpp:181
std::function< void(float new_value)> ChangeCallback
Callback type for change notifications.
Definition binding.hpp:149
Binding(StateStore &store, ParamID param_id)
Bind to a specific parameter in a store.
Definition binding.hpp:50
void set_edit_history(state::EditHistory *h)
Attach an EditHistory for undo support. Optional — null by default.
Definition binding.hpp:136
void end_gesture()
Notify the host that the current gesture has ended.
Definition binding.hpp:97
void set_normalized(float normalized)
Write from a normalized [0, 1] value. Fires change callbacks if changed.
Definition binding.hpp:75
bool poll()
Check whether the parameter was changed externally (e.g., host automation).
Definition binding.hpp:169
void on_change(ChangeCallback callback)
Register a callback that fires when the value changes via set() or poll().
Definition binding.hpp:152
ParamID id() const
The ID of the bound parameter.
Definition binding.hpp:146
void begin_gesture()
Notify the host that a user gesture (e.g., mouse drag) has begun.
Definition binding.hpp:88
state::EditHistory * edit_history() const
Definition binding.hpp:137
float get() const
Read the parameter's current value.
Definition binding.hpp:54
void set(float value)
Write a new value. Fires change callbacks if the value actually changed.
Definition binding.hpp:59
Global undo/redo history for the application.
Definition edit_history.hpp:39
Centralized parameter storage with lock-free value access.
Definition store.hpp:164
std::span< const ParamInfo > all_params() const
View of all registered parameters (in registration order).
Definition store.hpp:439
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
std::vector< Binding > create_bindings(StateStore &store)
Create a Binding for every parameter registered in a store.
Definition binding.hpp:208
uint32_t ParamID
Unique parameter identifier, stable across plugin versions.
Definition parameter.hpp:55
Immutable parameter metadata, registered once at plugin initialization.
Definition parameter.hpp:316
std::string name
Definition parameter.hpp:318