mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 03:29:19 +02:00
ECS System WIP
This commit is contained in:
63
registry/FName.h
Normal file
63
registry/FName.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "NameRegistry.h"
|
||||
|
||||
struct FName
|
||||
{
|
||||
using value_type = uint64_t;
|
||||
|
||||
static constexpr value_type INVALID_ID = 0;
|
||||
|
||||
value_type id = INVALID_ID;
|
||||
|
||||
constexpr FName() noexcept = default;
|
||||
|
||||
constexpr explicit FName(value_type value) noexcept
|
||||
: id(value)
|
||||
{
|
||||
}
|
||||
|
||||
FName(const char* text)
|
||||
: id(text ? NameRegistry::GetOrCreate(text) : INVALID_ID)
|
||||
{
|
||||
}
|
||||
|
||||
FName(const std::string& text)
|
||||
: id(text.empty() ? INVALID_ID : NameRegistry::GetOrCreate(text))
|
||||
{
|
||||
}
|
||||
|
||||
FName(std::string_view text)
|
||||
: id(text.empty() ? INVALID_ID : NameRegistry::GetOrCreate(text))
|
||||
{
|
||||
}
|
||||
|
||||
constexpr bool IsValid() const noexcept
|
||||
{
|
||||
return id != INVALID_ID;
|
||||
}
|
||||
|
||||
constexpr value_type GetId() const noexcept
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
const std::string& ToString() const
|
||||
{
|
||||
return NameRegistry::GetString(id);
|
||||
}
|
||||
|
||||
constexpr bool operator==(const FName& other) const noexcept
|
||||
{
|
||||
return id == other.id;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const FName& other) const noexcept
|
||||
{
|
||||
return id != other.id;
|
||||
}
|
||||
};
|
||||
41
registry/NameHash.h
Normal file
41
registry/NameHash.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
constexpr uint64_t FNV1A_OFFSET_BASIS_64 = 14695981039346656037ull;
|
||||
constexpr uint64_t FNV1A_PRIME_64 = 1099511628211ull;
|
||||
|
||||
constexpr uint64_t HashLiteral(const char* str, std::size_t len) noexcept
|
||||
{
|
||||
uint64_t hash = FNV1A_OFFSET_BASIS_64;
|
||||
for (std::size_t i = 0; i < len; ++i)
|
||||
{
|
||||
hash ^= static_cast<unsigned char>(str[i]);
|
||||
hash *= FNV1A_PRIME_64;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
constexpr uint64_t HashLiteral(const char* str) noexcept
|
||||
{
|
||||
uint64_t hash = FNV1A_OFFSET_BASIS_64;
|
||||
while (*str)
|
||||
{
|
||||
hash ^= static_cast<unsigned char>(*str++);
|
||||
hash *= FNV1A_PRIME_64;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
inline uint64_t HashRuntime(std::string_view str) noexcept
|
||||
{
|
||||
uint64_t hash = FNV1A_OFFSET_BASIS_64;
|
||||
for (char c : str)
|
||||
{
|
||||
hash ^= static_cast<unsigned char>(c);
|
||||
hash *= FNV1A_PRIME_64;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
11
registry/NameLiteral.h
Normal file
11
registry/NameLiteral.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "FName.h"
|
||||
#include "NameHash.h"
|
||||
|
||||
consteval FName operator"" _name(const char* str, std::size_t len)
|
||||
{
|
||||
return FName{ HashLiteral(str, len) };
|
||||
}
|
||||
52
registry/NameRegistry.cpp
Normal file
52
registry/NameRegistry.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "NameRegistry.h"
|
||||
#include "NameHash.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
uint64_t NameRegistry::GetOrCreate(std::string_view name)
|
||||
{
|
||||
if (name.empty())
|
||||
return 0;
|
||||
|
||||
const uint64_t hash = HashRuntime(name);
|
||||
|
||||
std::lock_guard<std::mutex> lock(GetMutex());
|
||||
auto& map = GetMap();
|
||||
|
||||
auto [it, inserted] = map.emplace(hash, std::string(name));
|
||||
if (!inserted)
|
||||
{
|
||||
assert(it->second == name && "Name hash collision detected");
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
const std::string& NameRegistry::GetString(uint64_t id)
|
||||
{
|
||||
static const std::string Empty;
|
||||
|
||||
if (id == 0)
|
||||
return Empty;
|
||||
|
||||
std::lock_guard<std::mutex> lock(GetMutex());
|
||||
auto& map = GetMap();
|
||||
|
||||
auto it = map.find(id);
|
||||
if (it != map.end())
|
||||
return it->second;
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
||||
std::unordered_map<uint64_t, std::string>& NameRegistry::GetMap()
|
||||
{
|
||||
static std::unordered_map<uint64_t, std::string> map;
|
||||
return map;
|
||||
}
|
||||
|
||||
std::mutex& NameRegistry::GetMutex()
|
||||
{
|
||||
static std::mutex mutex;
|
||||
return mutex;
|
||||
}
|
||||
18
registry/NameRegistry.h
Normal file
18
registry/NameRegistry.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
class NameRegistry
|
||||
{
|
||||
public:
|
||||
static uint64_t GetOrCreate(std::string_view name);
|
||||
static const std::string& GetString(uint64_t id);
|
||||
|
||||
private:
|
||||
static std::unordered_map<uint64_t, std::string>& GetMap();
|
||||
static std::mutex& GetMutex();
|
||||
};
|
||||
Reference in New Issue
Block a user