#pragma once #include "memory.h" #include "window.h" #include "event.h" #include "log.h" #include "rendering/rhi.h" #include "rendering/render_path.h" #include "rendering/view.h" #include "scene/scene.h" #include "ui/ui_layer.h" #include namespace Donut { // thin shell: owns the window, the RHI device, the Scene (document), the // RenderPath (device-side rendering) and the UILayer (docking UI), and runs // the frame loop that wires them together. all the rendering lives in the // RHI + shared renderers; all the editing lives in the Scene + UI panels. class Application : public AppActions { public: Application(const std::string& name = "Donut", int width = 1280, int height = 720); ~Application(); auto run() -> void; auto close() -> void; auto get_window() -> Window& { return *m_window; } static auto get() -> Application& { return *s_instance; } // AppActions — window/device changes requested by the Settings panel. auto set_resolution(int w, int h) -> void override; auto set_fullscreen(bool on) -> void override; auto set_vsync(bool on) -> void override; auto set_ui_scale(float scale) -> void override; auto get_window_size(int& w, int& h) const -> void override; auto is_fullscreen() const -> bool override; auto export_frame(const ExportConfig& cfg) -> int override; private: auto on_init() -> void; auto on_shutdown() -> void; auto on_event(Event& event) -> void; auto render_frame() -> void; auto update_input(View view) -> void; // orbit / free-fly / zoom for the active camera private: Scope m_window; Scope m_device; Scope m_scene; Scope m_render_path; Scope m_ui; // input tracking (per-frame transient state) bool m_left_was_down = false; double m_fps_last_x = 0.0, m_fps_last_y = 0.0; double m_last_frame_time = 0.0; double m_start_time = 0.0; bool m_user_moving = false; // windowed-mode geometry saved across a fullscreen toggle int m_windowed_x = 100, m_windowed_y = 100, m_windowed_w = 1280, m_windowed_h = 720; bool m_running = true; bool m_minimized = false; static Application* s_instance; }; }