From 4ecddafcd5ea4aa0da52ce0e2bd402365ed421f5 Mon Sep 17 00:00:00 2001 From: Redacted Date: Wed, 8 Jan 2025 12:23:48 -0500 Subject: [PATCH] Get rid of having to have Globals::CurrentScene everywhere. --- CMakeLists.txt | 2 +- include/Engine/types/Scene.h | 2 +- include/Engine/types/entity/Entity.h | 7 +++- include/Engine/types/entity/Trigger.h | 2 +- src/Engine/types/Scene.cpp | 9 +++++ src/Engine/types/entity/Camera.cpp | 4 +- src/Engine/types/entity/Entity.cpp | 45 ++++++++++++++++----- src/Engine/types/entity/InstancedSprite.cpp | 12 +++--- src/Engine/types/entity/Moby.cpp | 2 + src/Game/Scene/Loading.cpp | 4 +- 10 files changed, 64 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bd2412..39e97f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ CPMAddPackage( URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-26.zip ) -set(CMAKE_CXX_FLAGS "-O3 -Wall -Wextra") +#set(CMAKE_CXX_FLAGS "-O3 -Wall -Wextra") file(GLOB_RECURSE HEADERS "include/*.h" "include/*.hpp") file(GLOB_RECURSE SOURCES "src/*.c" "src/*.cpp") diff --git a/include/Engine/types/Scene.h b/include/Engine/types/Scene.h index 9323945..b9d187f 100644 --- a/include/Engine/types/Scene.h +++ b/include/Engine/types/Scene.h @@ -55,6 +55,6 @@ public: void Render(JGL::RenderTarget* render_target); void Render(ReWindow::RWindow* window); public: - explicit Scene(const std::string& name, const u8 tick_rate = 40) : tick_rate(tick_rate), name(name), entity_list(new Entity()) {} + explicit Scene(const std::string& name, const u8 tick_rate = 40) : tick_rate(tick_rate), name(name), entity_list(new Entity(this)) {} virtual ~Scene(); }; diff --git a/include/Engine/types/entity/Entity.h b/include/Engine/types/entity/Entity.h index d44fdbc..2ebb97e 100644 --- a/include/Engine/types/entity/Entity.h +++ b/include/Engine/types/entity/Entity.h @@ -4,13 +4,15 @@ #include namespace Engine { + class Scene; class Entity; } class Engine::Entity { -protected: +private: // nullptr means no parent. Entity* parent = nullptr; + Scene* scene = nullptr; // Epoch micro-seconds. long creation_time = 0.0f; @@ -27,6 +29,8 @@ public: [[nodiscard]] bool HasChildren() const { return !children.empty(); } [[nodiscard]] bool HasParent() const { return parent; } [[nodiscard]] Entity* GetParent() const; + [[nodiscard]] Scene* GetScene() const; + [[nodiscard]] Scene* GetScene(); // Microseconds. [[nodiscard]] long GetCreationTime() const; @@ -35,5 +39,6 @@ public: virtual void Update() {} public: virtual ~Entity(); + explicit Entity(Scene* scene) : scene(scene), creation_time(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()) {} explicit Entity() : creation_time(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()) {} }; \ No newline at end of file diff --git a/include/Engine/types/entity/Trigger.h b/include/Engine/types/entity/Trigger.h index cd24f37..9eb7b08 100644 --- a/include/Engine/types/entity/Trigger.h +++ b/include/Engine/types/entity/Trigger.h @@ -23,7 +23,7 @@ public: void SetSize(const Vector2& new_size) { size = new_size; } public: explicit Trigger(const Vector2& position, const Vector2& size, bool enabled = true) : - size(size), Entity(), Living(enabled), BoxCollider(enabled), Movable(position), Renderable(0, false) {} + size(size), Living(enabled), BoxCollider(enabled), Movable(position), Renderable(0, false) {} ~Trigger() override = default; }; diff --git a/src/Engine/types/Scene.cpp b/src/Engine/types/Scene.cpp index 1d161f8..af70997 100644 --- a/src/Engine/types/Scene.cpp +++ b/src/Engine/types/Scene.cpp @@ -24,6 +24,10 @@ void Scene::Update() { if (elapsed < target_tick_time) std::this_thread::sleep_for(std::chrono::microseconds(target_tick_time - elapsed)); + + // TODO Research how we can fix desync issues that would come about by a tick occasionally taking longer than we expected. + if (elapsed > target_tick_time) + Logger::Info("This tick took " + std::to_string((elapsed - target_tick_time).count()) + "μs longer than the target tick time."); } void Scene::UpdateLoop() { @@ -57,12 +61,17 @@ void Scene::Render() { } void Scene::Render(JGL::RenderTarget* render_target) { + auto start = std::chrono::steady_clock::now(); if (!render_target) Logger::Fatal("Rendering the current scene to a RenderTarget that is nullptr?"); J2D::Begin(render_target, true); Render(); J2D::End(); + auto stop = std::chrono::steady_clock::now(); + + auto frame_time = std::chrono::duration_cast(stop - start).count(); + render_target_frame_delta = frame_time / (1000.f * 1000.f); last_rendered_to_window = false; } diff --git a/src/Engine/types/entity/Camera.cpp b/src/Engine/types/entity/Camera.cpp index 756d483..34802fa 100644 --- a/src/Engine/types/entity/Camera.cpp +++ b/src/Engine/types/entity/Camera.cpp @@ -3,9 +3,9 @@ void Engine::Camera::ShouldRender(bool state) { if (state) - Globals::CurrentScene->SetActiveCamera(this); + GetScene()->SetActiveCamera(this); } bool Engine::Camera::ShouldRender() const { - return Globals::CurrentScene->GetActiveCamera() == this; + return GetScene()->GetActiveCamera() == this; } diff --git a/src/Engine/types/entity/Entity.cpp b/src/Engine/types/entity/Entity.cpp index d7af8e8..b8c0a1c 100644 --- a/src/Engine/types/entity/Entity.cpp +++ b/src/Engine/types/entity/Entity.cpp @@ -1,7 +1,10 @@ #include #include +#include -void Engine::Entity::AppendChild(Entity* entity) { +using namespace Engine; + +void Entity::AppendChild(Entity* entity) { if (entity->parent) entity->parent->RemoveChild(entity); @@ -9,12 +12,12 @@ void Engine::Entity::AppendChild(Entity* entity) { children.push_back(entity); } -Engine::Entity::~Entity() { +Entity::~Entity() { for (auto* e : children) delete e; } -void Engine::Entity::UpdateChildren() { +void Entity::UpdateChildren() { for (auto& e : children) { if (!e) continue; @@ -26,37 +29,37 @@ void Engine::Entity::UpdateChildren() { } } -void Engine::Entity::DestroyChild(Entity* entity) { +void Entity::DestroyChild(Entity* entity) { auto it = std::find(children.begin(), children.end(), entity); if (it != children.end()) delete *it, children.erase(it); } -void Engine::Entity::RemoveChild(Entity* entity) { +void Entity::RemoveChild(Entity* entity) { auto it = std::find(children.begin(), children.end(), entity); if (it != children.end()) children.erase(it); entity->parent = nullptr; } -long Engine::Entity::GetCreationTime() const { +long Entity::GetCreationTime() const { return creation_time; } -long Engine::Entity::GetAge() const { +long Entity::GetAge() const { return std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count() - creation_time; } -Engine::Entity* Engine::Entity::GetParent() const { +Entity* Entity::GetParent() const { return parent; } -std::vector Engine::Entity::GetChildren() const { +std::vector Entity::GetChildren() const { return children; } -std::vector Engine::Entity::GetAllDescendents(const Engine::Entity* entity) { - std::vector result = entity->GetChildren(); +std::vector Entity::GetAllDescendents(const Entity* entity) { + std::vector result = entity->GetChildren(); if (result.empty()) return result; @@ -67,3 +70,23 @@ std::vector Engine::Entity::GetAllDescendents(const Engine::Ent } return result; } + +Scene* Entity::GetScene() const { + if (scene) + return scene; + + const Entity* top = GetParent(); + while (top && top->GetParent()) + top = top->GetParent(); + + if (top->scene == nullptr) + Logger::Fatal("Getting the pointer to the current scene but we've lost it somehow?"); + + return top->scene; +} + +Scene* Entity::GetScene() { + const Entity* entity = this; + scene = entity->GetScene(); + return scene; +} diff --git a/src/Engine/types/entity/InstancedSprite.cpp b/src/Engine/types/entity/InstancedSprite.cpp index e6fea0a..f0f3bb9 100644 --- a/src/Engine/types/entity/InstancedSprite.cpp +++ b/src/Engine/types/entity/InstancedSprite.cpp @@ -3,31 +3,31 @@ using namespace Engine; Texture* InstancedSprite::GetTexture() { - auto* itx = Globals::CurrentScene->GetInstancedTexture(this); + auto* itx = GetScene()->GetInstancedTexture(this); if (itx) return itx->GetTexture(); return nullptr; } Texture* InstancedSprite::GetAlphaMask() { - auto* ita = Globals::CurrentScene->GetInstancedAlphaMask(this); + auto* ita = GetScene()->GetInstancedAlphaMask(this); if (ita) return ita->GetTexture(); return Sprite::GetAlphaMask(); } InstancedSprite::~InstancedSprite() { - auto* itx = Globals::CurrentScene->GetInstancedTexture(this); + auto* itx = GetScene()->GetInstancedTexture(this); if (itx) { itx->RemoveUser(this); if (itx->ReferenceCount() == 0) - Globals::CurrentScene->DestroyInstancedTexture(itx); + GetScene()->DestroyInstancedTexture(itx); } - auto* ita = Globals::CurrentScene->GetInstancedAlphaMask(this); + auto* ita = GetScene()->GetInstancedAlphaMask(this); if (ita) { ita->RemoveUser(this); if (ita->ReferenceCount() == 0) - Globals::CurrentScene->DestroyInstancedAlphaMask(ita); + GetScene()->DestroyInstancedAlphaMask(ita); } } diff --git a/src/Engine/types/entity/Moby.cpp b/src/Engine/types/entity/Moby.cpp index fd97bff..1178c18 100644 --- a/src/Engine/types/entity/Moby.cpp +++ b/src/Engine/types/entity/Moby.cpp @@ -1,6 +1,8 @@ #include #include +// TODO Improve the design such that in mixins we wouldn't have to get Globals::CurrentScene +// Maybe pass in the delta time as a parameter or something idk. using namespace J3ML; void Engine::Movable::MoveX(float speed) { position.x = position.x + (speed * Globals::CurrentScene->TickDeltaTime()); diff --git a/src/Game/Scene/Loading.cpp b/src/Game/Scene/Loading.cpp index 1370935..30e9ff5 100644 --- a/src/Game/Scene/Loading.cpp +++ b/src/Game/Scene/Loading.cpp @@ -7,8 +7,8 @@ void LoadingScreen::Init() { } void LoadingScreen::Render() { - angle += (elapsed * 4) * Globals::CurrentScene->FrameDeltaTime(); - elapsed += Globals::CurrentScene->FrameDeltaTime(); + angle += (elapsed * 4) * FrameDeltaTime(); + elapsed += FrameDeltaTime(); // Pretend we're actually loading something idk. if (elapsed >= 2.75)