diff --git a/Core/Game/Actors/Actor.hpp b/Core/Game/Actors/Actor.hpp index 744c194..37e97a9 100644 --- a/Core/Game/Actors/Actor.hpp +++ b/Core/Game/Actors/Actor.hpp @@ -13,7 +13,7 @@ GENERATE_META(Actor) class Actor : public ISave, public IRTTI { - World* world_; + std::shared_ptr world_; std::string name_; std::shared_ptr loc_, rot_, scale_; @@ -54,7 +54,7 @@ public: void RemoveTag(const std::string& tag) noexcept; const std::list& GetTags() const { return tags; } - World* GetWorld() const { return world_; } + std::shared_ptr GetWorld() const { return world_; } const std::string& GetName() const { return name_; } friend class World; diff --git a/Core/Game/GameInstance.cpp b/Core/Game/GameInstance.cpp index 2f7212c..a6246f5 100644 --- a/Core/Game/GameInstance.cpp +++ b/Core/Game/GameInstance.cpp @@ -7,10 +7,11 @@ #include "Core/CoreInstance.hpp" #include "Game/WorldFactory.hpp" #include "Game/World/World.hpp" +#include "Log/Log.hpp" extern std::vector world_factories; -GameInstance::GameInstance(CoreInstance& core) : core(core) +GameInstance::GameInstance(CoreInstance& core) : core_(core) { const std::string& base_world = core.getBaseWorldName(); @@ -21,33 +22,28 @@ GameInstance::GameInstance(CoreInstance& core) : core(core) { if (factories.world_name == base_world) { - world = factories.factory(*this); + world_ = factories.factory(*this); break; } } - if (world == nullptr) + if (world_ == nullptr) throw std::runtime_error("Can't find world"); } -GameInstance::~GameInstance() -{ - delete world; -} - void GameInstance::start() { - world->BeginPlay(); + world_->BeginPlay(); auto first = std::chrono::steady_clock::now(); - while (is_running) + while (is_running_) { auto second = std::chrono::steady_clock::now(); std::chrono::milliseconds delta_time = std::chrono::duration_cast(second - first); - world->Tick(delta_time.count() / 1000.0); + world_->Tick(delta_time.count() / 1000.0); first = second; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } @@ -55,11 +51,11 @@ void GameInstance::start() void GameInstance::stop() { - is_running = false; + is_running_ = false; } void GameInstance::quit() { stop(); - core.quit(); + core_.quit(); } diff --git a/Core/Game/GameInstance.hpp b/Core/Game/GameInstance.hpp index e56b85a..b70ae4f 100644 --- a/Core/Game/GameInstance.hpp +++ b/Core/Game/GameInstance.hpp @@ -11,10 +11,10 @@ GameInstance* GameFactory(CoreInstance& core) { return new Class(core); } class GameInstance { - CoreInstance& core; - World* world = nullptr; + CoreInstance& core_; + std::shared_ptr world_; - std::atomic is_running = true; + std::atomic is_running_ = true; void start(); // Stop call from the core @@ -25,10 +25,10 @@ public: // Init vulkan GameInstance(CoreInstance& core); - virtual ~GameInstance(); + virtual ~GameInstance() = default; - World* GetWorld() const { return world; } - CoreInstance& GetCore() const { return core; } + std::shared_ptr GetWorld() const { return world_; } + CoreInstance& GetCore() const { return core_; } friend class CoreInstance; }; diff --git a/Core/Game/SaveMap/ISave.h b/Core/Game/SaveMap/ISave.h index 02c3f95..808a5b8 100644 --- a/Core/Game/SaveMap/ISave.h +++ b/Core/Game/SaveMap/ISave.h @@ -4,7 +4,7 @@ class SaveMap; -class ISave +class ISave : public std::enable_shared_from_this { public: virtual ~ISave() = default; diff --git a/Core/Game/SaveMap/SaveMap.cpp b/Core/Game/SaveMap/SaveMap.cpp index 9391337..0de5592 100644 --- a/Core/Game/SaveMap/SaveMap.cpp +++ b/Core/Game/SaveMap/SaveMap.cpp @@ -56,14 +56,14 @@ SaveMap::SaveMap(const std::string& json_data) size_t end = i = json_data_blank.find_first_of(",}", i); i++; std::string value = json_data_blank.substr(begin, end - begin); - save_long[name.c_str() + 1] = std::stoll(value); + save_long[name.c_str() + 1] = std::stoll(value); // (name.c_str() + 1) - отсекаем метаданные } else if (name[0] == 'd') { size_t begin = json_data_blank.find(':', i) + 1; size_t end = i = json_data_blank.find_first_of(",}", i); i++; std::string value = json_data_blank.substr(begin, end - begin); - save_double[name.c_str() + 1] = std::stod(value); + save_double[name.c_str() + 1] = std::stod(value); // (name.c_str() + 1) - отсекаем метаданные } else if (name[0] == 's') { size_t begin = json_data_blank.find(':', i) + 2; @@ -74,7 +74,7 @@ SaveMap::SaveMap(const std::string& json_data) value = json_data_blank.substr(begin, end - begin); else value = ""; - save_string[name.c_str() + 1] = value; + save_string[name.c_str() + 1] = value; // (name.c_str() + 1) - отсекаем метаданные } else if (name[0] == 'o') { size_t begin = i = json_data_blank.find('{', i); @@ -100,10 +100,10 @@ SaveMap::SaveMap(const std::string& json_data) std::shared_ptr object_ptr(MakeObjectByName(object_name)); object_ptr->load(std::make_shared(object_json)); - save_objects[name.c_str() + 1] = object_ptr; + save_objects[name.c_str() + 1] = object_ptr; // (name.c_str() + 1) - отсекаем метаданные } else if (name[0] == 'v') { - std::string key = name.substr(2, name.length() - 2); + std::string key = name.substr(2, name.length() - 2); // (off = 2) - отсечение метаданных; (name.length() - 2) - отсечение кавычки и перевод в индексы size_t begin_arr = i = json_data_blank.find('[', i); int open = 1, close = 0; diff --git a/Core/Game/World/World.cpp b/Core/Game/World/World.cpp index 4c1f0ce..fe282a9 100644 --- a/Core/Game/World/World.cpp +++ b/Core/Game/World/World.cpp @@ -46,13 +46,13 @@ std::shared_ptr World::save() void World::load(std::shared_ptr save) { std::vector actors_IDs = save->GetVectorString("ActorsIDs"); - std::list> act = std::move(reinterpret_cast>&>(save->GetListObject("Actors"))); + std::list> act = save->GetListObject("Actors"); 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; + auto[it, flag] = actors_map.try_emplace(actors_IDs[i_id], std::static_pointer_cast(i)); + it->second->world_ = std::static_pointer_cast(shared_from_this()); it->second->name_ = it->first; i_id++; } diff --git a/Core/Game/WorldFactory.hpp b/Core/Game/WorldFactory.hpp index d9ac6d0..ecb5d24 100644 --- a/Core/Game/WorldFactory.hpp +++ b/Core/Game/WorldFactory.hpp @@ -11,7 +11,7 @@ class World; struct WorldFactory { const char* world_name; - World*(*factory)(GameInstance&); + std::shared_ptr(*factory)(GameInstance&); }; // Создаёт ассоцеативный список @@ -20,8 +20,8 @@ struct WorldFactory // Генерирует элемент списка #define GENERATE_WORLD_FACTORY(Class, WorldName) WorldFactory{#WorldName,\ -[](GameInstance& game_insance)->World* {\ - Class* world = new Class(game_insance);\ +[](GameInstance& game_insance)->std::shared_ptr {\ + std::shared_ptr world = std::make_shared(game_insance);\ std::ifstream config_file("./Worlds/" #WorldName ".world");\ if (config_file.fail())\ throw std::runtime_error("Can't open world file");\ @@ -32,7 +32,7 @@ struct WorldFactory data.resize(file_size);\ config_file.read(data.data(), file_size);\ world->load(std::make_shared(data));\ - return world;\ + return std::static_pointer_cast(world);\ }}, /* diff --git a/TestGame/src/Actors/TestActor.cpp b/TestGame/src/Actors/TestActor.cpp index c6b7afc..1dea7e7 100644 --- a/TestGame/src/Actors/TestActor.cpp +++ b/TestGame/src/Actors/TestActor.cpp @@ -1,12 +1,26 @@ #include "TestActor.h" +#include "Game/Actors/Camera.hpp" #include "Game/SaveMap/SaveMap.hpp" +#include "Game/World/World.hpp" #include "Log/Log.hpp" +void TestActor::print_when_main_camera_rotate(const Vector3D& rot) +{ + std::string msg = + "(" + name_ + ") camera move to x: " + std::to_string(rot.x) + + " y: " + std::to_string(rot.y) + + " z: " + std::to_string(rot.z); + Loging::Message(msg); +} + void TestActor::BeginPlay() { Actor::BeginPlay(); Loging::Log("TestActor::BeginPlay"); + GetWorld()->GetActorsByClass()[0].lock()->OnSetActorRotate.bind( + std::static_pointer_cast(shared_from_this()), + &TestActor::print_when_main_camera_rotate + ); } std::shared_ptr TestActor::save() diff --git a/TestGame/src/Actors/TestActor.h b/TestGame/src/Actors/TestActor.h index b36870b..339bbcd 100644 --- a/TestGame/src/Actors/TestActor.h +++ b/TestGame/src/Actors/TestActor.h @@ -5,6 +5,8 @@ GENERATE_META(TestActor) class TestActor final : public Actor { + const std::string name_ = "First test actor"; + void print_when_main_camera_rotate(const Vector3D& rot); public: void BeginPlay() override; diff --git a/TestGame/src/Worlds/TestWorld.cpp b/TestGame/src/Worlds/TestWorld.cpp index d6059e8..8fd3a00 100644 --- a/TestGame/src/Worlds/TestWorld.cpp +++ b/TestGame/src/Worlds/TestWorld.cpp @@ -1,6 +1,5 @@ #include "TestWorld.h" -#include #include #include "../Actors/TestActor.h" @@ -10,6 +9,14 @@ #include "Log/Log.hpp" #include "Game/Actors/Mesh/Mesh.hpp" +void TestWorld::print_when_camera_move(const Vector3D& loc_) +{ + std::string msg = + "(" + name_ + ") camera move to x: " + std::to_string(loc_.x) + + " y: " + std::to_string(loc_.y) + + " z: " + std::to_string(loc_.z); + Loging::Message(msg); +} + TestWorld::TestWorld(GameInstance& game_instance) : World(game_instance) {} @@ -22,10 +29,15 @@ void TestWorld::BeginPlay() Loging::Log("Load actor: " + i.lock()->GetName()); } - GetActorsByClass()[0].lock()->SetActive(); - //SpawnActorFormClass("TestActor1"); - //std::shared_ptr save_world = save(); - //Loging::Log(save_world->serialize()); + main_camera_ = GetActorsByClass()[0]; + std::shared_ptr lock_main_camera = main_camera_.lock(); + lock_main_camera->SetActive(); + lock_main_camera->OnSetActorLocate.bind( + std::static_pointer_cast(shared_from_this()), + &TestWorld::print_when_camera_move + ); + std::shared_ptr save_world = save(); + Loging::Message(save_world->serialize()); } void TestWorld::Tick(double delta_time) @@ -36,8 +48,12 @@ void TestWorld::Tick(double delta_time) time1 += delta_time; double delta1 = sin(time1); double delta2 = sin(3*time1); - GetActorsByClass()[0].lock()->SetActorLocate(Vector3D{2 + delta2, 2 + delta2, 2 + delta2}); - GetActorsByClass()[0].lock()->SetActorRotate(Vector3D{-3*glm::pi()/4 + glm::pi()/4 * delta1, glm::pi() / -4, 0}); + std::shared_ptr lock_main_camera = main_camera_.lock(); + if (lock_main_camera != nullptr) + { + lock_main_camera->SetActorLocate(Vector3D{2 + delta2, 2 + delta2, 2 + delta2}); + lock_main_camera->SetActorRotate(Vector3D{-3*glm::pi()/4 + glm::pi()/4 * delta1, glm::pi() / -4, 0}); + } time += delta_time; if (time >= 10.0) diff --git a/TestGame/src/Worlds/TestWorld.h b/TestGame/src/Worlds/TestWorld.h index a54a1c1..3a15a39 100644 --- a/TestGame/src/Worlds/TestWorld.h +++ b/TestGame/src/Worlds/TestWorld.h @@ -2,10 +2,16 @@ #include "Game/World/World.hpp" +class Camera; GENERATE_META(TestWorld) + class TestWorld final : public World { double time = 0; + std::weak_ptr main_camera_; + const std::string name_ = "First test world"; + + void print_when_camera_move(const Vector3D& loc_); public: TestWorld(GameInstance& game_instance); diff --git a/UwURenderEngine/RenderEngine/UwURenderEngine.cpp b/UwURenderEngine/RenderEngine/UwURenderEngine.cpp index 9ab2fdd..7e68d0a 100644 --- a/UwURenderEngine/RenderEngine/UwURenderEngine.cpp +++ b/UwURenderEngine/RenderEngine/UwURenderEngine.cpp @@ -1,8 +1,6 @@ #include "UwURenderEngine.hpp" #include -#include -#include #include #include @@ -15,7 +13,6 @@ #include "Game/World/World.hpp" #include "../Game/Actors/Mesh/Mesh.hpp" #include "DeviceFunctions/DeviceFunctions.hpp" -#include "Log/Log.hpp" RENDER_ENGINE_FACTORY_GENERATE(UwURenderEngine) @@ -407,7 +404,7 @@ UwURenderEngine::~UwURenderEngine() void UwURenderEngine::start() { - World* world = core_.GetGameInstance()->GetWorld(); + std::shared_ptr world = core_.GetGameInstance()->GetWorld(); std::vector> meshes = world->GetActorsByClass(); for (auto& i : meshes) { diff --git a/UwURenderEngine/RenderEngine/UwURenderEngine.hpp b/UwURenderEngine/RenderEngine/UwURenderEngine.hpp index daa75c9..4a9508b 100644 --- a/UwURenderEngine/RenderEngine/UwURenderEngine.hpp +++ b/UwURenderEngine/RenderEngine/UwURenderEngine.hpp @@ -4,11 +4,10 @@ #include "ModelManager.hpp" #include -#include #include +#include #define GLM_FORCE_RADIANS -#include #include #include "VkObjects/DescriptorSetLayout.hpp"