diff --git a/Core/Core/CoreInstance.cpp b/Core/Core/CoreInstance.cpp index 0f1039b..5590a6f 100644 --- a/Core/Core/CoreInstance.cpp +++ b/Core/Core/CoreInstance.cpp @@ -91,7 +91,7 @@ void CoreInstance::start() game_thread.join(); } -void CoreInstance::quit() +void CoreInstance::quit() const { // Stop the main loop render_engine_->stop_render(); diff --git a/Core/Core/CoreInstance.hpp b/Core/Core/CoreInstance.hpp index 37c159c..c7bac14 100644 --- a/Core/Core/CoreInstance.hpp +++ b/Core/Core/CoreInstance.hpp @@ -50,7 +50,7 @@ public: ~CoreInstance(); void start(); - void quit(); + void quit() const; bool IsReady() const { return is_ready; } int getCountCPU() const { return countCPU_; } diff --git a/Core/Game/Actors/Actor.cpp b/Core/Game/Actors/Actor.cpp index bae95cf..9bcf3bb 100644 --- a/Core/Game/Actors/Actor.cpp +++ b/Core/Game/Actors/Actor.cpp @@ -18,7 +18,7 @@ std::shared_ptr Actor::save() save->SaveObject("loc", loc_); save->SaveObject("rot", rot_); save->SaveObject("scale", scale_); - save->SaveListStrings("tags", std::move(tags)); + save->SaveListStrings("tags", std::move(tags_)); return save; } @@ -27,7 +27,7 @@ void Actor::load(std::shared_ptr save) loc_ = std::static_pointer_cast(save->GetObject("loc")); rot_ = std::static_pointer_cast(save->GetObject("rot")); scale_ = std::static_pointer_cast(save->GetObject("scale")); - tags = std::move(save->GetListString("tags")); + tags_ = std::move(save->GetListString("tags")); } void Actor::BeginPlay() @@ -52,10 +52,10 @@ void Actor::SetActorRotate(const Vector3D& rot) noexcept void Actor::AddTag(const std::string& tag) noexcept { - tags.push_back(tag); + tags_.push_back(tag); } void Actor::RemoveTag(const std::string& tag) noexcept { - tags.remove(tag); + tags_.remove(tag); } diff --git a/Core/Game/Actors/Actor.hpp b/Core/Game/Actors/Actor.hpp index 37e97a9..ae0c504 100644 --- a/Core/Game/Actors/Actor.hpp +++ b/Core/Game/Actors/Actor.hpp @@ -18,7 +18,7 @@ class Actor : public ISave, public IRTTI std::shared_ptr loc_, rot_, scale_; - std::list tags; + std::list tags_; protected: virtual void OnDestroy(); @@ -52,7 +52,7 @@ public: void AddTag(const std::string& tag) noexcept; void RemoveTag(const std::string& tag) noexcept; - const std::list& GetTags() const { return tags; } + const std::list& GetTags() const { return tags_; } std::shared_ptr GetWorld() const { return world_; } const std::string& GetName() const { return name_; } diff --git a/Core/Game/SaveMap/SaveMap.cpp b/Core/Game/SaveMap/SaveMap.cpp index 0de5592..1ad1f47 100644 --- a/Core/Game/SaveMap/SaveMap.cpp +++ b/Core/Game/SaveMap/SaveMap.cpp @@ -21,7 +21,7 @@ ISave* SaveMap::MakeObjectByName(const std::string& name) return factory.factory(); } } - throw std::runtime_error("Object not found"); + throw std::runtime_error("Object not found (" + name + ")"); } SaveMap::SaveMap(const char* class_name) : class_name(class_name) diff --git a/Core/Game/World/World.hpp b/Core/Game/World/World.hpp index 1c50b17..f452e06 100644 --- a/Core/Game/World/World.hpp +++ b/Core/Game/World/World.hpp @@ -49,7 +49,7 @@ public: std::shared_ptr object = std::make_shared(); object->SetActorLocate(loc); object->SetActorRotate(rot); - std::static_pointer_cast(object)->world_ = this; + std::static_pointer_cast(object)->world_ = std::static_pointer_cast(shared_from_this()); std::static_pointer_cast(object)->name_ = name; actors_map.try_emplace(name, object); return object; @@ -57,7 +57,7 @@ public: void DestroyActor(std::weak_ptr ptr); - template> + template>> Container GetActorsByTag(std::string tag) { Container container; @@ -68,7 +68,7 @@ public: for (auto& j : tags) { if (j == tag) - container.push_back(i); + container.push_back(i.second); } } @@ -76,9 +76,9 @@ public: } template - std::weak_ptr GetActorByID(const std::string& id) + std::weak_ptr GetActorByName(const std::string& name) { - auto it = actors_map.find(id); + auto it = actors_map.find(name); if (it == actors_map.end() || it->second == nullptr) return {}; diff --git a/TestGame/src/TestGameInstance.cpp b/TestGame/src/TestGameInstance.cpp index e062916..981bf19 100644 --- a/TestGame/src/TestGameInstance.cpp +++ b/TestGame/src/TestGameInstance.cpp @@ -1,9 +1,7 @@ #include "TestGameInstance.h" -#include "Game/Resource/Resource.hpp" #include -#include "Game/SaveMap/SaveMap.hpp" #include "Game/World/World.hpp" GENERATE_FACTORY_GAME_INSTANCE(TestGameInstance) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 6582a9c..91dc63a 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1,4 +1,4 @@ -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) include(FetchContent) FetchContent_Declare( googletest @@ -11,18 +11,16 @@ FetchContent_MakeAvailable(googletest) enable_testing() file(GLOB SRC - "SaveMapTest.cpp" - "ObjectPtrTest.cpp" - - "${PROJECT_SOURCE_DIR}/Core/Game/SaveMap/SaveMap.cpp" + "ObjectFactory.cpp" "WorldFactory.cpp" "TestRenderEngine.cpp" "TestRenderEngine.h" "TestGameInstance.cpp" "TestGameInstance.h" + "SaveMap/SaveMapTest.cpp" "SaveMap/CustomObject.h" + "World/WorldTest.cpp" "World/TestWorld.h" "World/TestActor.cpp" "World/TestActor.h" ) add_executable(Tests ${SRC}) -target_link_libraries(Tests PRIVATE - GTest::gtest_main -) +target_link_libraries(Tests PRIVATE GTest::gtest_main Core RenderEngineSDK) target_include_directories(Tests PRIVATE ${PROJECT_SOURCE_DIR}/Core + ${PROJECT_SOURCE_DIR}/RenderEngineSDK ) diff --git a/Tests/ObjectFactory.cpp b/Tests/ObjectFactory.cpp new file mode 100644 index 0000000..cb515ed --- /dev/null +++ b/Tests/ObjectFactory.cpp @@ -0,0 +1,10 @@ +#include "Game/ObjectFactory.hpp" + +#include "SaveMap/CustomObject.h" +#include "World/TestActor.h" + + +FACTORIES_LIST{ + GENERATE_FACTORY_OBJECT(CustomObject) + GENERATE_FACTORY_OBJECT(TestActor) +}; \ No newline at end of file diff --git a/Tests/SaveMap/CustomObject.h b/Tests/SaveMap/CustomObject.h new file mode 100644 index 0000000..c003205 --- /dev/null +++ b/Tests/SaveMap/CustomObject.h @@ -0,0 +1,18 @@ +#pragma once + +#include "Game/SaveMap/ISave.h" + +#include +#include + +class CustomObject : public ISave +{ +public: + int num; + std::string str; + double dbl; + + std::shared_ptr save() override; + void load(std::shared_ptr save) override; + bool operator==(const CustomObject& obj) const; +}; \ No newline at end of file diff --git a/Tests/SaveMapTest.cpp b/Tests/SaveMap/SaveMapTest.cpp similarity index 85% rename from Tests/SaveMapTest.cpp rename to Tests/SaveMap/SaveMapTest.cpp index 2d9def7..f9f52a1 100644 --- a/Tests/SaveMapTest.cpp +++ b/Tests/SaveMap/SaveMapTest.cpp @@ -1,42 +1,29 @@ #include -#include #include "Game/ObjectFactory.hpp" #include "Game/SaveMap/SaveMap.hpp" +#include "CustomObject.h" -class CustomObject : public ISave +std::shared_ptr CustomObject::save() { -public: - int num; - std::string str; - double dbl; - - std::shared_ptr save() override - { - std::shared_ptr save = std::make_shared("CustomObject"); - save->SaveInteger("num", num); - save->SaveString("str", str); - save->SaveDouble("dbl", dbl); - return save; - } - void load(std::shared_ptr save) override - { - num = static_cast(save->GetInteger("num")); - str = save->GetString("str"); - dbl = save->GetDouble("dbl"); - } + std::shared_ptr save = std::make_shared("CustomObject"); + save->SaveInteger("num", num); + save->SaveString("str", str); + save->SaveDouble("dbl", dbl); + return save; +} - bool operator==(const CustomObject& obj) const - { - return num == obj.num && str == obj.str && dbl == obj.dbl; - } -}; +void CustomObject::load(std::shared_ptr save) +{ + num = static_cast(save->GetInteger("num")); + str = save->GetString("str"); + dbl = save->GetDouble("dbl"); +} -FACTORIES_LIST { - GENERATE_FACTORY_OBJECT(CustomObject) -}; -// A compatibility plug -std::vector base_object_factories = {}; +bool CustomObject::operator==(const CustomObject& obj) const +{ + return num == obj.num && str == obj.str && dbl == obj.dbl; +} TEST(SaveMapTest, check_clean) { diff --git a/Tests/TestGameInstance.cpp b/Tests/TestGameInstance.cpp new file mode 100644 index 0000000..981bf19 --- /dev/null +++ b/Tests/TestGameInstance.cpp @@ -0,0 +1,10 @@ +#include "TestGameInstance.h" + +#include + +#include "Game/World/World.hpp" +GENERATE_FACTORY_GAME_INSTANCE(TestGameInstance) + +TestGameInstance::TestGameInstance(CoreInstance& core) : GameInstance(core) +{ +} diff --git a/Tests/TestGameInstance.h b/Tests/TestGameInstance.h new file mode 100644 index 0000000..368a059 --- /dev/null +++ b/Tests/TestGameInstance.h @@ -0,0 +1,9 @@ +#pragma once + +#include "Game/GameInstance.hpp" + +class TestGameInstance : public GameInstance +{ +public: + TestGameInstance(CoreInstance& core); +}; \ No newline at end of file diff --git a/Tests/TestRenderEngine.cpp b/Tests/TestRenderEngine.cpp new file mode 100644 index 0000000..be6acad --- /dev/null +++ b/Tests/TestRenderEngine.cpp @@ -0,0 +1,15 @@ +#include "TestRenderEngine.h" + +RENDER_ENGINE_FACTORY_GENERATE(TestRenderEngine) + +TestRenderEngine::TestRenderEngine(CoreInstance& core):RenderEngineBase(core) +{ +} + +void TestRenderEngine::start() +{ +} + +void TestRenderEngine::stop_render() const +{ +} diff --git a/Tests/TestRenderEngine.h b/Tests/TestRenderEngine.h new file mode 100644 index 0000000..e36e651 --- /dev/null +++ b/Tests/TestRenderEngine.h @@ -0,0 +1,12 @@ +#pragma once + +#include "RenderEngineBase.hpp" + +class TestRenderEngine final : public RenderEngineBase +{ +public: + TestRenderEngine(CoreInstance& core); + + void start() override; + void stop_render() const override; +}; \ No newline at end of file diff --git a/Tests/World/TestActor.cpp b/Tests/World/TestActor.cpp new file mode 100644 index 0000000..f9fc1c1 --- /dev/null +++ b/Tests/World/TestActor.cpp @@ -0,0 +1,19 @@ +#include "TestActor.h" + +#include "Game/SaveMap/SaveMap.hpp" + +TestActor::TestActor() +{ + SetType(Classes::TestActor); +} + +std::shared_ptr TestActor::save() +{ + std::shared_ptr save = std::make_shared("TestActor"); + save->connect_to(Actor::save()); + return save; +} +void TestActor::load(std::shared_ptr save) +{ + Actor::load(save->getParent()); +} \ No newline at end of file diff --git a/Tests/World/TestActor.h b/Tests/World/TestActor.h new file mode 100644 index 0000000..8b06bfc --- /dev/null +++ b/Tests/World/TestActor.h @@ -0,0 +1,14 @@ +#pragma once + +#include "RTTI_Meta.h" +#include "Game/Actors/Actor.hpp" + +GENERATE_META(TestActor) +class TestActor : public Actor +{ +public: + TestActor(); + + std::shared_ptr save() override; + void load(std::shared_ptr save) override; +}; diff --git a/Tests/World/TestWorld.h b/Tests/World/TestWorld.h new file mode 100644 index 0000000..79f1d4c --- /dev/null +++ b/Tests/World/TestWorld.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Game/World/World.hpp" + +class TestWorld : public World +{ +public: + explicit TestWorld(GameInstance& game_instance); + + std::shared_ptr save() override; + void load(std::shared_ptr save) override; +}; diff --git a/Tests/World/WorldTest.cpp b/Tests/World/WorldTest.cpp new file mode 100644 index 0000000..12f9f60 --- /dev/null +++ b/Tests/World/WorldTest.cpp @@ -0,0 +1,238 @@ +#include +#include +#include + +#include "TestActor.h" +#include "Game/World/World.hpp" +#include "TestWorld.h" +#include "Core/CoreInstance.hpp" +#include "Game/GameInstance.hpp" +#include "Game/SaveMap/SaveMap.hpp" + +TestWorld::TestWorld(GameInstance& game_instance) : World(game_instance) +{ +} + +std::shared_ptr TestWorld::save() +{ + std::shared_ptr save = std::make_shared("TestWorld"); + save->connect_to(World::save()); + return save; +} +void TestWorld::load(std::shared_ptr save) +{ + World::load(save->getParent()); +} + +TEST(World, check_load) +{ + const std::string main_config = + R"({ + "Class name":"MainConfig", + "dmin_memory_size":4096.0, + "imin_CPU_count":1, + "sgame_name":"tests", + "sbase_world":"tests" + })"; + std::ofstream main_config_file("main_config.conf"); + main_config_file << main_config; + main_config_file.close(); + + const std::string world_config = +R"( +{ + "Class name": "TestWorld", + "Parent parameters": { + "Class name": "World", + "vsActorsIDs": [ + "TempActor" + ], + "loActors": [ + { + "Class name": "Actor", + "oloc": { + "Class name": "Vector3D", + "dx": 1, + "dy": -1, + "dz": 1 + }, + "orot": { + "Class name": "Vector3D", + "dx": 0, + "dy": 0, + "dz": 0 + }, + "oscale": { + "Class name": "Vector3D", + "dx": 1, + "dy": 1, + "dz": 1 + }, + "lstags": [] + } + ] + } +} +)"; + + std::filesystem::create_directories("Worlds"); + std::ofstream world_file("Worlds/tests.world"); + world_file << world_config; + world_file.close(); + + CoreInstance tmp_core; + tmp_core.GetGameInstance()->GetWorld()->SpawnActorFormClass("Test"); + + std::vector> actors = tmp_core.GetGameInstance()->GetWorld()->GetActorsByClass(); + ASSERT_EQ(actors.size(), 2); + + std::filesystem::remove("Worlds/tests.world"); + std::filesystem::remove("Worlds"); + std::filesystem::remove("main_config.conf"); +} + +TEST(World, check_finders) +{ + const std::string main_config = + R"({ + "Class name":"MainConfig", + "dmin_memory_size":4096.0, + "imin_CPU_count":1, + "sgame_name":"tests", + "sbase_world":"tests" + })"; + std::ofstream main_config_file("main_config.conf"); + main_config_file << main_config; + main_config_file.close(); + + const std::string world_config = +R"( +{ + "Class name": "TestWorld", + "Parent parameters": { + "Class name": "World", + "vsActorsIDs": [ + "TempActor1", + "TempActor2" + ], + "loActors": [ + { + "Class name": "TestActor", + "Parent parameters":{ + "Class name": "Actor", + "oloc": { + "Class name": "Vector3D", + "dx": 1, + "dy": -1, + "dz": 1 + }, + "orot": { + "Class name": "Vector3D", + "dx": 0, + "dy": 0, + "dz": 0 + }, + "oscale": { + "Class name": "Vector3D", + "dx": 1, + "dy": 1, + "dz": 1 + }, + "lstags": [] + } + }, + { + "Class name": "Actor", + "oloc": { + "Class name": "Vector3D", + "dx": 1, + "dy": -1, + "dz": 1 + }, + "orot": { + "Class name": "Vector3D", + "dx": 0, + "dy": 0, + "dz": 0 + }, + "oscale": { + "Class name": "Vector3D", + "dx": 1, + "dy": 1, + "dz": 1 + }, + "lstags": ["Simple"] + } + ] + } +} +)"; + std::filesystem::create_directories("Worlds"); + std::ofstream world_file("Worlds/tests.world"); + world_file << world_config; + world_file.close(); + + CoreInstance tmp_core; + + // Test find by class + std::vector> test_actors = tmp_core.GetGameInstance()->GetWorld()->GetActorsByClass(); + ASSERT_EQ(test_actors.size(), 1); + + // Test find by tag + std::vector> actors = tmp_core.GetGameInstance()->GetWorld()->GetActorsByTag("Simple"); + ASSERT_EQ(actors.size(), 1); + + // Test find by name + std::weak_ptr actor_by_name = tmp_core.GetGameInstance()->GetWorld()->GetActorByName("TempActor2"); + ASSERT_EQ(actor_by_name.expired(), false); + ASSERT_EQ(*actor_by_name.lock()->GetTags().begin(), "Simple"); + + std::filesystem::remove("Worlds/tests.world"); + std::filesystem::remove("Worlds"); + std::filesystem::remove("main_config.conf"); +} + +TEST(World, check_spawn_actor_from_class) +{ + const std::string main_config = +R"({ + "Class name":"MainConfig", + "dmin_memory_size":4096.0, + "imin_CPU_count":1, + "sgame_name":"tests", + "sbase_world":"tests" + })"; + std::ofstream main_config_file("main_config.conf"); + main_config_file << main_config; + main_config_file.close(); + + const std::string world_config = +R"( +{ + "Class name": "TestWorld", + "Parent parameters": { + "Class name": "World", + "vsActorsIDs": [ + ], + "loActors": [ + ] + } +} +)"; + std::filesystem::create_directories("Worlds"); + std::ofstream world_file("Worlds/tests.world"); + world_file << world_config; + world_file.close(); + + CoreInstance tmp_core; + std::vector> test_actors = tmp_core.GetGameInstance()->GetWorld()->GetActorsByClass(); + ASSERT_EQ(test_actors.size(), 0); + + tmp_core.GetGameInstance()->GetWorld()->SpawnActorFormClass("Test"); + test_actors = tmp_core.GetGameInstance()->GetWorld()->GetActorsByClass(); + ASSERT_EQ(test_actors.size(), 1); + + std::filesystem::remove("Worlds/tests.world"); + std::filesystem::remove("Worlds"); + std::filesystem::remove("main_config.conf"); +} \ No newline at end of file diff --git a/Tests/WorldFactory.cpp b/Tests/WorldFactory.cpp new file mode 100644 index 0000000..9cf6148 --- /dev/null +++ b/Tests/WorldFactory.cpp @@ -0,0 +1,8 @@ +#include + +#include "World/TestWorld.h" + +WORLDS_LIST +{ + GENERATE_WORLD_FACTORY(TestWorld, tests) +}; \ No newline at end of file diff --git a/UwURenderEngine/Game/Actors/Camera.cpp b/UwURenderEngine/Game/Actors/Camera.cpp index 3cfa837..958926c 100644 --- a/UwURenderEngine/Game/Actors/Camera.cpp +++ b/UwURenderEngine/Game/Actors/Camera.cpp @@ -25,5 +25,5 @@ void Camera::load(std::shared_ptr save) void Camera::SetActive() const noexcept { - GET_RENDER_ENGINE->SetActiveCamera(GetWorld()->GetActorByID(GetName())); + GET_RENDER_ENGINE->SetActiveCamera(GetWorld()->GetActorByName(GetName())); }