Skip to content

[Feature] Add configurable event loop control flow policy to reduce CPU usage when idle #98

Description

@vmarcella

Overview

The event loop is currently forced into ControlFlow::Poll, keeping the CPU hot even when the application is not actively rendering or animating. This issue proposes adding a configurable control flow policy that allows applications to choose between continuous polling (for games/animations) and wait-based modes (for tools/editors) to reduce CPU usage when idle.

Current State

The event loop unconditionally uses polling mode:

// crates/lambda-rs-platform/src/winit/mod.rs:230-238pubfnrun_forever<Callback>(self,mutcallback:Callback)whereCallback:'static + FnMut(Event<E>,&EventLoopWindowTarget<E>),{self.event_loop.run(move |event, target| {
target.set_control_flow(ControlFlow::Poll);// Always pollingcallback(event, target);})}

This means that even when an application is idle (e.g., waiting for user input in a tool or editor), the CPU remains at high utilization spinning through empty event loop iterations.

Scope

Goals:

  • Provide configurable control flow policies: Poll, Wait, and WaitUntil(duration)
  • Allow applications to signal whether they require continuous rendering (animating) or can wait for events
  • Reduce CPU and power consumption for applications that do not need continuous updates

Non-Goals:

  • Automatic detection of animation state (applications must signal intent)
  • Frame pacing or advanced vsync coordination (separate concern)
  • Changing the default behavior for existing applications without opt-in

Proposed API

// crates/lambda-rs-platform/src/winit/mod.rs or appropriate location/// Control flow policy for the event looppubenumEventLoopPolicy{/// Continuous polling for games and real-time applicationsPoll,/// Wait for events, ideal for tools and editorsWait,/// Wait until next frame time for fixed-rate renderingWaitUntil{target_fps:u32},}// In runtime/application builder:implRuntimeBuilder{/// Set the event loop control flow policy./// /// - `Poll`: Continuous updates, high CPU usage, lowest latency/// - `Wait`: Sleep until events arrive, minimal CPU usage/// - `WaitUntil`: Target a specific frame ratepubfnwith_event_loop_policy(self,policy:EventLoopPolicy) -> Self;}// Runtime can expose a method to change policy dynamically:implRuntime{/// Signal whether the application is currently animating./// When true, uses Poll mode; when false, uses Wait mode.pubfnset_animating(&mutself,is_animating:bool);}

Example Usage:

// For a game (continuous rendering)let runtime = RuntimeBuilder::new().with_event_loop_policy(EventLoopPolicy::Poll).build()?;// For an editor (event-driven)let runtime = RuntimeBuilder::new().with_event_loop_policy(EventLoopPolicy::Wait).build()?;// For fixed 60 FPS renderinglet runtime = RuntimeBuilder::new().with_event_loop_policy(EventLoopPolicy::WaitUntil{target_fps:60}).build()?;

Acceptance Criteria

  • EventLoopPolicy enum defined with Poll, Wait, and WaitUntil variants
  • Builder method with_event_loop_policy added to runtime/application builder
  • Event loop respects the configured policy at runtime
  • Optional: Runtime method to dynamically switch between polling and waiting
  • Documentation updated with guidance on when to use each policy
  • Example demonstrating policy configuration added or existing example updated

Affected Crates

lambda-rs-platform, lambda-rs

Notes

  • Consider defaulting to Poll for backward compatibility, or WaitUntil { target_fps: 60 } for better defaults
  • The "is_animating" knob could be a simpler initial implementation before full policy support
  • This is particularly important for laptop/mobile users where CPU usage affects battery life

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestlambda-rsIssues pertaining to the core framework

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions