45 std::function<
void()> on_release)
48 .
window = std::move(window),
50 .on_release = on_release ? std::optional<std::function<void()>>(std::move(on_release)) : std::nullopt,
65 .
window = std::move(window),
67 .on_release = on_release ? std::optional<std::function<void(
double,
double)>>(std::move(on_release)) : std::nullopt,
75 std::function<
void(
double,
double)> on_release)
78 .
window = std::move(window),
80 .on_release = std::move(on_release)
98 std::function<
void(
double,
double)> fn)
106 m_move_steps.push_back({ .position = pos, .delay_seconds = delay_seconds });
212 std::string attach_name, std::function<
void()> attach,
213 std::string detach_name, std::function<
void()> detach)
244 if (promise.should_terminate) {
247 co_await source.next_message();
252 Vruta::Event scroll_loop(
253 std::shared_ptr<Core::Window> window,
254 std::function<
void(
double,
double)> fn)
256 auto& promise =
co_await Kriya::GetEventPromise {};
257 auto&
source = window->get_event_source();
259 Vruta::WindowEventFilter filter;
263 if (promise.should_terminate)
265 auto event =
co_await Kriya::WindowEventAwaiter(source, filter);
266 if (
auto* sd = std::get_if<Core::WindowEvent::ScrollData>(&event.data))
267 fn(sd->x_offset, sd->y_offset);
283 bool has_any_path = !std::holds_alternative<std::monostate>(
m_factory)
287 || !std::holds_alternative<std::monostate>(
m_trigger)
290 reg.commit_driven = !has_any_path;
295 std::visit([&](
const auto&
ptr) {
296 using T = std::decay_t<
decltype(*ptr)>;
297 if constexpr (std::is_same_v<T, Emitter>) {
298 if (!
ptr->fn_name().empty()) {
300 ptr->fn_name(), std::make_shared<Emitter::InfluenceFn>(
ptr->fn()));
302 }
else if constexpr (std::is_same_v<T, Sensor>) {
303 if (!
ptr->fn_name().empty()) {
305 ptr->fn_name(), std::make_shared<Sensor::PerceptionFn>(
ptr->fn()));
307 }
else if constexpr (std::is_same_v<T, Agent>) {
308 if (!
ptr->influence_fn_name().empty()) {
310 ptr->influence_fn_name(), std::make_shared<Emitter::InfluenceFn>(
ptr->influence_fn()));
312 if (!
ptr->perception_fn_name().empty()) {
314 ptr->perception_fn_name(), std::make_shared<Sensor::PerceptionFn>(
ptr->perception_fn()));
323 if (!std::holds_alternative<std::monostate>(
m_factory)) {
325 reg.task_name = name;
326 std::visit([&](
auto&
factory) {
327 using F = std::decay_t<
decltype(
factory)>;
328 if constexpr (!std::is_same_v<F, std::monostate>) {
330 std::make_shared<std::invoke_result_t<F>>(
factory()),
344 reg.event_name = name;
345 ev_manager.add_event(
361 timer->schedule(*
m_duration, [timer, detach]() {
374 reg.chain_name = name;
379 glm::vec3 pos = step.position;
380 chain.then([&fab, pos,
id]() {
381 std::visit([&pos](
const auto&
ptr) {
382 ptr->set_position(pos);
384 fab.m_registrations[id].member);
400 if (!std::holds_alternative<std::monostate>(
m_trigger)) {
401 std::visit([&](
auto& trig) {
402 using T = std::decay_t<
decltype(trig)>;
404 if constexpr (std::is_same_v<T, KeyTrigger>) {
406 reg.event_name = name;
408 ev_manager.add_event(
409 std::make_shared<Vruta::Event>(
412 [&fab,
id]() { fab.fire(id); })
414 [&fab,
id]() { fab.fire(id); })),
417 if (trig.on_release) {
418 auto release_name =
make_name(
"nexus_event_release");
419 reg.chain_name = release_name;
420 ev_manager.add_event(
421 std::make_shared<Vruta::Event>(
426 }
else if constexpr (std::is_same_v<T, MouseTrigger>) {
428 reg.event_name = name;
431 ev_manager.add_event(
432 std::make_shared<Vruta::Event>(
435 [&fab, eid](
double px,
double py) {
436 fab.m_registrations[eid].pending_cursor = glm::vec2(px, py);
440 [&fab, eid](
double px,
double py) {
441 fab.m_registrations[eid].pending_cursor = glm::vec2(px, py);
445 if (trig.on_release) {
446 auto release_name =
make_name(
"nexus_event_release");
447 reg.chain_name = release_name;
448 ev_manager.add_event(
449 std::make_shared<Vruta::Event>(
454 }
else if constexpr (std::is_same_v<T, ScrollTrigger>) {
456 reg.event_name = name;
457 ev_manager.add_event(
458 std::make_shared<Vruta::Event>(
459 scroll_loop(trig.window, trig.fn)),
462 }
else if constexpr (std::is_same_v<T, NetworkTrigger>) {
464 reg.task_name = name;
466 std::make_shared<Vruta::SoundRoutine>(
467 network_loop(*trig.source,
m_fabric,
id)),
470 }
else if constexpr (std::is_same_v<T, WindowEventTrigger>) {
472 reg.event_name = name;
474 ev_manager.add_event(
475 std::make_shared<Vruta::Event>(
491 reg.task_name = name;
496 if (pos_fn.has_value()) {
497 glm::vec3 p = (*pos_fn)();
498 std::visit([&p](const auto& ptr) {
499 ptr->set_position(p);
501 fab.m_registrations[
id].member);
506 auto cancel_name =
make_name(
"nexus_metro_cancel");
507 auto timer = std::make_shared<Kriya::Timer>(scheduler);
508 timer->schedule(*
m_duration, [name, timer, &scheduler]() {
509 scheduler.cancel_task(name);
514 m_fabric.m_registrations[m_entity_id].wiring.emplace(std::move(*
this));
523 auto& reg = m_fabric.m_registrations[m_entity_id];
525 if (!reg.task_name.empty()) {
526 m_fabric.m_scheduler.cancel_task(reg.task_name);
527 reg.task_name.clear();
529 if (!reg.chain_name.empty()) {
530 m_fabric.m_scheduler.cancel_task(reg.chain_name);
531 reg.chain_name.clear();
533 if (!reg.event_name.empty()) {
534 m_fabric.m_event_manager.cancel_event(reg.event_name);
535 reg.event_name.clear();
538 if (m_bind_detach.has_value()) {
555 if (promise.should_terminate)
558 if (
auto* pos = std::get_if<Core::WindowEvent::MousePosData>(&event.data))
A sequential chain of timed events with precise temporal control.
Awaiter for suspending on GLFW window input events with optional filtering.
void fire(uint32_t id)
Fire a single object against the current snapshot without republishing.
std::unordered_map< std::string, std::shared_ptr< Sensor::PerceptionFn > > m_perception_fns
Vruta::TaskScheduler & m_scheduler
std::unordered_map< uint32_t, Registration > m_registrations
std::unordered_map< std::string, std::shared_ptr< Emitter::InfluenceFn > > m_influence_fns
Vruta::EventManager & m_event_manager
Orchestrates spatial indexing and scheduling for Nexus objects.
std::optional< std::function< void()> > m_bind_detach
Wiring & position_from(PositionFn fn)
Drive position from a callable evaluated on each every() tick.
std::string m_position_fn_name
Vruta::Event window_event_source_loop(Vruta::WindowEventSource &source, Vruta::WindowEventFilter filter, Fabric &fabric, uint32_t id)
std::string make_name(const char *prefix) const
Wiring & use(SoundFactory factory)
Delegate coroutine creation entirely to the caller.
Wiring & on_scroll(std::shared_ptr< Core::Window > window, std::function< void(double, double)> fn)
Fire the entity on each mouse scroll event from a window.
std::function< Vruta::CrossRoutine()> CrossFactory
std::string m_bind_attach_name
Wiring & on(std::shared_ptr< Core::Window > window, IO::Keys key)
Fire the entity on a key event from a window.
std::function< glm::vec3()> PositionFn
std::optional< std::function< void()> > m_bind_attach
std::optional< double > m_duration
Vruta::ProcessingToken m_metro_token
Wiring & every(double interval_seconds, Vruta::ProcessingToken token=Vruta::ProcessingToken::SAMPLE_ACCURATE)
Fire the entity on a recurring interval.
Wiring & times(size_t count)
Repeat the configured sequence or choreography N times.
Wiring & move_to(const glm::vec3 &pos, double delay_seconds=0.0)
Choreograph a position move as an EventChain step.
std::function< Vruta::GraphicsRoutine()> GraphicsFactory
std::function< Vruta::Event(Vruta::TaskScheduler &)> EventFactory
Vruta::ProcessingToken m_duration_token
std::optional< double > m_interval
const Factory & factory() const
Active factory variant set by use for non-Event factories.
std::string m_bind_detach_name
Wiring & for_duration(double seconds, Vruta::ProcessingToken token=Vruta::ProcessingToken::SAMPLE_ACCURATE)
Limit a recurring registration to a fixed duration then cancel.
std::vector< MoveStep > m_move_steps
std::string m_factory_name
std::optional< PositionFn > m_position_fn
void finalise()
Apply the configured wiring.
Wiring & bind()
Call the entity's influence function once immediately.
std::function< Vruta::SoundRoutine()> SoundFactory
Fluent builder that wires an entity into Fabric's scheduling infrastructure.
Coroutine type for event-driven suspension.
Awaitable broadcast message stream for a network endpoint.
A C++20 coroutine-based audio processing task with sample-accurate timing.
uint64_t get_next_task_id() const
Generates a unique task ID for new tasks.
Awaitable stream of GLFW window input events.
MouseButtons
Enumeration for mouse buttons.
Vruta::Event key_released(std::shared_ptr< Core::Window > window, IO::Keys key, std::function< void()> callback)
Creates an Event coroutine that triggers on specific key release.
Vruta::Event key_pressed(std::shared_ptr< Core::Window > window, IO::Keys key, std::function< void()> callback)
Creates an Event coroutine that triggers on specific key press.
Vruta::Event key_held(std::shared_ptr< Core::Window > window, IO::Keys key, std::function< void()> callback)
Creates an Event coroutine that triggers on key press and repeats while held.
Vruta::Event mouse_released(std::shared_ptr< Core::Window > window, IO::MouseButtons button, std::function< void(double, double)> callback)
Creates an Event coroutine that triggers on specific mouse button release.
Vruta::Event mouse_pressed(std::shared_ptr< Core::Window > window, IO::MouseButtons button, std::function< void(double, double)> callback)
Creates an Event coroutine that triggers on specific mouse button press.
Vruta::Event mouse_dragged(std::shared_ptr< Core::Window > window, IO::MouseButtons button, std::function< void(double, double)> callback)
Creates an Event coroutine that triggers on mouse drag with specific button.
std::shared_ptr< Vruta::Routine > metro(double interval_seconds, std::function< void()> callback, Vruta::ProcessingToken token)
Creates a periodic event generator that executes a callback at regular intervals.
Event-domain promise accessor with optional NetworkSource ownership transfer.
Templated awaitable for accessing a coroutine's promise object.
std::shared_ptr< Core::Window > window
std::shared_ptr< Core::Window > window
Vruta::NetworkSource * source
Vruta::WindowEventSource * source
Filter criteria for GLFW window input events.