Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
design_param_binding.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <pulp/view/design_frame_view.hpp> // DesignFrameElement, ScalarSourceBinding
4
5#include <functional>
6#include <memory>
7#include <string>
8#include <unordered_map>
9#include <vector>
10
11namespace pulp::view {
12
13class View;
14
15// Collaborator that owns the DesignFrameView sub-clusters concerned with
16// host-parameter binding: per-element scalar sources, the bind grid, and the
17// scale-mismatch diagnostic. Split out of DesignFrameView to keep that class
18// focused on the frame/overlay/hit lifecycle; DesignFrameView holds one of these
19// and forwards the relevant public methods to it. Behavior is unchanged — this
20// is a pure extraction.
21//
22// Communication seam is narrow: the bind-grid and scale-mismatch methods take
23// the view's `elements` and `HostParamSurface*` as explicit arguments per call,
24// so the collaborator stores no back-pointer for them. The scalar-source cluster
25// is the one exception: a ScalarSourceBinding must enrol with a View, so the
26// collaborator holds `owner_` solely to construct ScalarSourceBinding(owner_).
28public:
29 explicit DesignParamBinding(View& owner);
30
31 // ── C: live per-element scalar sources ───────────────────────────────────
32 // Bind (or, with a null source, unbind) the ScalarSource for `param_key`, then
33 // re-point the active frame's slot table against `elements`. See
34 // DesignFrameView::set_element_scalar_source for the public contract.
35 void set_scalar_source(const std::string& param_key,
36 std::shared_ptr<ScalarSource> source,
37 const std::vector<DesignFrameElement>& elements);
38
39 // Latest value published for element `i`, or 0 when out of range / unbound.
40 float element_scalar(int i) const;
41
42 // Whether element `i` of the active frame has a scalar source bound.
44
45 // Re-point the active frame's slot table at the bindings whose param_key
46 // `elements` declares, and park the rest. Called after every elements_ swap.
47 void rebuild_slots(const std::vector<DesignFrameElement>& elements);
48
49 // ── B: bind grid ─────────────────────────────────────────────────────────
50 // Replace the grid's key set, dropping the previous grid's stand-ins off the
51 // tail of `elements`, then re-apply against `elements`. See
52 // DesignFrameView::build_bind_grid for the public contract.
53 void build_grid(std::vector<std::string> keys,
54 std::vector<DesignFrameElement>& elements);
55
56 // Append the bind grid's stand-in elements to `elements` for keys the active
57 // frame carries no control for. Called after every frame activation.
58 void apply_grid(std::vector<DesignFrameElement>& elements);
59
60 // Whether element `i` is a bind-grid stand-in rather than a design control.
61 // `element_count` is the active frame's live element count (upper bound).
62 bool is_stand_in(int i, int element_count) const;
63
64 // The keys the bind grid was last built with.
65 const std::vector<std::string>& grid_keys() const { return bind_grid_keys_; }
66
67 // ── A: param-scale mismatch diagnostic ───────────────────────────────────
68 // Record a distinct param-scale mismatch and fire the diagnostic callback.
69 // De-duplicates by param_key. Callable from DesignFrameView's const normalize
70 // path (resolve_value_count) because it is reached through the collaborator
71 // pointer, whose const-ness the const view does not propagate — the
72 // accumulator is a diagnostic log, not observable view state.
73 void report_mismatch(const std::string& key, int ui_count, int host_count,
74 bool host_has_param);
75
76 // The host's value cardinality for `key`, or 0 when `hp` does not resolve it.
77 int host_step_count_for(const std::string& key, HostParamSurface* hp) const;
78
79 // Whether the live surface `hp` carries `key` — ParamScaleMismatch::host_has_param.
80 bool host_has_param_for(const std::string& key, HostParamSurface* hp) const;
81
82 // Install the diagnostic callback and replay the mismatches already seen. See
83 // DesignFrameView::set_on_param_scale_mismatch for the public contract.
84 void set_on_mismatch(std::function<void(const ParamScaleMismatch&)> cb);
85
86 // The distinct param-scale mismatches seen so far (first-seen order, deduped).
87 const std::vector<ParamScaleMismatch>& mismatches() const {
88 return param_scale_mismatches_;
89 }
90
91private:
92 View& owner_;
93
94 // Element scalar bindings, owned by stable param_key so they survive a frame
95 // swap, plus the active frame's index-aligned view of them (non-owning; null
96 // where the element has no binding) so element_scalar() stays paint-safe.
97 std::unordered_map<std::string, std::unique_ptr<ScalarSourceBinding>> element_scalars_;
98 std::vector<ScalarSourceBinding*> active_element_scalars_;
99
100 // Bind grid: the caller-supplied host-parameter keys, and the index of the
101 // first stand-in in the active frame's elements (all stand-ins are appended
102 // after the frame's own elements, so one index bounds them). -1 = no grid.
103 std::vector<std::string> bind_grid_keys_;
104 int bind_grid_begin_ = -1;
105
106 // Param-scale mismatch diagnostic accumulator + callback. Written by
107 // report_mismatch, which the const normalize path reaches through this
108 // collaborator; the accumulator records what was observed and never feeds
109 // back into what the view emits or renders.
110 std::function<void(const ParamScaleMismatch&)> on_param_scale_mismatch_;
111 std::vector<ParamScaleMismatch> param_scale_mismatches_;
112};
113
114} // namespace pulp::view
A framework-agnostic, native-view-facing runtime parameter accessor.
Definition host_surfaces.hpp:40
bool host_has_param_for(const std::string &key, HostParamSurface *hp) const
void report_mismatch(const std::string &key, int ui_count, int host_count, bool host_has_param)
bool element_has_scalar_source(int i) const
const std::vector< std::string > & grid_keys() const
Definition design_param_binding.hpp:65
void rebuild_slots(const std::vector< DesignFrameElement > &elements)
int host_step_count_for(const std::string &key, HostParamSurface *hp) const
void set_scalar_source(const std::string &param_key, std::shared_ptr< ScalarSource > source, const std::vector< DesignFrameElement > &elements)
const std::vector< ParamScaleMismatch > & mismatches() const
Definition design_param_binding.hpp:87
void apply_grid(std::vector< DesignFrameElement > &elements)
bool is_stand_in(int i, int element_count) const
void build_grid(std::vector< std::string > keys, std::vector< DesignFrameElement > &elements)
void set_on_mismatch(std::function< void(const ParamScaleMismatch &)> cb)
float element_scalar(int i) const
Definition view.hpp:73
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
@ i
Definition input_events.hpp:40
Definition design_frame_view.hpp:312