-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Open
Copy link
Labels
enhancementNew feature or requestNew feature or request
Description
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-238
pub fn run_forever<Callback>(self, mut callback: Callback)
where
Callback: 'static + FnMut(Event<E>, &EventLoopWindowTarget<E>),
{
self
.event_loop
.run(move |event, target| {
target.set_control_flow(ControlFlow::Poll); // Always polling
callback(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, andWaitUntil(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 loop
pub enum EventLoopPolicy {
/// Continuous polling for games and real-time applications
Poll,
/// Wait for events, ideal for tools and editors
Wait,
/// Wait until next frame time for fixed-rate rendering
WaitUntil { target_fps: u32 },
}
// In runtime/application builder:
impl RuntimeBuilder {
/// 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 rate
pub fn with_event_loop_policy(self, policy: EventLoopPolicy) -> Self;
}
// Runtime can expose a method to change policy dynamically:
impl Runtime {
/// Signal whether the application is currently animating.
/// When true, uses Poll mode; when false, uses Wait mode.
pub fn set_animating(&mut self, 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 rendering
let runtime = RuntimeBuilder::new()
.with_event_loop_policy(EventLoopPolicy::WaitUntil { target_fps: 60 })
.build()?;Acceptance Criteria
-
EventLoopPolicyenum defined withPoll,Wait, andWaitUntilvariants - Builder method
with_event_loop_policyadded 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
Pollfor backward compatibility, orWaitUntil { 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
Labels
enhancementNew feature or requestNew feature or request