dreamwell-runtime 1.0.0

Dreamwell Runtime — cross-platform GPU-accelerated game client
Documentation
// Runtime UI — optional egui overlay for debug HUD, console, and dev tools.
// Feature-gated behind `ui`. When disabled, all methods are no-ops.
//
// Usage: create RuntimeUi at startup, call handle_event() in the input phase,
// run() in the render phase, and draw() to get paint jobs.

#[cfg(feature = "ui")]
use egui_winit::EventResponse;

/// Runtime UI state. No-op when `ui` feature is disabled.
pub struct RuntimeUi {
    #[cfg(feature = "ui")]
    ctx: egui::Context,
    #[cfg(feature = "ui")]
    winit_state: Option<egui_winit::State>,
    #[cfg(feature = "ui")]
    renderer: Option<egui_wgpu::Renderer>,
    /// Whether the debug HUD is visible.
    pub hud_visible: bool,
}

impl RuntimeUi {
    /// Create runtime UI. Call after window creation.
    pub fn new() -> Self {
        Self {
            #[cfg(feature = "ui")]
            ctx: egui::Context::default(),
            #[cfg(feature = "ui")]
            winit_state: None,
            #[cfg(feature = "ui")]
            renderer: None,
            hud_visible: false,
        }
    }

    /// Initialize egui integration with the window and device.
    #[cfg(feature = "ui")]
    pub fn init(&mut self, window: &winit::window::Window, device: &wgpu::Device, surface_format: wgpu::TextureFormat) {
        let viewport_id = self.ctx.viewport_id();
        self.winit_state = Some(egui_winit::State::new(
            self.ctx.clone(),
            viewport_id,
            window,
            None,
            None,
            None,
        ));
        self.renderer = Some(egui_wgpu::Renderer::new(device, surface_format, None, 1, false));
    }

    /// Handle a winit event. Returns true if egui consumed the event.
    #[cfg(feature = "ui")]
    pub fn handle_event(&mut self, window: &winit::window::Window, event: &winit::event::WindowEvent) -> bool {
        if let Some(ref mut state) = self.winit_state {
            let response = state.on_window_event(window, event);
            response.consumed
        } else {
            false
        }
    }

    /// Handle a winit event (no-op when feature disabled).
    #[cfg(not(feature = "ui"))]
    pub fn handle_event(&mut self, _window: &winit::window::Window, _event: &winit::event::WindowEvent) -> bool {
        false
    }

    /// Toggle HUD visibility (bound to F3).
    pub fn toggle_hud(&mut self) {
        self.hud_visible = !self.hud_visible;
    }
}

impl Default for RuntimeUi {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn runtime_ui_default() {
        let ui = RuntimeUi::new();
        assert!(!ui.hud_visible);
    }

    #[test]
    fn toggle_hud() {
        let mut ui = RuntimeUi::new();
        ui.toggle_hud();
        assert!(ui.hud_visible);
        ui.toggle_hud();
        assert!(!ui.hud_visible);
    }
}