MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Mapped.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace MayaFlux::Buffers {
6class VKBuffer;
7}
8
10
11/**
12 * @brief Version counter incremented on every value write.
13 *
14 * Plain uint64_t behind a shared_ptr. The graphics tick compares against
15 * its last-seen version to detect changes without polling the value itself.
16 * Not atomic — same scheduler tick, no concurrent access.
17 */
18using Version = uint64_t;
19
20/**
21 * @struct MappedState
22 * @brief Value carrier for a Mapped primitive.
23 *
24 * Owns the current value and a version counter. Any writer increments
25 * version after updating value. The graphics tick reads both and decides
26 * whether to regenerate geometry.
27 *
28 * Exposed as shared_ptr<MappedState<T>> so any external system — a node
29 * output reader, a buffer writer, a scheduler callback — can hold a
30 * reference and read or write without knowing about the primitive.
31 *
32 * @tparam T Value type. float for a single continuous parameter,
33 * glm::vec2 for a 2D position, any plain data type.
34 */
35template <typename T>
37 T value {};
39 uint32_t id { 0 };
40
41 void write(T v)
42 {
43 value = v;
44 ++version;
45 }
46};
47
48/**
49 * @brief Geometry function signature.
50 *
51 * Called by the graphics tick when the version has advanced. Receives the
52 * current value and an output byte vector to fill with interleaved vertex
53 * data. Layout, stride, and topology are determined by how the caller
54 * constructed the VKBuffer and RenderProcessor — the function is agnostic
55 * to all of those.
56 *
57 * The function is also responsible for updating the Element's spatial
58 * description if the geometry change affects hit testing (e.g. a handle
59 * that moves). It receives the Element by reference for that purpose.
60 *
61 * @tparam T Value type matching the MappedState.
62 */
63template <typename T>
64using GeometryFn = std::function<void(T value, std::vector<uint8_t>& out_bytes, Element& element)>;
65
66/**
67 * @struct Mapped
68 * @brief Infrastructure for a continuously-mapped value whose GPU geometry
69 * tracks it.
70 *
71 * The geometry function IS the primitive. Mapped provides only the
72 * mechanism: a shared value carrier, a version counter, and a sync()
73 * call that invokes the geometry function when the value changes.
74 *
75 * The geometry function decides everything about shape, topology, and
76 * vertex layout. It can write from any source — mouse pixel coordinates,
77 * microphone energy, another node's output, a tendency field, a computed
78 * function of time — by whatever means the caller chooses. The common
79 * geometry helpers in Geometry.hpp are illustrative, not idiomatic.
80 *
81 * Orchestration (node binding, buffer mapping, scheduler-driven update,
82 * input capture) attaches externally by writing to state and calling
83 * state->write(v). Mapped has no knowledge of or dependency on any
84 * orchestration layer.
85 *
86 * @tparam T Value type.
87 */
88template <typename T>
89struct Mapped {
90 /// @brief Shared value carrier. External systems hold a copy of this ptr.
91 std::shared_ptr<MappedState<T>> state;
92
93 /// @brief Geometry regeneration function. Set once at construction.
95
96 /// @brief The Element registered with the Layer.
97 /// element.id is valid after Layer::add(element) has been called.
99
100 /// @brief Last version seen by sync(). Initialised to a sentinel that
101 /// guarantees one geometry generation on the first sync() call.
102 Version last_version { static_cast<Version>(-1) };
103
104 /// @brief When true, sync() regenerates geometry every call regardless of
105 /// whether state->version has advanced. Set by subsystems where the
106 /// value pointer is stable but the data it references changes each frame.
107 bool force_redraw_on_sync { false };
108
109 /**
110 * @brief Call once per graphics tick.
111 *
112 * If state->version has advanced since last_version, invokes geometry_fn
113 * with the current value into a local byte buffer, then passes the result
114 * to VKBuffer::set_data so the existing upload path handles GPU transfer.
115 *
116 * The caller is responsible for driving the graphics tick — Mapped does
117 * not register itself with any scheduler.
118 */
119 void sync()
120 {
121 if (!state || !geometry_fn || !element.buffer)
122 return;
123 if (state->version == last_version && !force_redraw_on_sync)
124 return;
125
127 element.buffer->submit(m_bytes);
128 last_version = state->version;
129 }
130
131private:
132 std::vector<uint8_t> m_bytes;
133};
134
135/**
136 * @brief Construct a Mapped<T> with a freshly allocated MappedState.
137 * @param initial Starting value.
138 * @param geometry Geometry function producing vertex bytes from a value.
139 * @param buffer VKBuffer whose raw bytes the geometry function writes into.
140 * @return Ready-to-use Mapped. Register element with a Layer before first sync().
141 */
142template <typename T>
143[[nodiscard]] Mapped<T> make_mapped(
144 T initial,
145 GeometryFn<T> geometry,
146 std::shared_ptr<Buffers::FormaBuffer> buffer)
147{
148 auto st = std::make_shared<MappedState<T>>();
149 st->write(initial);
150
151 Element el;
152 el.buffer = std::move(buffer);
153
154 Mapped<T> m;
155 m.state = std::move(st);
156 m.geometry_fn = std::move(geometry);
157 m.element = std::move(el);
158 m.last_version = static_cast<Version>(-1);
159 return m;
160}
161
162} // namespace MayaFlux::Portal::Forma
uint64_t Version
Version counter incremented on every value write.
Definition Mapped.hpp:18
std::function< void(T value, std::vector< uint8_t > &out_bytes, Element &element)> GeometryFn
Geometry function signature.
Definition Mapped.hpp:64
Mapped< T > make_mapped(T initial, GeometryFn< T > geometry, std::shared_ptr< Buffers::FormaBuffer > buffer)
Construct a Mapped<T> with a freshly allocated MappedState.
Definition Mapped.hpp:143
std::shared_ptr< Buffers::FormaBuffer > buffer
Buffer whose rendered output occupies this region.
Definition Element.hpp:72
A bounded, renderable region on a window surface.
Definition Element.hpp:58
Value carrier for a Mapped primitive.
Definition Mapped.hpp:36
std::shared_ptr< MappedState< T > > state
Shared value carrier. External systems hold a copy of this ptr.
Definition Mapped.hpp:91
std::vector< uint8_t > m_bytes
Definition Mapped.hpp:132
void sync()
Call once per graphics tick.
Definition Mapped.hpp:119
GeometryFn< T > geometry_fn
Geometry regeneration function. Set once at construction.
Definition Mapped.hpp:94
Element element
The Element registered with the Layer.
Definition Mapped.hpp:98
bool force_redraw_on_sync
When true, sync() regenerates geometry every call regardless of whether state->version has advanced.
Definition Mapped.hpp:107
Version last_version
Last version seen by sync().
Definition Mapped.hpp:102
Infrastructure for a continuously-mapped value whose GPU geometry tracks it.
Definition Mapped.hpp:89