#pragma once #include #include #include namespace rage { class scrNativeCallContext { public: constexpr void reset() { m_ArgCount = 0; m_DataCount = 0; } template constexpr void PushArg(T&& value) { static_assert(sizeof(T) <= sizeof(std::uint64_t)); *reinterpret_cast>*>(reinterpret_cast(m_Args) + (m_ArgCount++)) = std::forward(value); } template constexpr T& GetArg(std::size_t index) { static_assert(sizeof(T) <= sizeof(std::uint64_t)); return *reinterpret_cast(reinterpret_cast(m_Args) + index); } template constexpr void SetArg(std::size_t index, T&& value) { static_assert(sizeof(T) <= sizeof(std::uint64_t)); *reinterpret_cast>*>(reinterpret_cast(m_Args) + index) = std::forward(value); } template constexpr T* GetReturnValue() { return reinterpret_cast(m_ReturnValue); } template constexpr void SetReturnValue(T&& value) { *reinterpret_cast>*>(m_ReturnValue) = std::forward(value); } protected: void* m_ReturnValue; std::uint32_t m_ArgCount; void* m_Args; std::int32_t m_DataCount; std::uint32_t m_Data[48]; }; static_assert(sizeof(scrNativeCallContext) == 0xE0); using scrNativeHash = std::int64_t; using scrNativePair = std::pair; using scrNativeHandler = void(*)(scrNativeCallContext*); }