168 std::string attach_name, std::function<
void()> attach,
169 std::string detach_name, std::function<
void()> detach)
200 if (promise.should_terminate) {
212 Vruta::Event event_source_loop(
213 Vruta::EventSource& source,
217 auto& promise =
co_await Kriya::GetEventPromise {};
219 if (promise.should_terminate) {
222 co_await source.next_event();
240 bool has_any_path = !std::holds_alternative<std::monostate>(
m_factory)
244 || !std::holds_alternative<std::monostate>(
m_trigger)
247 reg.commit_driven = !has_any_path;
252 std::visit([&](
const auto& ptr) {
253 using T = std::decay_t<
decltype(*ptr)>;
254 if constexpr (std::is_same_v<T, Emitter>) {
255 if (!ptr->fn_name().empty()) {
257 ptr->fn_name(), std::make_shared<Emitter::InfluenceFn>(ptr->fn()));
259 }
else if constexpr (std::is_same_v<T, Sensor>) {
260 if (!ptr->fn_name().empty()) {
262 ptr->fn_name(), std::make_shared<Sensor::PerceptionFn>(ptr->fn()));
264 }
else if constexpr (std::is_same_v<T, Agent>) {
265 if (!ptr->influence_fn_name().empty()) {
267 ptr->influence_fn_name(), std::make_shared<Emitter::InfluenceFn>(ptr->influence_fn()));
269 if (!ptr->perception_fn_name().empty()) {
271 ptr->perception_fn_name(), std::make_shared<Sensor::PerceptionFn>(ptr->perception_fn()));
280 if (!std::holds_alternative<std::monostate>(
m_factory)) {
282 reg.task_name = name;
283 std::visit([&](
auto&
factory) {
284 using F = std::decay_t<
decltype(
factory)>;
285 if constexpr (!std::is_same_v<F, std::monostate>) {
287 std::make_shared<std::invoke_result_t<F, Vruta::TaskScheduler&>>(
factory(scheduler)),
301 reg.event_name = name;
302 ev_manager.add_event(
316 auto timer = std::make_shared<Kriya::Timer>(scheduler);
318 timer->schedule(*
m_duration, [timer, detach]() {
331 reg.chain_name = name;
336 glm::vec3 pos = step.position;
337 chain.then([&fab, pos,
id]() {
338 std::visit([&pos](
const auto& ptr) {
339 ptr->set_position(pos);
341 fab.m_registrations[
id].member);
357 if (!std::holds_alternative<std::monostate>(
m_trigger)) {
358 std::visit([&](
auto& trig) {
359 using T = std::decay_t<
decltype(trig)>;
361 if constexpr (std::is_same_v<T, KeyTrigger>) {
363 reg.event_name = name;
365 ev_manager.add_event(
366 std::make_shared<Vruta::Event>(
368 [&fab,
id]() { fab.fire(id); })),
371 }
else if constexpr (std::is_same_v<T, MouseTrigger>) {
373 reg.event_name = name;
374 ev_manager.add_event(
375 std::make_shared<Vruta::Event>(
377 [
this,
id](
double,
double) { m_fabric.fire(id); })),
380 }
else if constexpr (std::is_same_v<T, NetworkTrigger>) {
382 reg.task_name = name;
384 std::make_shared<Vruta::SoundRoutine>(
385 network_loop(*trig.source,
m_fabric,
id)),
388 }
else if constexpr (std::is_same_v<T, EventTrigger>) {
390 reg.event_name = name;
391 ev_manager.add_event(
392 std::make_shared<Vruta::Event>(
393 event_source_loop(*trig.source,
m_fabric,
id)),
408 reg.task_name = name;
412 std::make_shared<Vruta::SoundRoutine>(
414 if (pos_fn.has_value()) {
415 glm::vec3 p = (*pos_fn)();
416 std::visit([&p](const auto& ptr) {
417 ptr->set_position(p);
419 fab.m_registrations[
id].member);
426 auto cancel_name =
make_name(
"nexus_metro_cancel");
427 auto timer = std::make_shared<Kriya::Timer>(scheduler);
428 timer->schedule(*
m_duration, [name, timer, &scheduler]() {
429 scheduler.cancel_task(name);
434 m_fabric.m_registrations[m_entity_id].wiring.emplace(std::move(*
this));
443 auto& reg = m_fabric.m_registrations[m_entity_id];
445 if (!reg.task_name.empty()) {
446 m_fabric.m_scheduler.cancel_task(reg.task_name);
447 reg.task_name.clear();
449 if (!reg.chain_name.empty()) {
450 m_fabric.m_scheduler.cancel_task(reg.chain_name);
451 reg.chain_name.clear();
453 if (!reg.event_name.empty()) {
454 m_fabric.m_event_manager.cancel_event(reg.event_name);
455 reg.event_name.clear();
458 if (m_bind_detach.has_value()) {
A sequential chain of timed events with precise temporal control.
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
std::string make_name(const char *prefix) const
Wiring & use(SoundFactory factory)
Delegate coroutine creation entirely to the caller.
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.
Wiring & for_duration(double seconds)
Limit a recurring registration to a fixed duration then cancel.
std::function< glm::vec3()> PositionFn
std::optional< std::function< void()> > m_bind_attach
std::optional< double > m_duration
std::function< Vruta::ComplexRoutine(Vruta::TaskScheduler &)> ComplexFactory
std::function< Vruta::GraphicsRoutine(Vruta::TaskScheduler &)> GraphicsFactory
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::Event(Vruta::TaskScheduler &)> EventFactory
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
std::vector< MoveStep > m_move_steps
std::string m_factory_name
std::function< Vruta::SoundRoutine(Vruta::TaskScheduler &)> SoundFactory
std::optional< PositionFn > m_position_fn
void finalise()
Apply the configured wiring.
Wiring & bind()
Call the entity's influence function once immediately.
Wiring & every(double interval_seconds)
Fire the entity on a recurring interval.
Fluent builder that wires an entity into Fabric's scheduling infrastructure.
Awaitable event stream for window events.
Kriya::NetworkAwaiter next_message()
Create an awaiter for the next message.
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.
MouseButtons
Enumeration for mouse buttons.
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 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::SoundRoutine metro(Vruta::TaskScheduler &scheduler, double interval_seconds, std::function< void()> callback)
Creates a periodic event generator that executes a callback at regular intervals.
Templated awaitable for accessing a coroutine's promise object.
Vruta::EventSource * source
std::shared_ptr< Core::Window > window
std::shared_ptr< Core::Window > window
Vruta::NetworkSource * source
Filter criteria for window events.