MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Wiring.hpp
Go to the documentation of this file.
1#pragma once
2
4
8
10
11namespace MayaFlux::Core {
12class Window;
13}
14
15namespace MayaFlux::Vruta {
16class TaskScheduler;
17class EventManager;
18class Routine;
19class SoundRoutine;
20class GraphicsRoutine;
21class CrossRoutine;
22class Event;
23}
24
25namespace MayaFlux::Nexus {
26
27class Fabric;
28
29/**
30 * @class Wiring
31 * @brief Fluent builder that wires an entity into Fabric's scheduling infrastructure.
32 *
33 * Obtained via @c Fabric::wire. Describes when and how the object's function
34 * is invoked. Call @c finalise() to apply the configuration.
35 *
36 * No coroutine is created unless a scheduling modifier is set. @c bind()
37 * performs an immediate single call with no coroutine. Any scheduling
38 * modifier (@c every, @c on, @c move_to, @c position_from, @c use) creates
39 * and registers a coroutine owned by Fabric.
40 */
41class MAYAFLUX_API Wiring {
42public:
43 using PositionFn = std::function<glm::vec3()>;
44 using SoundFactory = std::function<Vruta::SoundRoutine()>;
45 using GraphicsFactory = std::function<Vruta::GraphicsRoutine()>;
46 using CrossFactory = std::function<Vruta::CrossRoutine()>;
48 using NullFunc = std::nullptr_t;
49 static constexpr NullFunc no_release = nullptr;
50
51 // =====================================================================
52 // Scheduling modifiers
53 // =====================================================================
54
55 /**
56 * @brief Fire the entity on a recurring interval.
57 * @param interval_seconds Period between invocations.
58 * @param token Scheduler rate to use (default: SAMPLE_ACCURATE).
59 */
60 Wiring& every(double interval_seconds, Vruta::ProcessingToken token = Vruta::ProcessingToken::SAMPLE_ACCURATE);
61
62 /**
63 * @brief Limit a recurring registration to a fixed duration then cancel.
64 * @param seconds Total active time. Pairs with @c every().
65 * @param token If set, uses the specified scheduler's clock for timing; otherwise defaults to SAMPLE_ACCURATE.
66 */
67 Wiring& for_duration(double seconds, Vruta::ProcessingToken token = Vruta::ProcessingToken::SAMPLE_ACCURATE);
68
69 /**
70 * @brief Fire the entity on a key event from a window.
71 * @param window Source window.
72 * @param key Key to listen for.
73 */
74 Wiring& on(std::shared_ptr<Core::Window> window, IO::Keys key);
75
76 /**
77 * @brief Fire the entity repeatedly while a key is held, invoking a release callback on release.
78 * @param window Source window.
79 * @param key Key to listen for.
80 * @param held If true, fires on repeat ticks while held.
81 * @param on_release Called when the key is released.
82 */
83 Wiring& on(std::shared_ptr<Core::Window> window, IO::Keys key, bool held,
84 std::function<void()> on_release = nullptr);
85
86 /**
87 * @brief Fire the entity on a mouse button event from a window.
88 * @param window Source window.
89 * @param button Mouse button to listen for.
90 */
91 Wiring& on(std::shared_ptr<Core::Window> window, IO::MouseButtons button);
92
93 /**
94 * @brief Fire the entity on mouse-motion events while @p button is held.
95 *
96 * Mirrors the key held overload. Cursor position is available via
97 * InfluenceContext on each qualifying event.
98 *
99 * @param window Source window.
100 * @param button Button that must be pressed for the entity to fire.
101 * @param held Pass @c true to select the motion-while-held path.
102 * @param on_release Called when the button is released.
103 */
104 Wiring& on(std::shared_ptr<Core::Window> window, IO::MouseButtons button, bool held,
105 std::function<void(double, double)> on_release = nullptr);
106
107 /**
108 * @brief Fire the entity on mouse button press and invoke a release callback on release.
109 * @param window Source window.
110 * @param button Mouse button to listen for.
111 * @param on_release Called with cursor position when the button is released. Cancelled with the wiring.
112 */
113 Wiring& on(std::shared_ptr<Core::Window> window, IO::MouseButtons button,
114 std::function<void(double, double)> on_release);
115
116 /**
117 * @brief Fire the entity on each incoming message from a network source.
118 * @param source OSC or raw network source.
119 */
120 Wiring& on(Vruta::NetworkSource& source);
121
122 /**
123 * @brief Fire the entity on each matching window event.
124 * @param source Event stream.
125 * @param filter Optional filter criteria.
126 */
128
129 /**
130 * @brief Choreograph a position move as an EventChain step.
131 * @param pos Target position.
132 * @param delay_seconds Delay after the previous step (0 = immediate on start).
133 */
134 Wiring& move_to(const glm::vec3& pos, double delay_seconds = 0.0);
135
136 /**
137 * @brief Drive position from a callable evaluated on each @c every() tick.
138 * @param fn Returns the new position on each invocation.
139 */
140 Wiring& position_from(PositionFn fn);
141
142 /**
143 * @brief Drive position from a named callable evaluated on each @c every() tick.
144 * @param fn_name Identifier used for state encoding.
145 * @param fn Returns the new position on each invocation.
146 */
147 Wiring& position_from(std::string fn_name, PositionFn fn);
148
149 /**
150 * @brief Repeat the configured sequence or choreography N times.
151 * @param count Number of repetitions.
152 */
153 Wiring& times(size_t count);
154
155 /**
156 * @brief Delegate coroutine creation entirely to the caller.
157 *
158 * Fabric registers the entity with the spatial index and adds the
159 * returned coroutine. All timing and entity commit logic is the
160 * caller's responsibility.
161 */
162 Wiring& use(SoundFactory factory);
163 Wiring& use(GraphicsFactory factory);
164 Wiring& use(CrossFactory factory);
165 Wiring& use(EventFactory factory);
166
167 /** @brief Register a named factory. */
168 Wiring& use(std::string fn_name, SoundFactory factory);
169 Wiring& use(std::string fn_name, GraphicsFactory factory);
170 Wiring& use(std::string fn_name, CrossFactory factory);
171 Wiring& use(std::string fn_name, EventFactory factory);
172
173 // =====================================================================
174 // Immediate bind — no coroutine
175 // =====================================================================
176
177 /**
178 * @brief Call the entity's influence function once immediately.
179 *
180 * No coroutine is created. If @c for_duration was set, a Timer fires
181 * the detach function after expiry.
182 */
183 Wiring& bind();
184
185 /**
186 * @brief Call a custom function once immediately instead of the entity's own.
187 * @param fn Callable to invoke in place of the entity's influence function.
188 */
189 Wiring& bind(std::function<void()> fn);
190
191 /**
192 * @brief Call attach immediately; call detach after @c for_duration expires
193 * or on explicit @c cancel().
194 * @param attach Called immediately on finalise().
195 * @param detach Called on expiry or cancellation.
196 */
197 Wiring& bind(std::function<void()> attach, std::function<void()> detach);
198
199 /** @brief Call a named custom function once immediately. */
200 Wiring& bind(std::string fn_name, std::function<void()> fn);
201
202 /** @brief Call named attach/detach functions. */
203 Wiring& bind(std::string attach_name, std::function<void()> attach,
204 std::string detach_name, std::function<void()> detach);
205
206 // =====================================================================
207 // Terminal
208 // =====================================================================
209
210 /**
211 * @brief Apply the configured wiring.
212 *
213 * Resolves the builder state into a coroutine (if any scheduling
214 * modifier was set) or an immediate call (if @c bind was used),
215 * and registers the result with Fabric.
216 */
217 void finalise();
218
219 /**
220 * @brief Cancel an active wiring and release any owned coroutine.
221 */
222 void cancel();
223
224private:
225 friend class Fabric;
226
227 explicit Wiring(Fabric& fabric, uint32_t entity_id)
228 : m_fabric(fabric)
229 , m_entity_id(entity_id)
230 {
231 }
232
233 // =====================================================================
234 // Stored configuration
235 // =====================================================================
236
237 struct MoveStep {
238 glm::vec3 position;
240 };
241
242 struct KeyTrigger {
243 std::shared_ptr<Core::Window> window;
245 std::optional<std::function<void()>> on_release;
246 bool held {};
247 };
248
250 std::shared_ptr<Core::Window> window;
252 std::optional<std::function<void(double, double)>> on_release;
253 bool held {};
254 };
255
259
264
269
270 using Trigger = std::variant<std::monostate, KeyTrigger, MouseTrigger, NetworkTrigger, EventTrigger, WindowEventTrigger>;
271 using Factory = std::variant<std::monostate, SoundFactory, GraphicsFactory, CrossFactory>;
272 using EFactory = std::optional<EventFactory>;
273
274 std::string make_name(const char* prefix) const;
276 uint32_t m_entity_id;
277 bool m_has_scheduling {};
278
279 std::optional<double> m_interval;
280 std::optional<double> m_duration;
281 std::optional<PositionFn> m_position_fn;
283 std::vector<MoveStep> m_move_steps;
284 size_t m_times { 1 };
285 Vruta::ProcessingToken m_metro_token { Vruta::ProcessingToken::SAMPLE_ACCURATE };
286 Vruta::ProcessingToken m_duration_token { Vruta::ProcessingToken::SAMPLE_ACCURATE };
287
291 std::string m_factory_name;
292
293 std::optional<std::function<void()>> m_bind_attach;
294 std::optional<std::function<void()>> m_bind_detach;
297
298 Vruta::Event window_event_source_loop(Vruta::WindowEventSource& source, Vruta::WindowEventFilter filter, Fabric& fabric, uint32_t id);
299
300public:
301 // =====================================================================
302 // Move semantics
303 // =====================================================================
304 ~Wiring() = default;
305 Wiring(const Wiring&) = delete;
306 Wiring& operator=(const Wiring&) = delete;
307 Wiring(Wiring&&) noexcept = default;
308 Wiring& operator=(Wiring&&) = delete;
309
310 // =====================================================================
311 // Introspection
312 // =====================================================================
313
314 /** @brief Stable id of the wired entity. */
315 [[nodiscard]] uint32_t entity_id() const { return m_entity_id; }
316
317 /** @brief Recurring interval in seconds, if @c every was called. */
318 [[nodiscard]] std::optional<double> interval() const { return m_interval; }
319
320 /** @brief Active duration in seconds, if @c for_duration was called. */
321 [[nodiscard]] std::optional<double> duration() const { return m_duration; }
322
323 /** @brief Repetition count set by @c times, default 1. */
324 [[nodiscard]] size_t times_count() const { return m_times; }
325
326 /** @brief Choreography steps from @c move_to calls. */
327 [[nodiscard]] const std::vector<MoveStep>& move_steps() const { return m_move_steps; }
328
329 /** @brief Active trigger variant set by @c on. */
330 [[nodiscard]] const Trigger& trigger() const { return m_trigger; }
331
332 /** @brief Active factory variant set by @c use for non-Event factories. */
333 [[nodiscard]] const Factory& factory() const { return m_factory; }
334
335 /** @brief Active event-factory, if @c use(EventFactory) was called. */
336 [[nodiscard]] const EFactory& event_factory() const { return m_event_factory; }
337
338 /** @brief True if @c position_from was called. */
339 [[nodiscard]] bool has_position_fn() const { return m_position_fn.has_value(); }
340
341 /** @brief True if any @c bind overload was called. */
342 [[nodiscard]] bool has_bind() const { return m_bind_attach.has_value(); }
343
344 /** @brief True if @c bind(attach, detach) was called. */
345 [[nodiscard]] bool has_bind_detach() const { return m_bind_detach.has_value(); }
346
347 /** @brief Name of the position function, empty if anonymous. */
348 [[nodiscard]] const std::string& position_fn_name() const { return m_position_fn_name; }
349
350 /** @brief Name of the active factory, empty if anonymous or none. */
351 [[nodiscard]] const std::string& factory_name() const { return m_factory_name; }
352
353 /** @brief Name of the bind attach function, empty if anonymous or none. */
354 [[nodiscard]] const std::string& bind_attach_name() const { return m_bind_attach_name; }
355
356 /** @brief Name of the bind detach function, empty if anonymous or none. */
357 [[nodiscard]] const std::string& bind_detach_name() const { return m_bind_detach_name; }
358};
359
360} // namespace MayaFlux::Nexus
size_t count
Orchestrates spatial indexing and scheduling for Nexus objects.
Definition Fabric.hpp:38
std::optional< std::function< void()> > m_bind_detach
Definition Wiring.hpp:294
bool has_position_fn() const
True if position_from was called.
Definition Wiring.hpp:339
const Trigger & trigger() const
Active trigger variant set by on.
Definition Wiring.hpp:330
std::string m_position_fn_name
Definition Wiring.hpp:282
bool has_bind_detach() const
True if bind(attach, detach) was called.
Definition Wiring.hpp:345
std::function< Vruta::CrossRoutine()> CrossFactory
Definition Wiring.hpp:46
std::string m_bind_attach_name
Definition Wiring.hpp:295
std::nullptr_t NullFunc
Definition Wiring.hpp:48
const std::string & position_fn_name() const
Name of the position function, empty if anonymous.
Definition Wiring.hpp:348
const std::string & bind_attach_name() const
Name of the bind attach function, empty if anonymous or none.
Definition Wiring.hpp:354
const std::string & factory_name() const
Name of the active factory, empty if anonymous or none.
Definition Wiring.hpp:351
Wiring(Wiring &&) noexcept=default
const EFactory & event_factory() const
Active event-factory, if use(EventFactory) was called.
Definition Wiring.hpp:336
std::function< glm::vec3()> PositionFn
Definition Wiring.hpp:43
std::optional< std::function< void()> > m_bind_attach
Definition Wiring.hpp:293
const std::vector< MoveStep > & move_steps() const
Choreography steps from move_to calls.
Definition Wiring.hpp:327
std::optional< double > m_duration
Definition Wiring.hpp:280
std::optional< EventFactory > EFactory
Definition Wiring.hpp:272
Wiring & operator=(const Wiring &)=delete
std::function< Vruta::GraphicsRoutine()> GraphicsFactory
Definition Wiring.hpp:45
std::function< Vruta::Event(Vruta::TaskScheduler &)> EventFactory
Definition Wiring.hpp:47
const std::string & bind_detach_name() const
Name of the bind detach function, empty if anonymous or none.
Definition Wiring.hpp:357
std::variant< std::monostate, KeyTrigger, MouseTrigger, NetworkTrigger, EventTrigger, WindowEventTrigger > Trigger
Definition Wiring.hpp:270
std::optional< double > m_interval
Definition Wiring.hpp:279
const Factory & factory() const
Active factory variant set by use for non-Event factories.
Definition Wiring.hpp:333
bool has_bind() const
True if any bind overload was called.
Definition Wiring.hpp:342
std::optional< double > interval() const
Recurring interval in seconds, if every was called.
Definition Wiring.hpp:318
std::optional< double > duration() const
Active duration in seconds, if for_duration was called.
Definition Wiring.hpp:321
Wiring(const Wiring &)=delete
std::string m_bind_detach_name
Definition Wiring.hpp:296
std::vector< MoveStep > m_move_steps
Definition Wiring.hpp:283
std::string m_factory_name
Definition Wiring.hpp:291
size_t times_count() const
Repetition count set by times, default 1.
Definition Wiring.hpp:324
std::optional< PositionFn > m_position_fn
Definition Wiring.hpp:281
Wiring(Fabric &fabric, uint32_t entity_id)
Definition Wiring.hpp:227
std::variant< std::monostate, SoundFactory, GraphicsFactory, CrossFactory > Factory
Definition Wiring.hpp:271
std::function< Vruta::SoundRoutine()> SoundFactory
Definition Wiring.hpp:44
Fluent builder that wires an entity into Fabric's scheduling infrastructure.
Definition Wiring.hpp:41
Coroutine resumed by more than one clock.
Definition Routine.hpp:642
Base for event filters used by EventSources to match signals to awaiters.
Abstract base for all awaitable signal sources.
Coroutine type for event-driven suspension.
Definition Event.hpp:26
A C++20 coroutine-based graphics processing task with frame-accurate timing.
Definition Routine.hpp:496
Awaitable broadcast message stream for a network endpoint.
A C++20 coroutine-based audio processing task with sample-accurate timing.
Definition Routine.hpp:316
Token-based multimodal task scheduling system for unified coroutine processing.
Definition Scheduler.hpp:51
Awaitable stream of GLFW window input events.
MouseButtons
Enumeration for mouse buttons.
Definition Keys.hpp:147
std::shared_ptr< Core::Window > window
Definition Wiring.hpp:243
std::optional< std::function< void()> > on_release
Definition Wiring.hpp:245
std::optional< std::function< void(double, double)> > on_release
Definition Wiring.hpp:252
std::shared_ptr< Core::Window > window
Definition Wiring.hpp:250
Filter criteria for GLFW window input events.