From 28a903973d766675cbc5e0345900dcdba5a92610 Mon Sep 17 00:00:00 2001 From: pv Date: Fri, 17 Nov 2023 11:43:31 +0300 Subject: [PATCH 1/2] Implement NodeRef --- include/RED4ext/NativeTypes.hpp | 7 +- include/RED4ext/NodeRef.hpp | 125 ++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 include/RED4ext/NodeRef.hpp diff --git a/include/RED4ext/NativeTypes.hpp b/include/RED4ext/NativeTypes.hpp index b40a980b5..828ad0e2a 100644 --- a/include/RED4ext/NativeTypes.hpp +++ b/include/RED4ext/NativeTypes.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -220,12 +221,6 @@ struct MessageResourcePath }; RED4EXT_ASSERT_SIZE(MessageResourcePath, 0x8); -struct NodeRef -{ - uint64_t hash; // 00 -}; -RED4EXT_ASSERT_SIZE(NodeRef, 0x8); - struct RuntimeEntityRef { int64_t unk00; // 00 diff --git a/include/RED4ext/NodeRef.hpp b/include/RED4ext/NodeRef.hpp new file mode 100644 index 000000000..ea84192fa --- /dev/null +++ b/include/RED4ext/NodeRef.hpp @@ -0,0 +1,125 @@ +#pragma once + +#include + +#include +#include + +namespace RED4ext +{ +struct NodeRef +{ + static constexpr auto GlobalRoot = FNV1a64("$"); // NodeRef("$") + static constexpr auto RelativeRoot = FNV1a64("~"); // NodeRef("~") + + constexpr NodeRef(uint64_t aHash = 0) noexcept + : hash(aHash) + { + } + + constexpr NodeRef(const char* aNodeRefStr) noexcept + : hash(Hash(aNodeRefStr)) + { + } + + constexpr operator uint64_t() const noexcept + { + return hash; + } + + constexpr size_t operator()(const NodeRef& aNodeRef) const + { + return aNodeRef.hash; + } + + constexpr NodeRef& operator=(const uint64_t aRhs) noexcept + { + hash = aRhs; + return *this; + } + + constexpr NodeRef& operator=(const char* aRhs) noexcept + { + *this = NodeRef(aRhs); + return *this; + } + + constexpr NodeRef& operator=(const NodeRef& aRhs) noexcept + { + hash = aRhs.hash; + return *this; + } + + constexpr bool operator==(const NodeRef& aRhs) const noexcept + { + return hash == aRhs.hash; + } + + constexpr bool operator!=(const NodeRef& aRhs) const noexcept + { + return !(*this == aRhs); + } + + constexpr bool operator==(const uint64_t aRhs) const noexcept + { + return hash == aRhs; + } + + constexpr bool operator!=(const uint64_t aRhs) const noexcept + { + return hash != aRhs; + } + + [[nodiscard]] constexpr bool IsEmpty() const noexcept + { + return hash == 0; + } + + static constexpr uint64_t Hash(const char* aNodeRefStr) + { + constexpr uint64_t prime = 0x100000001b3; + constexpr uint64_t seed = 0xCBF29CE484222325; + + uint64_t hash = seed; + + while (aNodeRefStr && *aNodeRefStr) + { + if (*aNodeRefStr == '#') + { + ++aNodeRefStr; + continue; + } + + if (*aNodeRefStr == ';') + { + ++aNodeRefStr; + + while (*aNodeRefStr && *aNodeRefStr != '/') + ++aNodeRefStr; + + if (!*aNodeRefStr) + break; + } + + hash ^= *aNodeRefStr; + hash *= prime; + + ++aNodeRefStr; + } + + return hash == seed ? 0 : hash; + } + + uint64_t hash; +}; +RED4EXT_ASSERT_SIZE(NodeRef, 0x8); + +template +struct HashMapHash>> +{ + uint32_t operator()(const T& aKey) const noexcept + { + return static_cast(aKey) ^ ((aKey >> 32) & 0xFFFFFFFF); + } +}; +} // namespace RED4ext From 86fa042361d3c87e14c93f4b90679b3b67c49af8 Mon Sep 17 00:00:00 2001 From: pv Date: Fri, 17 Nov 2023 11:44:07 +0300 Subject: [PATCH 2/2] Add convenience methods for DynArray --- include/RED4ext/DynArray.hpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/include/RED4ext/DynArray.hpp b/include/RED4ext/DynArray.hpp index 629fd7d95..7a0f0433f 100644 --- a/include/RED4ext/DynArray.hpp +++ b/include/RED4ext/DynArray.hpp @@ -27,6 +27,17 @@ struct DynArray { } + DynArray(std::initializer_list aItems, Memory::IAllocator* aAllocator = nullptr) + : DynArray(aAllocator) + { + Reserve(aItems.size()); + + for (const auto& item : aItems) + { + EmplaceBack(item); + } + } + DynArray(const DynArray& aOther) : DynArray(aOther.GetAllocator()) { @@ -239,6 +250,26 @@ struct DynArray } #pragma endregion + T& Front() + { + return *entries; + } + + const T& Front() const + { + return *entries; + } + + T& Back() + { + return *(entries + size - 1); + } + + const T& Back() const + { + return *(entries + size - 1); + } + T* entries; // 00 uint32_t capacity; // 08 uint32_t size; // 0C