Refactoring Application, removing singelton to make it namespace, cleaner and easier to access

This commit is contained in:
Chewico 2025-05-21 19:29:16 +02:00
parent 00fc2aff1c
commit bea9a56354
10 changed files with 282 additions and 42 deletions

View File

@ -25,6 +25,27 @@ namespace Deer {
float m_time;
};
namespace Application_tmp {
using Function = void(*)();
using EventFunction = void(*)(Event&);
extern bool running;
void run();
void setTickCallback(Function);
#ifdef DEER_RENDER
void initWindow();
void shutdownWindow();
void setRenderCallback(Function);
void setEventCallback(EventFunction);
Window& getWindow();
#endif
}
class Application {
public:
Application();

View File

@ -0,0 +1,118 @@
#include "Deer/Application.h"
#include <functional>
#include <thread>
#ifdef DEER_RENDER
#include "DeerRender/Render/RenderCommand.h"
#include "DeerRender/Render/RenderUtils.h"
#include "DeerRender/Render/Render.h"
#include "DeerRender/ImGui/ImGuiLayer.h"
#include "imgui.h"
#endif
namespace Deer {
namespace Application_tmp {
Function tickCallback;
bool running;
const double targetUpdateTime = 1.0 / 60.0; // Fixed 60 FPS update
double targetRenderTime = 1.0 / 160.0; // User-defined render FPS
#ifdef DEER_RENDER
Function renderCallback;
EventFunction eventCallback;
Scope<Window> window;
Scope<ImGuiLayer> imGuiLayer;
#endif
void setTickCallback(Function _tick) {
tickCallback = _tick;
}
#ifdef DEER_RENDER
void setRenderCallback(Function _render) {
renderCallback = _render;
}
void setEventCallback(EventFunction _event) {
eventCallback = _event;
}
Window& getWindow() {
return *window;
}
void initWindow() {
window = Scope<Window>(Window::create());
imGuiLayer = MakeScope<ImGuiLayer>();
window->initWindow();
imGuiLayer->onAttach();
if (eventCallback)
window->setEventCallback(eventCallback);
RenderUtils::initializeRenderUtils();
RenderCommand::init();
}
void shutdownWindow() {
imGuiLayer->onDetach();
window.reset();
imGuiLayer.reset();
}
#endif
void run() {
running = true;
auto previousTime = std::chrono::high_resolution_clock::now();
double accumulatedUpdateTime = 0.0;
double accumulatedRenderTime = 0.0;
while (running) {
// Time handling
auto currentTime = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> deltaTime = currentTime - previousTime;
previousTime = currentTime;
accumulatedUpdateTime += deltaTime.count();
accumulatedRenderTime += deltaTime.count();
// Fixed Update loop (60 FPS)
while (accumulatedUpdateTime >= targetUpdateTime) {
Timestep timestep = (float)targetUpdateTime;
accumulatedUpdateTime -= targetUpdateTime;
if (tickCallback)
tickCallback();
}
#ifdef DEER_RENDER
// Render loop (User-defined FPS)
if (accumulatedRenderTime >= targetRenderTime && tickCallback) {
RenderCommand::setClearColor({ 0.2f, 0.2f, 0.3f, 1.0f });
RenderCommand::clear();
ImGuiIO& io = ImGui::GetIO();
io.DeltaTime = (float)targetRenderTime;
imGuiLayer->begin();
tickCallback();
imGuiLayer->end();
accumulatedRenderTime -= targetRenderTime;
}
window->resolveEvents();
#endif
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
}
}

View File

@ -45,7 +45,6 @@ namespace Deer {
}
void ImGuiLayer::end() {
RenderCommand::unbindFrameBuffer();
ImGui::EndFrame();

View File

@ -1,46 +1,13 @@
#pragma once
#include "Deer/EntryPoint.h"
#include "Deer/Application.h"
#include "DeerRender/Events/Event.h"
#include "DeerStudio/Editor/ActiveEntity.h"
#include "DeerStudio/Editor/EditorPanel.h"
#include <vector>
class asIScriptEngine;
class asIScriptObject;
class asIScriptModule;
class asIScriptContext;
int main(int, char**);
namespace Deer {
class DeerStudioApplication : public Deer::Application {
public:
DeerStudioApplication()
: Application(Deer::WindowProps("Deer Studio")) { }
private:
int originEntity, dirEntity, hitEntity;
private:
int onPreInit() override;
int onInit() override;
void onShutdown() override;
void onRender(Timestep delta) override;
void onUpdate(Timestep delta) override;
void onEvent(Event& e) override;
void onImGUI() override;
void drawMenuBar();
void onChangeScene();
namespace DeerStudio {
void onRender(Timestep delta);
void onUpdate(Timestep delta);
std::vector<Ref<EditorPanel>> Panels;
};
void onEvent(Event& e);
}
}
Deer::Application* createApplication(int argc, char** argv) {
Deer::DeerStudioApplication* app = new Deer::DeerStudioApplication();
return app;
}

View File

@ -0,0 +1,109 @@
#include "DeerStudio.h"
#include "DeerStudio/EditorEngine.h"
// TMP
#include "DeerStudio/Editor/Icons.h"
#include "DeerStudio/Fonts.h"
#include "DeerStudio/Style.h"
// TMP
#include "Deer/Application.h"
#include "Deer/Path.h"
#include "Deer/DataStore.h"
#include "Deer/Voxel.h"
int main(int, char**) {
Deer::Path projectPath = Deer::Application_tmp::getWindow().folderDialog(nullptr);
if (projectPath.empty()) return 0;
Deer::DataStore::rootPath = projectPath;
Deer::DataStore::loadVoxelsData();
Deer::DataStore::loadVoxelsAspect();
Deer::Application_tmp::initWindow();
Deer::DataStore::generateTextureAtlas();
Deer::DataStore::loadVoxelsShaders();
Deer::EditorEngine::initialize();
Deer::Icons::setupIcons();
Deer::initializeFonts();
SetupImGuiStyle();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20));
Deer::Application_tmp::run();
Deer::EditorEngine::deinitialize();
}
namespace Deer {
namespace DeerStudio {
void onUpdate() {
if (Scene::getExecutingState())
Scene::tickExecution();
if (VoxelWorld::isInitialized())
VoxelWorld::bakeNextChunk();
}
void onRender() {
static bool opt_fullscreen = true;
static bool opt_padding = false;
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
ImGuiWindowFlags window_flags =
ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
{
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
ImGui::SetNextWindowSize(viewport->WorkSize);
ImGui::SetNextWindowViewport(viewport->ID);
window_flags |= ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus |
ImGuiWindowFlags_NoNavFocus;
window_flags |= ImGuiWindowFlags_NoBackground;
}
static bool p_open = true;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::Begin("DockSpace Demo", &p_open, window_flags);
ImGui::PopStyleVar();
ImGui::PopStyleVar(2);
ImGuiID dockspace_id = ImGui::GetID("DockSpace Demo");
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
if (ImGui::BeginMenuBar()) {
drawMenuBar();
ImGui::EndMenuBar();
}
for (auto Panel : Panels) {
Panel->onImGui();
}
// ---- PanelS -----
TerrainEditor::onImGui();
viewport_onImGui();
EditorEngine::render();
// ---- PanelS -----
Scene::gizmoRenderer.refresh();
ImGui::End();
}
void onEvent(Event& e) {
viewport_onEvent(e);
}
}
} // namespace Deer

View File

@ -71,6 +71,9 @@ namespace Deer {
int getAvailableSizeX();
int getAvailableSizeY();
float slider(std::string&, float, float, float);
int sliderInt(std::string&, int, int, int);
// Draws a button for a popup menu
bool menuItem(std::string&);

View File

@ -449,6 +449,16 @@ namespace Deer {
return false;
}
float slider(std::string& label, float value, float min, float max) {
ImGui::SliderFloat(label.c_str(), &value, min, max);
return value;
}
int sliderInt(std::string& label, int value, int min, int max) {
ImGui::SliderInt(label.c_str(), &value, min, max);
return value;
}
float getMouseDeltaX() {
ImGuiIO& io = ImGui::GetIO();
return io.MouseDelta.x;

View File

@ -52,6 +52,8 @@ namespace Deer {
REGISTER_GLOBAL_FUNC("int getAvailableSizeX()", getAvailableSizeX);
REGISTER_GLOBAL_FUNC("int getAvailableSizeY()", getAvailableSizeY);
REGISTER_GLOBAL_FUNC("void disablePannelPadding(bool)", disablePannelPadding);
REGISTER_GLOBAL_FUNC("int sliderInt(string&in, int, int, int)", sliderInt);
REGISTER_GLOBAL_FUNC("float slider(string&in, float, float, float)", slider);
scriptEngine->SetDefaultNamespace("");
}

View File

@ -41,7 +41,6 @@ class ViewportPannel : DockPanel {
sceneCamera.transform.position = sceneCamera.transform.relative(panDir);
}
vec3 relDir = vec3();
if (UI::isKeyDown(key::W))
@ -78,7 +77,16 @@ class ViewportPannel : DockPanel {
if (UI::menuItem("Start")) {
}
if (UI::menuItem("Camera Props")) {
UI::openPopup("ViewportCameraProps", any());
}
UI::simplePopup("ViewportCameraProps", ReciverFunc(this.viewportCameraProps));
}
void viewportCameraProps(any@ data) {
sceneCamera.camera.fov = UI::slider("Fov", sceneCamera.camera.fov / 3.14f * 180, 10, 160) / 180 * 3.14f;
}
}

View File

@ -501,5 +501,8 @@ namespace UI {
float getMouseDeltaY();
int getAvailableSizeX();
int getAvailableSizeY();
void disablePannelPadding(bool)
void disablePannelPadding(bool);
int sliderInt(string&in, int value, int min, int max);
float slider(string&in, float value, float min, float max);
}