From 280f843fb7e9466cc20bf1afcdf52a8ac244aa2f Mon Sep 17 00:00:00 2001 From: Jiga228 Date: Mon, 22 Jun 2026 14:47:53 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A7=D1=83=D1=82=D0=BA=D0=B0=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D0=B4=D0=B5=D0=BB=D0=B5=D0=B3?= =?UTF-8?q?=D0=B0=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 10 +-- Core/Core/CoreInstance.hpp | 8 +- Core/Delegate/Delegate.h | 175 +++++++++++++++++++++++++++++++++++++ Core/Game/Actors/Actor.cpp | 4 +- 4 files changed, 186 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 330bfec..6785b9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,11 +14,11 @@ if(NOT MSVC) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") endif() -if(MSVC) - add_compile_options(/GR-) -else() - add_compile_options(-fno-rtti) -endif() +#if(MSVC) +# add_compile_options(/GR-) +#else() +# add_compile_options(-fno-rtti) +#endif() if(BUILD_MODE STREQUAL "Engine") add_subdirectory(FastRTTI) diff --git a/Core/Core/CoreInstance.hpp b/Core/Core/CoreInstance.hpp index 38aec00..fe43957 100644 --- a/Core/Core/CoreInstance.hpp +++ b/Core/Core/CoreInstance.hpp @@ -37,14 +37,14 @@ class CoreInstance { const char* main_config_name = "main_config.conf"; MainConfig main_config_; - int countCPU_; + int countCPU_ = 0; // Memory in MB - double memorySize_; + double memorySize_ = 0; std::list modules_; GLFWwindow* window_ = nullptr; - RenderEngineBase* render_engine_; - GameInstance* game_; + RenderEngineBase* render_engine_ = nullptr; + GameInstance* game_ = nullptr; bool is_ready = false; public: diff --git a/Core/Delegate/Delegate.h b/Core/Delegate/Delegate.h index 5c7f626..a25bc7d 100644 --- a/Core/Delegate/Delegate.h +++ b/Core/Delegate/Delegate.h @@ -182,4 +182,179 @@ public: iterator = iterator->next; } } +}; + +/* + * Реализация для случая когда Type_Parameter == void + */ +template<> +class Delegate +{ + class ObjectWasDelete : public std::runtime_error + { + public: + ObjectWasDelete() : std::runtime_error("Delegate (call): Object was delete") {} + }; + + /* + * Базовая структура для записи подптсок + */ + struct BaseListData + { + std::shared_ptr next; + virtual ~BaseListData() = default; + virtual void call() = 0; + }; + + template + struct ObjectListData : public BaseListData + { + using Method = void(Type_Object::*)(); + std::weak_ptr object; + Method method = nullptr; + + ObjectListData() = default; + ObjectListData(std::weak_ptr object, Method method) : object(std::move(object)), method(method) {} + void call() + { + if (auto shared_object = object.lock()) + { + (shared_object.get()->*method)(); + } + else + { + throw ObjectWasDelete(); + } + } + }; + + struct FunctionListData : public BaseListData + { + void(*function)(); + FunctionListData() = default; + FunctionListData(void(*func)()) : function(func) {} + void call() + { + function(); + } + }; + + std::shared_ptr list_head = nullptr; + std::mutex m_list; +public: + template + void bind(std::weak_ptr object, void (Type_Object::*method)()) + { + if (!object.expired() && !method) + return; + + std::lock_guard lock(m_list); + std::shared_ptr old_head = list_head; + list_head = std::make_shared>(object, method); + list_head->next = old_head; + } + + void bind(void(*function)()) + { + if (!function) + return; + + std::lock_guard lock(m_list); + std::shared_ptr old_head = list_head; + list_head = std::make_shared(function); + list_head->next = old_head; + } + + template + void unbind(std::shared_ptr object, void(Type_Object::*method)()) + { + std::lock_guard lock(m_list); + + if (!list_head) + return; + + if (auto object_list_data = dynamic_cast*>(list_head.get())) + { + std::shared_ptr shared_object_list_data = object_list_data->object.lock(); + if (!shared_object_list_data) + { + list_head = list_head->next; + } + else if (shared_object_list_data == object && object_list_data->method == method) + { + list_head = list_head->next; + return; + } + } + + std::shared_ptr old_it = list_head, iterator = list_head->next; + while (iterator) + { + if (auto object_list = dynamic_cast*>(iterator.get())) + { + if (object_list->object.expired()) + old_it->next = iterator->next; + if (object_list->object.lock() == object && object_list->method == method) + { + old_it->next = iterator->next; + return; + } + } + old_it = iterator; + iterator = iterator->next; + } + } + + void unbind(void(*func)()) + { + std::lock_guard lock(m_list); + + if (!list_head) + return; + + if (auto function_list_data = dynamic_cast(list_head.get())) + { + if (function_list_data->function == func) + { + list_head = list_head->next; + return; + } + } + + std::shared_ptr old_it = list_head, iterator = list_head->next; + while (iterator) + { + if (auto function_list = dynamic_cast(iterator.get())) + { + if (function_list->function == func) + { + old_it->next = iterator->next; + return; + } + } + iterator = iterator->next; + } + } + + void call() + { + std::lock_guard lock(m_list); + std::shared_ptr old_head, iterator = list_head; + while(iterator) + { + try { + iterator->call(); + } catch (const ObjectWasDelete&) { + if (iterator == list_head) + { + list_head = list_head->next; + } + else + { + old_head->next = iterator->next; + } + } + iterator = iterator->next; + } + } }; \ No newline at end of file diff --git a/Core/Game/Actors/Actor.cpp b/Core/Game/Actors/Actor.cpp index 19f17cd..2ff3b3c 100644 --- a/Core/Game/Actors/Actor.cpp +++ b/Core/Game/Actors/Actor.cpp @@ -40,13 +40,13 @@ void Actor::Tick(double delta_time) void Actor::SetActorLocate(const Vector3D& loc) noexcept { *this->loc_ = loc; - OnSetActorLocate.Call(loc); + OnSetActorLocate.call(loc); } void Actor::SetActorRotate(const Vector3D& rot) noexcept { *this->rot_ = rot; - OnSetActorRotate.Call(rot); + OnSetActorRotate.call(rot); } void Actor::AddTag(const std::string& tag) noexcept