MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Emitter.hpp
Go to the documentation of this file.
1#pragma once
2
5
6namespace MayaFlux::Buffers {
7class VKBuffer;
8}
9
10namespace MayaFlux::Nexus {
11
12/**
13 * @class Emitter
14 * @brief Object that acts on existing MayaFlux objects when committed.
15 *
16 * Constructed with only an influence function. Position is optional: call
17 * @c set_position before registering with @c Fabric if spatial indexing is
18 * required. Entities without a position are committed normally but are not
19 * inserted into the spatial index.
20 *
21 * The id is assigned by @c Fabric::wire and is stable for the object's
22 * lifetime. It is zero until the object has been registered.
23 */
24class MAYAFLUX_API Emitter {
25public:
26 using InfluenceFn = std::function<void(const InfluenceContext&)>;
27
28 /**
29 * @brief Construct with an influence function.
30 * @param fn Called on every commit with the current context.
31 */
32 explicit Emitter(InfluenceFn fn)
33 : m_fn(std::move(fn))
34 {
35 }
36
37 /**
38 * @brief Construct with a named influence function.
39 * @param fn_name Identifier used for state encoding.
40 * @param fn Called on every commit with the current context.
41 */
42 Emitter(std::string fn_name, InfluenceFn fn)
43 : m_fn_name(std::move(fn_name))
44 , m_fn(std::move(fn))
45 {
46 }
47
48 /** @brief Identifier assigned to the influence function, empty if anonymous. */
49 [[nodiscard]] const std::string& fn_name() const { return m_fn_name; }
50
51 /** @brief Set or replace the influence function's identifier. */
52 void set_fn_name(std::string name) { m_fn_name = std::move(name); }
53
54 /** @brief The influence function itself. */
55 [[nodiscard]] const InfluenceFn& fn() const { return m_fn; }
56
57 /**
58 * @brief Return the current position, if set.
59 */
60 [[nodiscard]] const std::optional<glm::vec3>& position() const { return m_position; }
61
62 /**
63 * @brief Set the position, enabling spatial indexing for this object.
64 * @param p World-space coordinates.
65 */
66 void set_position(const glm::vec3& p) { m_position = p; }
67
68 /**
69 * @brief Clear the position, removing this object from spatial queries.
70 */
71 void clear_position() { m_position.reset(); }
72
73 /**
74 * @brief Return the stable object id assigned by Fabric.
75 */
76 [[nodiscard]] uint32_t id() const { return m_id; }
77
78 // =========================================================================
79 // Output sinks
80 // =========================================================================
81
82 /** @brief Register an audio output on @p channel. */
83 void sink_audio(Buffers::BufferManager& mgr, uint32_t channel)
84 {
85 add_audio_sink(m_audio_sinks, mgr, channel);
86 }
87
88 /** @brief Register an audio output on @p channel with a producer function. */
89 void sink_audio(Buffers::BufferManager& mgr, uint32_t channel,
90 std::function<Kakshya::DataVariant(const InfluenceContext&)> fn,
91 std::string fn_name = "")
92 {
93 add_audio_sink(m_audio_sinks, mgr, channel, std::move(fn), std::move(fn_name));
94 }
95
96 /** @brief Unregister the audio sink on @p channel. */
97 void remove_audio_sink(Buffers::BufferManager& mgr, uint32_t channel)
98 {
99 Nexus::remove_audio_sink(m_audio_sinks, mgr, channel);
100 }
101
102 /** @brief Register a render output targeting @p window. */
104 {
105 add_render_sink(m_render_sinks, mgr, config, {}, "", m_position);
106 }
107
108 /** @brief Register a render output targeting @p window with a producer function. */
110 std::string fn_name, RenderFn fn)
111 {
112 add_render_sink(m_render_sinks, mgr, config, std::move(fn), std::move(fn_name), m_position);
113 }
114
115 [[nodiscard]] const std::vector<AudioSink>& audio_sinks() const { return m_audio_sinks; }
116 [[nodiscard]] const std::vector<RenderSink>& render_sinks() const { return m_render_sinks; }
117
118 /* @brief Return the render processor for the sink targeting @p window, or nullptr if not found. */
119 std::shared_ptr<Buffers::RenderProcessor> get_render_processor(
120 const std::shared_ptr<Core::Window>& window) const
121 {
122 auto it = std::ranges::find_if(m_render_sinks,
123 [&window](const RenderSink& s) { return s.window == window; });
124 return it != m_render_sinks.end() ? it->renderer : nullptr;
125 }
126
127 /** @brief Unregister the render sink targeting @p window. */
128 void remove_render(Buffers::BufferManager& mgr, const std::shared_ptr<Core::Window>& window)
129 {
130 remove_render_sink(m_render_sinks, mgr, window);
131 }
132
133 /** @brief Push @p samples to all registered audio sinks. */
134 void set_audio_data(std::span<const double> samples)
135 {
136 push_audio_data(m_audio_sinks, samples);
137 }
138
139 /**
140 * @brief Set pre-packed interleaved vertex bytes to all registered render sinks.
141 *
142 * data must point to N contiguous 60-byte Vertex records.
143 * byte_count must be a multiple of 60.
144 */
145 void set_vertices(const void* data, size_t byte_count);
146
147 /**
148 * @brief Set typed vertex data to all registered render sinks.
149 * @tparam T One of Kakshya::PointVertex, Kakshya::LineVertex, Kakshya::MeshVertex, Kakshya::Vertex.
150 */
151 template <typename T>
152 void set_vertices(std::span<const T> vertices)
153 {
154 static_assert(sizeof(T) == 60, "set_vertices: T must be a 60-byte vertex type");
155 set_vertices(vertices.data(), vertices.size_bytes());
156 }
157
158 /** @brief Set the intensity, a general-purpose parameter for influence functions. */
159 void set_intensity(float i) { m_intensity = i; }
160
161 /** @brief Get the current intensity. */
162 [[nodiscard]] float intensity() const { return m_intensity; }
163
164 /** @brief Set the radius, a general-purpose parameter for influence functions. */
165 void set_radius(float r) { m_radius = r; }
166
167 /** @brief Get the current radius. */
168 [[nodiscard]] float radius() const { return m_radius; }
169
170 /** @brief Set the color, a general-purpose parameter for influence functions. */
171 void set_color(const glm::vec3& c) { m_color = c; }
172
173 /** @brief Clear the color, resetting it to an unset state. */
174 void clear_color() { m_color.reset(); }
175
176 /** @brief Get the current color, if set. */
177 [[nodiscard]] const std::optional<glm::vec3>& color() const { return m_color; }
178
179 /** @brief Set the size, a general-purpose parameter for influence functions. */
180 void set_size(float s) { m_size = s; }
181
182 /** @brief Clear the size, resetting it to an unset state. */
183 void clear_size() { m_size.reset(); }
184
185 /** @brief Get the current size, if set. */
186 [[nodiscard]] const std::optional<float>& size() const { return m_size; }
187
188 /**
189 * @brief Set the render processor to target for GPU-side influence delivery.
190 *
191 * Creates a UBO matching the InfluenceUBO layout, registers a binding
192 * named "u_influence" at set=1 binding=0 on the target processor,
193 * and binds the UBO. On each subsequent invoke(), the context fields
194 * are packed into the UBO automatically.
195 *
196 * @param proc Target render processor. Must outlive this Emitter or
197 * be cleared via clear_influence_target() first.
198 */
199 void set_influence_target(std::shared_ptr<Buffers::RenderProcessor> proc);
200
201 /**
202 * @brief Disconnect from the current influence target.
203 *
204 * Unbinds the "u_influence" descriptor from the target processor
205 * and releases the UBO.
206 */
207 void clear_influence_target();
208
209 /**
210 * @brief Return the current influence target, if set.
211 */
212 [[nodiscard]] std::weak_ptr<Buffers::RenderProcessor> influence_target() const
213 {
214 return m_influence_target;
215 }
216
217 /**
218 * @brief Invoke the influence function with the supplied context.
219 * @param ctx Populated context for this commit.
220 */
221 void invoke(const InfluenceContext& ctx) const
222 {
223 if (m_fn) {
224 m_fn(ctx);
225 }
226 dispatch_audio_sinks(m_audio_sinks, ctx);
227 dispatch_render_sinks(m_render_sinks, ctx);
228 if (m_influence_ubo)
229 upload_influence_ubo(ctx);
230 }
231
232private:
233 std::optional<glm::vec3> m_position;
234 std::optional<glm::vec3> m_color;
235 std::optional<float> m_size;
236 float m_intensity { 1.0F };
237 float m_radius { 1.0F };
238
239 std::shared_ptr<Buffers::RenderProcessor> m_influence_target;
240 std::shared_ptr<Buffers::VKBuffer> m_influence_ubo;
241
243 uint32_t m_id {};
244 std::string m_fn_name;
245
246 mutable std::vector<AudioSink> m_audio_sinks;
247 mutable std::vector<RenderSink> m_render_sinks;
248
249 void upload_influence_ubo(const InfluenceContext& ctx) const;
250
251 friend class Fabric;
252};
253
254} // namespace MayaFlux::Nexus
Token-based multimodal buffer management system for unified data stream processing.
const std::string & fn_name() const
Identifier assigned to the influence function, empty if anonymous.
Definition Emitter.hpp:49
const std::optional< glm::vec3 > & position() const
Return the current position, if set.
Definition Emitter.hpp:60
float radius() const
Get the current radius.
Definition Emitter.hpp:168
std::weak_ptr< Buffers::RenderProcessor > influence_target() const
Return the current influence target, if set.
Definition Emitter.hpp:212
std::shared_ptr< Buffers::VKBuffer > m_influence_ubo
Definition Emitter.hpp:240
std::optional< float > m_size
Definition Emitter.hpp:235
const std::vector< AudioSink > & audio_sinks() const
Definition Emitter.hpp:115
const InfluenceFn & fn() const
The influence function itself.
Definition Emitter.hpp:55
std::optional< glm::vec3 > m_color
Definition Emitter.hpp:234
void sink_audio(Buffers::BufferManager &mgr, uint32_t channel)
Register an audio output on channel.
Definition Emitter.hpp:83
void clear_size()
Clear the size, resetting it to an unset state.
Definition Emitter.hpp:183
uint32_t id() const
Return the stable object id assigned by Fabric.
Definition Emitter.hpp:76
std::function< void(const InfluenceContext &)> InfluenceFn
Definition Emitter.hpp:26
std::shared_ptr< Buffers::RenderProcessor > m_influence_target
Definition Emitter.hpp:239
std::optional< glm::vec3 > m_position
Definition Emitter.hpp:233
void set_intensity(float i)
Set the intensity, a general-purpose parameter for influence functions.
Definition Emitter.hpp:159
const std::optional< float > & size() const
Get the current size, if set.
Definition Emitter.hpp:186
void set_size(float s)
Set the size, a general-purpose parameter for influence functions.
Definition Emitter.hpp:180
void render(Buffers::BufferManager &mgr, const Portal::Graphics::RenderConfig &config)
Register a render output targeting window.
Definition Emitter.hpp:103
void set_radius(float r)
Set the radius, a general-purpose parameter for influence functions.
Definition Emitter.hpp:165
const std::vector< RenderSink > & render_sinks() const
Definition Emitter.hpp:116
void render(Buffers::BufferManager &mgr, const Portal::Graphics::RenderConfig &config, std::string fn_name, RenderFn fn)
Register a render output targeting window with a producer function.
Definition Emitter.hpp:109
std::vector< AudioSink > m_audio_sinks
Definition Emitter.hpp:246
void sink_audio(Buffers::BufferManager &mgr, uint32_t channel, std::function< Kakshya::DataVariant(const InfluenceContext &)> fn, std::string fn_name="")
Register an audio output on channel with a producer function.
Definition Emitter.hpp:89
void set_vertices(std::span< const T > vertices)
Set typed vertex data to all registered render sinks.
Definition Emitter.hpp:152
void remove_render(Buffers::BufferManager &mgr, const std::shared_ptr< Core::Window > &window)
Unregister the render sink targeting window.
Definition Emitter.hpp:128
std::vector< RenderSink > m_render_sinks
Definition Emitter.hpp:247
const std::optional< glm::vec3 > & color() const
Get the current color, if set.
Definition Emitter.hpp:177
void invoke(const InfluenceContext &ctx) const
Invoke the influence function with the supplied context.
Definition Emitter.hpp:221
Emitter(std::string fn_name, InfluenceFn fn)
Construct with a named influence function.
Definition Emitter.hpp:42
std::shared_ptr< Buffers::RenderProcessor > get_render_processor(const std::shared_ptr< Core::Window > &window) const
Definition Emitter.hpp:119
void clear_color()
Clear the color, resetting it to an unset state.
Definition Emitter.hpp:174
void clear_position()
Clear the position, removing this object from spatial queries.
Definition Emitter.hpp:71
float intensity() const
Get the current intensity.
Definition Emitter.hpp:162
void set_color(const glm::vec3 &c)
Set the color, a general-purpose parameter for influence functions.
Definition Emitter.hpp:171
void set_audio_data(std::span< const double > samples)
Push samples to all registered audio sinks.
Definition Emitter.hpp:134
void set_fn_name(std::string name)
Set or replace the influence function's identifier.
Definition Emitter.hpp:52
void set_position(const glm::vec3 &p)
Set the position, enabling spatial indexing for this object.
Definition Emitter.hpp:66
Emitter(InfluenceFn fn)
Construct with an influence function.
Definition Emitter.hpp:32
void remove_audio_sink(Buffers::BufferManager &mgr, uint32_t channel)
Unregister the audio sink on channel.
Definition Emitter.hpp:97
Object that acts on existing MayaFlux objects when committed.
Definition Emitter.hpp:24
Orchestrates spatial indexing and scheduling for Nexus objects.
Definition Fabric.hpp:38
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.
Definition NDData.hpp:76
std::function< void(const InfluenceContext &)> RenderFn
Definition Sinks.hpp:26
void remove_render_sink(std::vector< RenderSink > &sinks, Buffers::BufferManager &mgr, const std::shared_ptr< Core::Window > &window)
Unregister and destroy the render sink targeting window.
Definition Sinks.cpp:186
void dispatch_render_sinks(std::vector< RenderSink > &sinks, const InfluenceContext &ctx)
For each sink that has a producer fn, call it and push the result.
Definition Sinks.cpp:207
void push_audio_data(std::vector< AudioSink > &sinks, std::span< const double > samples)
Push samples to every audio sink in sinks.
Definition Sinks.cpp:64
void dispatch_audio_sinks(std::vector< AudioSink > &sinks, const InfluenceContext &ctx)
For each sink that has a producer fn, call it and push the result.
Definition Sinks.cpp:71
void add_audio_sink(std::vector< AudioSink > &sinks, Buffers::BufferManager &mgr, uint32_t channel, std::function< Kakshya::DataVariant(const InfluenceContext &)> fn, std::string fn_name)
Create and register an audio sink on channel.
Definition Sinks.cpp:18
void add_render_sink(std::vector< RenderSink > &sinks, Buffers::BufferManager &mgr, const Portal::Graphics::RenderConfig &config, RenderFn fn, std::string fn_name, const std::optional< glm::vec3 > &initial_position)
Create and register a render sink targeting window.
Definition Sinks.cpp:95
Data passed to an Emitter or Agent influence function on each commit.
std::shared_ptr< Core::Window > window
Definition Sinks.hpp:69
Holds the plumbing for one graphics output registered from a Nexus object.
Definition Sinks.hpp:63
Unified rendering configuration for graphics buffers.