From 0ec86e3de8b4c8e14efaaeeda7e39e53ad5be5ed Mon Sep 17 00:00:00 2001 From: Jiga228 Date: Sat, 18 Oct 2025 14:26:22 +0700 Subject: [PATCH] Move world on unordered_map and object_ptr --- Core/Core/RenderEngine/RenderEngine.cpp | 2 +- Core/Game/Actors/Actor.cpp | 8 +----- Core/Game/Actors/Actor.hpp | 3 +- Core/Game/World/World.cpp | 37 ++++++++++++++++++------- Core/Game/World/World.hpp | 34 ++++++++++++++--------- TestGame/Worlds/TestWorld.world | 14 +++++----- TestGame/src/Worlds/TestWorld.cpp | 7 +++++ Tests/ObjectPtrTest.cpp | 33 ++++++++++++++++++++++ 8 files changed, 99 insertions(+), 39 deletions(-) diff --git a/Core/Core/RenderEngine/RenderEngine.cpp b/Core/Core/RenderEngine/RenderEngine.cpp index 2d1683d..7d643f2 100644 --- a/Core/Core/RenderEngine/RenderEngine.cpp +++ b/Core/Core/RenderEngine/RenderEngine.cpp @@ -991,7 +991,7 @@ RenderEngine::~RenderEngine() void RenderEngine::start() { World* world = core_.GetGameInstance()->GetWorld(); - std::vector meshes = world->GetActorsByClass(); + std::vector> meshes = world->GetActorsByClass(); for (auto& i : meshes) i->load_model(i->GetModelName()); diff --git a/Core/Game/Actors/Actor.cpp b/Core/Game/Actors/Actor.cpp index 8269f6e..12c7973 100644 --- a/Core/Game/Actors/Actor.cpp +++ b/Core/Game/Actors/Actor.cpp @@ -8,7 +8,7 @@ void Actor::OnDestroy() { } -Actor::Actor() +Actor::Actor() : loc(new Vector3D), rot(new Vector3D), scale(new Vector3D) { SetType(Classes::Actor); } @@ -60,9 +60,3 @@ void Actor::RemoveTag(const std::string& tag) noexcept { tags.remove(tag); } - -void Actor::Destroy() -{ - OnDestroy(); - //world_->actors.remove(this); -} diff --git a/Core/Game/Actors/Actor.hpp b/Core/Game/Actors/Actor.hpp index bf93162..fb7108d 100644 --- a/Core/Game/Actors/Actor.hpp +++ b/Core/Game/Actors/Actor.hpp @@ -15,6 +15,7 @@ GENERATE_META(Actor) class Actor : public ISave, public IRTTI { World* world_; + std::string name_; UType::object_ptr loc, rot, scale; @@ -53,9 +54,9 @@ public: void AddTag(const std::string& tag) noexcept; void RemoveTag(const std::string& tag) noexcept; const std::list& GetTags() const { return tags; } - void Destroy(); World* GetWorld() const { return world_; } + const std::string& GetName() const { return name_; } friend class World; }; diff --git a/Core/Game/World/World.cpp b/Core/Game/World/World.cpp index 09482dd..bceb99c 100644 --- a/Core/Game/World/World.cpp +++ b/Core/Game/World/World.cpp @@ -8,32 +8,49 @@ World::World(GameInstance& game_instance) : game_instance(game_instance) World::~World() { - actors.clear(); + actors_map.clear(); } void World::BeginPlay() { - for (auto& i : actors) - i->BeginPlay(); + for (auto& i : actors_map) + i.second->BeginPlay(); } void World::Tick(double delta_time) { - for (auto& i : actors) - i->Tick(delta_time); + for (auto& i : actors_map) + i.second->Tick(delta_time); } std::shared_ptr World::save() { std::shared_ptr save = std::make_shared("World"); - save->SaveListObject("Actors", std::move(reinterpret_cast>&>(actors))); return save; } void World::load(std::shared_ptr save) { - actors = std::move(reinterpret_cast>&>(save->GetListObject("Actors"))); + std::vector actors_IDs = save->GetVectorString("ActorsIDs"); + std::list> act = std::move(reinterpret_cast>&>(save->GetListObject("Actors"))); - for (auto& i : actors) - i->world_ = this; -} \ No newline at end of file + size_t i_id = 0; + for (auto& i : act) + { + auto[it, flag] = actors_map.try_emplace(actors_IDs[i_id], i); + it->second->world_ = this; + it->second->name_ = it->first; + i_id++; + } +} + +void World::DestroyActor(UType::object_ptr ptr) +{ + if (ptr.get() == nullptr) + return; + + std::string name = ptr->GetName(); + actors_map.erase(name); + ptr->OnDestroy(); + ptr.destroy(); +} diff --git a/Core/Game/World/World.hpp b/Core/Game/World/World.hpp index f936e07..dfeef07 100644 --- a/Core/Game/World/World.hpp +++ b/Core/Game/World/World.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -16,8 +17,7 @@ class World : public ISave { GameInstance& game_instance; - // Actors only - std::list> actors; + std::unordered_map> actors_map; public: World(GameInstance& game_instance); @@ -33,37 +33,39 @@ public: void load(std::shared_ptr save) override; #pragma endregion - template> - Container GetActorsByClass() + template + std::vector> GetActorsByClass() { - Container list; - for (auto i = actors.cbegin(); i != actors.cend(); ++i) + std::vector> list; + for (auto i = actors_map.cbegin(); i != actors_map.cend(); ++i) { - if (T* cast_object = RTTI::dyn_cast((*i).get())) - list.push_back(cast_object); + if (T* cast_object = RTTI::dyn_cast(i->second.get())) + list.push_back(UType::object_ptr(cast_object)); } return list; } template - T* SpawnActorFormClass(const Vector3D& loc = { 0, 0, 0 }, const Vector3D& rot = { 0, 0, 0 }) + UType::object_ptr SpawnActorFormClass(std::string name, const Vector3D& loc = { 0, 0, 0 }, const Vector3D& rot = { 0, 0, 0 }) { - T* object = new T(); + UType::object_ptr object(new T()); object->SetActorLocate(loc); object->SetActorRotate(rot); static_cast(object)->world_ = this; - actors.push_back(object); + actors_map.try_emplace(name, object); return object; } + void DestroyActor(UType::object_ptr ptr); + template> Container GetActorsByTag(std::string tag) { Container container; - for (auto& i : actors) + for (auto& i : actors_map) { - const std::list& tags = i->GetTags(); + const std::list& tags = i.second->GetTags(); for (auto& j : tags) { if (j == tag) @@ -73,5 +75,11 @@ public: return container; } + + template + UType::object_ptr GetActorByID(const std::string& id) + { + return actors_map[id]; + } }; diff --git a/TestGame/Worlds/TestWorld.world b/TestGame/Worlds/TestWorld.world index ada8632..6b3ccfe 100644 --- a/TestGame/Worlds/TestWorld.world +++ b/TestGame/Worlds/TestWorld.world @@ -3,7 +3,7 @@ "dtime": 5.000000, "Parent parameters": { "Class name":"World", - "vsActorsIDs": ["Mesh"], + "vsActorsIDs": ["TestMesh1"], "loActors": [ { "Class name": "StaticMesh", @@ -14,9 +14,9 @@ "Class name":"Actor", "oloc": { "Class name":"Vector3D", - "dx":0.0, - "dy":0.0, - "dz":0.0 + "dx":1.0, + "dy":-1.0, + "dz":1.0 }, "orot": { "Class name":"Vector3D", @@ -26,9 +26,9 @@ }, "oscale": { "Class name": "Vector3D", - "dx": 0.0, - "dy": 0.0, - "dz": 0.0 + "dx": 1.0, + "dy": 1.0, + "dz": 1.0 }, "tags":[] } diff --git a/TestGame/src/Worlds/TestWorld.cpp b/TestGame/src/Worlds/TestWorld.cpp index 9b8731f..a2def3c 100644 --- a/TestGame/src/Worlds/TestWorld.cpp +++ b/TestGame/src/Worlds/TestWorld.cpp @@ -21,6 +21,13 @@ void TestWorld::Tick(double delta_time) if (time >= 10.0) { Message("TestWorld: Time out"); + std::vector> meshes = GetActorsByClass(); + if (!meshes.empty()) + { + DestroyActor(static_cast>(meshes[0])); + time = 7.0; + return; + } GetGameInstance().quit(); } } diff --git a/Tests/ObjectPtrTest.cpp b/Tests/ObjectPtrTest.cpp index dafe324..d6704fc 100644 --- a/Tests/ObjectPtrTest.cpp +++ b/Tests/ObjectPtrTest.cpp @@ -1,6 +1,21 @@ #include #include "Types/object_ptr.hpp" +class TestClass +{ + int* test_ptr_; +public: + TestClass(int* test_ptr) : test_ptr_(test_ptr) + { + *test_ptr_ = 1; + } + + ~TestClass() + { + *test_ptr_ = 2; + } +}; + TEST(object_ptr_test, base_test) { int* test = new int(123); @@ -23,4 +38,22 @@ TEST(object_ptr_test, check_destry) ptr.destroy(); EXPECT_EQ(ptr.get(), nullptr); EXPECT_EQ(ptr2.get(), nullptr); +} + +TEST(object_ptr_test, check_destroy) +{ + int* test = new int(0); + { + UType::object_ptr ptr(new TestClass(test)); + EXPECT_EQ(*test, 1); + } + EXPECT_EQ(*test, 2); + + *test = 0; + { + UType::object_ptr ptr(new TestClass(test)); + UType::object_ptr ptr2(ptr); + EXPECT_EQ(*test, 1); + } + EXPECT_EQ(*test, 2); } \ No newline at end of file