原设计 OnRender() 既承载默认渲染又是虚钩子,派生类一 override 主渲染就丢失(钩子语义与框架行为耦合)。现在 Run() 固定调 Renderer.Render(scene),OnRenderOverlay() 只做叠加层(ImGui/ 调试视图/编辑器 UI),不覆写则无叠加层——runtime 零渲染代码, editor 扩展不破坏主渲染。
106 lines
3.9 KiB
C++
106 lines
3.9 KiB
C++
//
|
||
// Created by atdunbg on 2026/9/22.
|
||
//
|
||
// Application:程序生命周期基类。
|
||
//
|
||
// 分层目标:main 不再知道 Window/Renderer 的存在——
|
||
// main 只 new 一个派生类并 Run();
|
||
// 派生类通过生命周期钩子(OnInit/OnUpdate/OnRenderOverlay/OnShutdown)
|
||
// 和事件钩子(OnEvent + 类型化事件)定义程序行为;
|
||
// runtime、editor 等不同程序形态只是不同的派生类。
|
||
//
|
||
// 主循环固定为:PollEvents → OnUpdate(dt) → [主渲染 → OnRenderOverlay] → 判退出。
|
||
// 主渲染(Renderer.Render(scene))是框架行为,派生类不可覆盖也不会丢失;
|
||
// 派生类的渲染扩展(ImGui/调试视图/编辑器叠加层)走 OnRenderOverlay,
|
||
// 在主渲染之后、Present 之前执行,不覆写则什么都不发生。
|
||
// dt 由框架统一计时(含首帧与卡顿钳制),派生层无需自己管理。
|
||
//
|
||
|
||
#ifndef HELLOVULKAN_APPLICATION_H
|
||
#define HELLOVULKAN_APPLICATION_H
|
||
|
||
#include <Engine/Core/Types.h>
|
||
#include <Engine/Core/Event.h>
|
||
#include <chrono>
|
||
#include <string>
|
||
|
||
namespace Engine {
|
||
|
||
class Window;
|
||
class Renderer;
|
||
|
||
namespace ECS { class Scene; }
|
||
namespace Assets { class AssetManager; }
|
||
|
||
class Application {
|
||
public:
|
||
Application(std::string title, u32 width, u32 height);
|
||
virtual ~Application();
|
||
|
||
Application(const Application&) = delete;
|
||
Application& operator=(const Application&) = delete;
|
||
|
||
// 进入主循环(阻塞直到 Close() 或窗口关闭)
|
||
void Run();
|
||
|
||
// 请求退出(当帧结束后生效)
|
||
void Close() { m_Running = false; }
|
||
|
||
// ---- 供派生类访问的模块 ----
|
||
Window& GetWindow() const { return *m_Window; }
|
||
Renderer& GetRenderer() const { return *m_Renderer; }
|
||
ECS::Scene& GetScene() const { return *m_Scene; }
|
||
Assets::AssetManager& GetAssets() const { return *m_Assets; }
|
||
f32 GetDeltaTime() const { return m_DeltaTime; }
|
||
u64 GetFrameCount() const { return m_FrameCount; }
|
||
|
||
protected:
|
||
// ---- 生命周期钩子 ----
|
||
|
||
// 框架装配完成(Window/Renderer 可用),派生类做初始化(建场景等)
|
||
virtual void OnInit() {}
|
||
|
||
// 每帧逻辑更新(输入、动画、物理……)
|
||
virtual void OnUpdate(f32 deltaTime) {}
|
||
|
||
// 主渲染之后、当帧提交之前的叠加层钩子(ImGui/调试视图/编辑器 UI)。
|
||
// 主渲染由框架固定执行;这里只负责"额外的"渲染,不覆写则无叠加层。
|
||
virtual void OnRenderOverlay() {}
|
||
|
||
// 主循环结束后、析构前(保存、清理场景等)
|
||
virtual void OnShutdown() {}
|
||
|
||
// ---- 事件钩子 ----
|
||
// OnEvent 收到所有事件(原始入口,适合做全局日志/拦截);
|
||
// 类型化钩子按事件类型分别回调,派生类按需覆写。
|
||
virtual void OnEvent(const Event& event) {}
|
||
virtual void OnWindowClose(const Event& event);
|
||
virtual void OnWindowResize(const Event& event) {}
|
||
virtual void OnWindowFocus(const Event& event) {}
|
||
virtual void OnWindowLostFocus(const Event& event) {}
|
||
virtual void OnKeyPress(const Event& event) {}
|
||
virtual void OnKeyRelease(const Event& event) {}
|
||
virtual void OnMouseButtonPress(const Event& event) {}
|
||
virtual void OnMouseButtonRelease(const Event& event) {}
|
||
virtual void OnMouseMove(const Event& event) {}
|
||
virtual void OnMouseScroll(const Event& event) {}
|
||
|
||
private:
|
||
void DispatchEvent(const Event& event);
|
||
|
||
Scope<Window> m_Window;
|
||
Scope<ECS::Scene> m_Scene;
|
||
Scope<Renderer> m_Renderer;
|
||
Scope<Assets::AssetManager> m_Assets;
|
||
|
||
bool m_Running = false;
|
||
f32 m_DeltaTime = 0.0f;
|
||
u64 m_FrameCount = 0;
|
||
|
||
std::chrono::steady_clock::time_point m_LastFrameTime;
|
||
};
|
||
|
||
} // namespace Engine
|
||
|
||
#endif //HELLOVULKAN_APPLICATION_H
|