Apply the configured wiring.
Resolves the builder state into a coroutine (if any scheduling modifier was set) or an immediate call (if bind was used), and registers the result with Fabric.
234{
239
240 bool has_any_path = !std::holds_alternative<std::monostate>(
m_factory)
244 || !std::holds_alternative<std::monostate>(
m_trigger)
246
247 reg.commit_driven = !has_any_path;
248
249
250
251
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()));
258 }
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()));
263 }
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()));
268 }
269 if (!ptr->perception_fn_name().empty()) {
271 ptr->perception_fn_name(), std::make_shared<Sensor::PerceptionFn>(ptr->perception_fn()));
272 }
273 }
274 },
275 reg.member);
276
277
278
279
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>) {
286 scheduler.add_task(
287 std::make_shared<std::invoke_result_t<F, Vruta::TaskScheduler&>>(
factory(scheduler)),
288 name, false);
289 }
290 },
293 return;
294 }
295
296
297
298
301 reg.event_name = name;
302 ev_manager.add_event(
304 name);
306 return;
307 }
308
309
310
311
313 (*m_bind_attach)();
314
316 auto timer = std::make_shared<Kriya::Timer>(scheduler);
318 timer->schedule(*
m_duration, [timer, detach]() {
319 detach();
320 });
321 }
323 return;
324 }
325
326
327
328
331 reg.chain_name = name;
332
333 Kriya::EventChain
chain(scheduler, 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);
340 },
341 fab.m_registrations[
id].member);
342 fab.fire(id);
343 },
344 step.delay_seconds);
345 }
348 }
351 return;
352 }
353
354
355
356
357 if (!std::holds_alternative<std::monostate>(
m_trigger)) {
358 std::visit([&](auto& trig) {
359 using T = std::decay_t<
decltype(trig)>;
360
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); })),
369 name);
370
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); })),
378 name);
379
380 } else if constexpr (std::is_same_v<T, NetworkTrigger>) {
382 reg.task_name = name;
383 scheduler.add_task(
384 std::make_shared<Vruta::SoundRoutine>(
385 network_loop(*trig.source,
m_fabric,
id)),
386 name, false);
387
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)),
394 name);
395 }
396 },
399 return;
400 }
401
402
403
404
408 reg.task_name = name;
410
411 scheduler.add_task(
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);
418 },
419 fab.m_registrations[id].member);
420 }
421 fab.fire(id);
422 })),
423 name, false);
424
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);
430 });
431 }
432 }
433
435}
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
std::optional< std::function< void()> > m_bind_detach
std::string make_name(const char *prefix) const
std::optional< std::function< void()> > m_bind_attach
std::optional< double > m_duration
std::optional< double > m_interval
const Factory & factory() const
Active factory variant set by use for non-Event factories.
std::vector< MoveStep > m_move_steps
std::optional< PositionFn > m_position_fn
Tendency< A, C > chain(const Tendency< A, B > &first, const Tendency< B, C > &second)
Sequential composition: evaluate first, feed result into second.
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.