diff --git a/lib/Core/Foundation/Application.cpp b/lib/Core/Foundation/Application.cpp index c8ce9a8..c264adb 100644 --- a/lib/Core/Foundation/Application.cpp +++ b/lib/Core/Foundation/Application.cpp @@ -7,12 +7,14 @@ void Core::Application::Bootstrap() m_booted = true; + OnStarting(); + for (const auto& feature : GetRegistered()) { feature->OnBootstrap(); } - OnBootstrap(); + OnStarted(); } void Core::Application::Shutdown() @@ -20,13 +22,15 @@ void Core::Application::Shutdown() if (!m_booted) return; - OnShutdown(); + OnStopping(); for (const auto& feature : GetRegistered()) { feature->OnShutdown(); } + OnStopped(); + m_booted = false; } diff --git a/lib/Core/Foundation/Application.hpp b/lib/Core/Foundation/Application.hpp index b2a1f39..b38eaf0 100644 --- a/lib/Core/Foundation/Application.hpp +++ b/lib/Core/Foundation/Application.hpp @@ -21,8 +21,10 @@ class Application : public Registry protected: void OnRegistered(const Core::SharedPtr& aFeature) override; - virtual void OnBootstrap() {}; - virtual void OnShutdown() {}; + virtual void OnStarting() {}; + virtual void OnStarted() {}; + virtual void OnStopping() {}; + virtual void OnStopped() {}; private: bool m_booted = false; diff --git a/lib/Core/Raw.hpp b/lib/Core/Raw.hpp index 60c8bc3..909f729 100644 --- a/lib/Core/Raw.hpp +++ b/lib/Core/Raw.hpp @@ -80,6 +80,28 @@ class RawFunc : public RawFunc using Base::Base; }; +template +class RawVFunc {}; + +template +class RawVFunc : public RawBase +{ +public: + using Type = R (*)(C*, Args...); + using Callable = Type; + + static constexpr uintptr_t offset = A; + + constexpr RawVFunc() = default; + + R operator()(C* aContext, Args&&... aArgs) const + { + auto vft = *reinterpret_cast(aContext); + auto callable = *reinterpret_cast(vft + offset); + return callable(aContext, std::forward(aArgs)...); + } +}; + template class RawPtr : public RawBase { @@ -167,12 +189,12 @@ class OffsetPtr static constexpr bool indirect = std::is_pointer_v; constexpr OffsetPtr(uintptr_t aBase) - : addr(aBase + offset) + : address(aBase + offset) { } constexpr OffsetPtr(void* aBase) - : addr(reinterpret_cast(aBase) + offset) + : address(reinterpret_cast(aBase) + offset) { } @@ -234,7 +256,7 @@ class OffsetPtr [[nodiscard]] inline uintptr_t GetAddress() const noexcept { - return addr; + return address; } inline static Type* Get(void* aBase) @@ -247,6 +269,6 @@ class OffsetPtr return OffsetPtr(aBase); } - uintptr_t addr; + uintptr_t address; }; } diff --git a/lib/Red/TypeInfo/Invocation.hpp b/lib/Red/TypeInfo/Invocation.hpp index c5a02f0..b709790 100644 --- a/lib/Red/TypeInfo/Invocation.hpp +++ b/lib/Red/TypeInfo/Invocation.hpp @@ -6,6 +6,13 @@ namespace Red { namespace Detail { +constexpr auto TDBIDHelper = Red::CName("gamedataTDBIDHelper"); + +constexpr bool IsFakeStatic(Red::CName aTypeName) +{ + return aTypeName == TDBIDHelper; +} + inline CBaseFunction* GetFunction(CClass* aType, CName aName) { if (aType) @@ -39,6 +46,11 @@ inline CBaseFunction* GetStaticFunction(CClass* aType, CName aName) } } + if (IsFakeStatic(aType->name)) + { + return GetFunction(aType, aName); + } + if (aType->parent) { return GetStaticFunction(aType->parent, aName); @@ -73,8 +85,16 @@ inline bool CallFunction(CBaseFunction* aFunc, IScriptable* aContext, Args&&... { const auto& func = reinterpret_cast(aFunc); - if (!aContext || !aContext->GetType()->IsA(func->parent)) - return false; + if (!IsFakeStatic(func->parent->name)) + { + if (!aContext || !aContext->GetType()->IsA(func->parent)) + return false; + } + else + { + static char s_dummyContext[sizeof(Red::IScriptable)]{}; + aContext = reinterpret_cast(&s_dummyContext); + } } CStack stack(aContext);