MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Agent.hpp
Go to the documentation of this file.
1#pragma once
2
5
7
8namespace MayaFlux::Buffers {
9class VKBuffer;
10}
11
12namespace MayaFlux::Nexus {
13
14/**
15 * @class Agent
16 * @brief Object that both perceives nearby entities and acts on MayaFlux objects.
17 *
18 * Constructed with only a query radius, a perception function, and an influence
19 * function. Position is optional: call @c set_position before registering with
20 * @c Fabric if spatial behaviour is required. Without a position the spatial
21 * index is not consulted and @c spatial_results will be empty on each commit.
22 *
23 * On each commit the perception function is invoked first, then the influence
24 * function. Both receive contexts populated from the same spatial snapshot.
25 *
26 * The id is assigned by @c Fabric::wire and is stable for the object's lifetime.
27 */
28class MAYAFLUX_API Agent {
29public:
30 using InfluenceFn = std::function<void(const InfluenceContext&)>;
31 using PerceptionFn = std::function<void(const PerceptionContext&)>;
32
33 /**
34 * @brief Construct with query radius, perception function, and influence function.
35 * @param query_radius Radius passed to the spatial index on each commit.
36 * Ignored if no position has been set.
37 * @param perception Called first on every commit.
38 * @param influence Called second on every commit.
39 */
40 explicit Agent(float query_radius, PerceptionFn perception, InfluenceFn influence)
41 : m_query_radius(query_radius)
42 , m_perception_fn(std::move(perception))
43 , m_influence_fn(std::move(influence))
44 {
45 }
46
47 /**
48 * @brief Construct with named perception and influence functions.
49 * @param query_radius Radius passed to the spatial index on each commit.
50 * @param perception_fn_name Identifier for the perception function.
51 * @param perception Called first on every commit.
52 * @param influence_fn_name Identifier for the influence function.
53 * @param influence Called second on every commit.
54 */
55 Agent(float query_radius,
56 std::string perception_fn_name, PerceptionFn perception,
57 std::string influence_fn_name, InfluenceFn influence)
58 : m_query_radius(query_radius)
59 , m_perception_fn_name(std::move(perception_fn_name))
60 , m_perception_fn(std::move(perception))
61 , m_influence_fn_name(std::move(influence_fn_name))
62 , m_influence_fn(std::move(influence))
63 {
64 }
65
66 virtual ~Agent() = default;
67
68 /** @brief Identifier assigned to the perception function, empty if anonymous. */
69 [[nodiscard]] const std::string& perception_fn_name() const { return m_perception_fn_name; }
70
71 /** @brief Identifier assigned to the influence function, empty if anonymous. */
72 [[nodiscard]] const std::string& influence_fn_name() const { return m_influence_fn_name; }
73
74 /** @brief Set or replace the perception function's identifier. */
75 void set_perception_fn_name(std::string name) { m_perception_fn_name = std::move(name); }
76
77 /** @brief Set or replace the influence function's identifier. */
78 void set_influence_fn_name(std::string name) { m_influence_fn_name = std::move(name); }
79
80 /** @brief The perception function itself. */
81 [[nodiscard]] const PerceptionFn& perception_fn() const { return m_perception_fn; }
82
83 /** @brief The influence function itself. */
84 [[nodiscard]] const InfluenceFn& influence_fn() const { return m_influence_fn; }
85
86 /**
87 * @brief Return the current position, if set.
88 */
89 [[nodiscard]] const std::optional<glm::vec3>& position() const { return m_position; }
90
91 /**
92 * @brief Set the position, enabling spatial indexing and queries for this object.
93 * @param p World-space coordinates.
94 */
95 void set_position(const glm::vec3& p) { m_position = p; }
96
97 /**
98 * @brief Clear the position, removing this object from spatial operations.
99 */
100 void clear_position() { m_position.reset(); }
101
102 /**
103 * @brief Return the query radius.
104 */
105 [[nodiscard]] float query_radius() const { return m_query_radius; }
106
107 /**
108 * @brief Set the query radius.
109 * @param r New radius in world-space units.
110 */
111 void set_query_radius(float r) { m_query_radius = r; }
112
113 /**
114 * @brief Return the stable object id assigned by Fabric.
115 */
116 [[nodiscard]] uint32_t id() const { return m_id; }
117
118 // =========================================================================
119 // Output sinks
120 // =========================================================================
121
122 /** @brief Register an audio output on @p channel. */
123 void sink_audio(Buffers::BufferManager& mgr, uint32_t channel)
124 {
125 add_audio_sink(m_audio_sinks, mgr, channel);
126 }
127
128 /** @brief Register an audio output on @p channel with a producer function. */
129 void sink_audio(Buffers::BufferManager& mgr, uint32_t channel,
130 std::function<Kakshya::DataVariant(const InfluenceContext&)> fn,
131 std::string fn_name = "")
132 {
133 add_audio_sink(m_audio_sinks, mgr, channel, std::move(fn), std::move(fn_name));
134 }
135
136 /** @brief Unregister the audio sink on @p channel. */
137 void remove_audio_sink(Buffers::BufferManager& mgr, uint32_t channel)
138 {
139 Nexus::remove_audio_sink(m_audio_sinks, mgr, channel);
140 }
141
142 /** @brief Register a render output targeting @p window. */
144 {
145 add_render_sink(m_render_sinks, mgr, config, {}, "", m_position);
146 }
147
148 /** @brief Register a render output targeting @p window with a producer function. */
150 std::string fn_name, RenderFn fn)
151 {
152 add_render_sink(m_render_sinks, mgr, config, std::move(fn), std::move(fn_name), m_position);
153 }
154
155 [[nodiscard]] const std::vector<AudioSink>& audio_sinks() const { return m_audio_sinks; }
156 [[nodiscard]] const std::vector<RenderSink>& render_sinks() const { return m_render_sinks; }
157
158 /* @brief Return the render processor for the sink targeting @p window, or nullptr if not found. */
159 std::shared_ptr<Buffers::RenderProcessor> get_render_processor(
160 const std::shared_ptr<Core::Window>& window) const
161 {
162 auto it = std::ranges::find_if(m_render_sinks,
163 [&window](const RenderSink& s) { return s.window == window; });
164 return it != m_render_sinks.end() ? it->renderer : nullptr;
165 }
166
167 /** @brief Unregister the render sink targeting @p window. */
168 void remove_render(Buffers::BufferManager& mgr, const std::shared_ptr<Core::Window>& window)
169 {
170 remove_render_sink(m_render_sinks, mgr, window);
171 }
172
173 /** @brief Push @p samples to all registered audio sinks. */
174 void set_audio_data(std::span<const double> samples)
175 {
176 push_audio_data(m_audio_sinks, samples);
177 }
178
179 /**
180 * @brief Set pre-packed interleaved vertex bytes to all registered render sinks.
181 *
182 * data must point to N contiguous 60-byte Vertex records.
183 * byte_count must be a multiple of 60.
184 */
185 void set_vertices(const void* data, size_t byte_count);
186
187 /**
188 * @brief Set typed vertex data to all registered render sinks.
189 * @tparam T One of Kakshya::PointVertex, Kakshya::LineVertex, Kakshya::MeshVertex, Kakshya::Vertex.
190 */
191 template <typename T>
192 void set_vertices(std::span<const T> vertices)
193 {
194 static_assert(sizeof(T) == 60, "set_vertices: T must be a 60-byte vertex type");
195 set_vertices(vertices.data(), vertices.size_bytes());
196 }
197
198 /** @brief Set the intensity, a general-purpose parameter for influence functions. */
199 void set_intensity(float i) { m_intensity = i; }
200
201 /** @brief Get the current intensity. */
202 [[nodiscard]] float intensity() const { return m_intensity; }
203
204 /** @brief Set the radius, a general-purpose parameter for influence functions. */
205 void set_radius(float r) { m_radius = r; }
206
207 /** @brief Get the current radius. */
208 [[nodiscard]] float radius() const { return m_radius; }
209
210 /** @brief Set the color, a general-purpose parameter for influence functions. */
211 void set_color(const glm::vec3& c) { m_color = c; }
212
213 /** @brief Clear the color, resetting it to an unset state. */
214 void clear_color() { m_color.reset(); }
215
216 /** @brief Get the current color, if set. */
217 [[nodiscard]] const std::optional<glm::vec3>& color() const { return m_color; }
218
219 /** @brief Set the size, a general-purpose parameter for influence functions. */
220 void set_size(float s) { m_size = s; }
221
222 /** @brief Clear the size, resetting it to an unset state. */
223 void clear_size() { m_size.reset(); }
224
225 /** @brief Get the current size, if set. */
226 [[nodiscard]] const std::optional<float>& size() const { return m_size; }
227
228 /**
229 * @brief Add a render processor to receive GPU-side influence data.
230 *
231 * Allocates the shared influence UBO on the first call. Subsequent calls
232 * bind the same UBO to the new processor: all targets receive identical
233 * context data each commit. Adding the same processor twice is a no-op.
234 *
235 * @param proc Render processor to target. Ignored if null.
236 */
237 void add_influence_target(std::shared_ptr<Buffers::RenderProcessor> proc);
238
239 /**
240 * @brief Remove a single influence target and unbind its UBO.
241 *
242 * If this was the last target the UBO is freed.
243 *
244 * @param proc Processor previously passed to add_influence_target().
245 */
246 void remove_influence_target(const std::shared_ptr<Buffers::RenderProcessor>& proc);
247
248 /**
249 * @brief Unbind and remove all influence targets and free the UBO.
250 */
251 void clear_influence_targets();
252
253 /**
254 * @brief All render processors currently receiving influence data.
255 */
256 [[nodiscard]] const std::vector<std::shared_ptr<Buffers::RenderProcessor>>&
258 {
259 return m_influence_targets;
260 }
261
262 /**
263 * @brief Invoke the perception function with the supplied context.
264 * @param ctx Populated context for this commit.
265 */
266 virtual void invoke_perception(const PerceptionContext& ctx)
267 {
268 if (m_perception_fn) {
269 m_perception_fn(ctx);
270 }
271 }
272
273 /**
274 * @brief Invoke the influence function with the supplied context.
275 * @param ctx Populated context for this commit.
276 */
277 virtual void invoke_influence(const InfluenceContext& ctx) const
278 {
279 if (m_influence_fn) {
280 m_influence_fn(ctx);
281 }
282 dispatch_audio_sinks(m_audio_sinks, ctx);
283 dispatch_render_sinks(m_render_sinks, ctx);
284 if (m_influence_ubo)
285 upload_influence_ubo(ctx);
286 }
287
288private:
289 std::optional<glm::vec3> m_position;
290 std::optional<glm::vec3> m_color;
291 std::optional<float> m_size;
292 float m_intensity { 1.0F };
293 float m_radius { 1.0F };
294
295 std::vector<std::shared_ptr<Buffers::RenderProcessor>> m_influence_targets;
296 std::shared_ptr<Buffers::VKBuffer> m_influence_ubo;
297
303 uint32_t m_id {};
304
305 mutable std::vector<AudioSink> m_audio_sinks;
306 mutable std::vector<RenderSink> m_render_sinks;
307
308 void upload_influence_ubo(const InfluenceContext& ctx) const;
309
310 friend class Fabric;
311};
312
313} // namespace MayaFlux::Nexus
Token-based multimodal buffer management system for unified data stream processing.
void set_color(const glm::vec3 &c)
Set the color, a general-purpose parameter for influence functions.
Definition Agent.hpp:211
float radius() const
Get the current radius.
Definition Agent.hpp:208
void set_influence_fn_name(std::string name)
Set or replace the influence function's identifier.
Definition Agent.hpp:78
const std::optional< glm::vec3 > & position() const
Return the current position, if set.
Definition Agent.hpp:89
Agent(float query_radius, PerceptionFn perception, InfluenceFn influence)
Construct with query radius, perception function, and influence function.
Definition Agent.hpp:40
void set_intensity(float i)
Set the intensity, a general-purpose parameter for influence functions.
Definition Agent.hpp:199
const std::optional< glm::vec3 > & color() const
Get the current color, if set.
Definition Agent.hpp:217
InfluenceFn m_influence_fn
Definition Agent.hpp:302
virtual void invoke_influence(const InfluenceContext &ctx) const
Invoke the influence function with the supplied context.
Definition Agent.hpp:277
PerceptionFn m_perception_fn
Definition Agent.hpp:300
void remove_audio_sink(Buffers::BufferManager &mgr, uint32_t channel)
Unregister the audio sink on channel.
Definition Agent.hpp:137
void set_size(float s)
Set the size, a general-purpose parameter for influence functions.
Definition Agent.hpp:220
std::vector< std::shared_ptr< Buffers::RenderProcessor > > m_influence_targets
Definition Agent.hpp:295
virtual void invoke_perception(const PerceptionContext &ctx)
Invoke the perception function with the supplied context.
Definition Agent.hpp:266
uint32_t id() const
Return the stable object id assigned by Fabric.
Definition Agent.hpp:116
const std::vector< AudioSink > & audio_sinks() const
Definition Agent.hpp:155
std::vector< AudioSink > m_audio_sinks
Definition Agent.hpp:305
void clear_position()
Clear the position, removing this object from spatial operations.
Definition Agent.hpp:100
void render(Buffers::BufferManager &mgr, const Portal::Graphics::RenderConfig &config)
Register a render output targeting window.
Definition Agent.hpp:143
std::optional< float > m_size
Definition Agent.hpp:291
std::optional< glm::vec3 > m_position
Definition Agent.hpp:289
const std::vector< std::shared_ptr< Buffers::RenderProcessor > > & influence_targets() const
All render processors currently receiving influence data.
Definition Agent.hpp:257
const InfluenceFn & influence_fn() const
The influence function itself.
Definition Agent.hpp:84
std::function< void(const PerceptionContext &)> PerceptionFn
Definition Agent.hpp:31
float intensity() const
Get the current intensity.
Definition Agent.hpp:202
void sink_audio(Buffers::BufferManager &mgr, uint32_t channel)
Register an audio output on channel.
Definition Agent.hpp:123
const std::string & influence_fn_name() const
Identifier assigned to the influence function, empty if anonymous.
Definition Agent.hpp:72
const std::optional< float > & size() const
Get the current size, if set.
Definition Agent.hpp:226
void clear_size()
Clear the size, resetting it to an unset state.
Definition Agent.hpp:223
void set_audio_data(std::span< const double > samples)
Push samples to all registered audio sinks.
Definition Agent.hpp:174
std::optional< glm::vec3 > m_color
Definition Agent.hpp:290
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 Agent.hpp:149
void clear_color()
Clear the color, resetting it to an unset state.
Definition Agent.hpp:214
std::shared_ptr< Buffers::RenderProcessor > get_render_processor(const std::shared_ptr< Core::Window > &window) const
Definition Agent.hpp:159
void set_query_radius(float r)
Set the query radius.
Definition Agent.hpp:111
std::string m_perception_fn_name
Definition Agent.hpp:299
void set_radius(float r)
Set the radius, a general-purpose parameter for influence functions.
Definition Agent.hpp:205
void set_perception_fn_name(std::string name)
Set or replace the perception function's identifier.
Definition Agent.hpp:75
void remove_render(Buffers::BufferManager &mgr, const std::shared_ptr< Core::Window > &window)
Unregister the render sink targeting window.
Definition Agent.hpp:168
const std::string & perception_fn_name() const
Identifier assigned to the perception function, empty if anonymous.
Definition Agent.hpp:69
Agent(float query_radius, std::string perception_fn_name, PerceptionFn perception, std::string influence_fn_name, InfluenceFn influence)
Construct with named perception and influence functions.
Definition Agent.hpp:55
std::string m_influence_fn_name
Definition Agent.hpp:301
const PerceptionFn & perception_fn() const
The perception function itself.
Definition Agent.hpp:81
std::vector< RenderSink > m_render_sinks
Definition Agent.hpp:306
float query_radius() const
Return the query radius.
Definition Agent.hpp:105
void set_vertices(std::span< const T > vertices)
Set typed vertex data to all registered render sinks.
Definition Agent.hpp:192
void set_position(const glm::vec3 &p)
Set the position, enabling spatial indexing and queries for this object.
Definition Agent.hpp:95
std::function< void(const InfluenceContext &)> InfluenceFn
Definition Agent.hpp:30
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 Agent.hpp:129
std::shared_ptr< Buffers::VKBuffer > m_influence_ubo
Definition Agent.hpp:296
virtual ~Agent()=default
const std::vector< RenderSink > & render_sinks() const
Definition Agent.hpp:156
Object that both perceives nearby entities and acts on MayaFlux objects.
Definition Agent.hpp:28
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.
Data passed to a Sensor or Agent perception 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.