Skip to content

Commit

Permalink
Merge pull request #98 from psiberx/master
Browse files Browse the repository at this point in the history
Add NodeRef
  • Loading branch information
wopss authored Nov 21, 2023
2 parents 21dbf43 + 86fa042 commit 7947d3a
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 6 deletions.
31 changes: 31 additions & 0 deletions include/RED4ext/DynArray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ struct DynArray
{
}

DynArray(std::initializer_list<T> aItems, Memory::IAllocator* aAllocator = nullptr)
: DynArray(aAllocator)
{
Reserve(aItems.size());

for (const auto& item : aItems)
{
EmplaceBack(item);
}
}

DynArray(const DynArray& aOther)
: DynArray(aOther.GetAllocator())
{
Expand Down Expand Up @@ -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
Expand Down
7 changes: 1 addition & 6 deletions include/RED4ext/NativeTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <RED4ext/HashMap.hpp>
#include <RED4ext/Hashing/CRC.hpp>
#include <RED4ext/InstanceType.hpp>
#include <RED4ext/NodeRef.hpp>
#include <RED4ext/ResourceReference.hpp>
#include <RED4ext/Unks.hpp>

Expand Down Expand Up @@ -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
Expand Down
125 changes: 125 additions & 0 deletions include/RED4ext/NodeRef.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#pragma once

#include <cstdint>

#include <RED4ext/Common.hpp>
#include <RED4ext/HashMap.hpp>

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<typename T>
struct HashMapHash<T, std::enable_if_t<std::is_same_v<T, NodeRef>>>
{
uint32_t operator()(const T& aKey) const noexcept
{
return static_cast<uint32_t>(aKey) ^ ((aKey >> 32) & 0xFFFFFFFF);
}
};
} // namespace RED4ext

0 comments on commit 7947d3a

Please sign in to comment.