Separate ordered & unordered component hashes in ecs

This commit is contained in:
Nikita Lisitsa 2024-11-18 16:55:39 +03:00
parent 3359aaa62d
commit ad752f0ea1
6 changed files with 51 additions and 13 deletions

View file

@ -0,0 +1,39 @@
#pragma once
#include <psemek/util/uuid.hpp>
#include <psemek/util/hash.hpp>
namespace psemek::ecs::detail
{
template <bool With>
struct ordered_component_hasher
{
std::size_t result = 0xb6113227befa663bull;
void operator()(util::uuid const & uuid)
{
auto hash = std::hash<util::uuid>{}(uuid);
if (!With)
hash = ~hash;
util::hash_combine(result, hash);
}
};
template <bool With, typename UUIDs>
std::size_t ordered_component_hash(UUIDs const & uuids)
{
ordered_component_hasher<With> hasher;
for (auto const & uuid : uuids)
hasher(uuid);
return hasher.result;
}
template <typename WithUUIDs, typename WithoutUUIDs>
std::size_t ordered_component_hash(WithUUIDs const & with_uuids, WithoutUUIDs const & without_uuids)
{
return ordered_component_hash<true>(with_uuids) ^ ordered_component_hash<false>(without_uuids);
}
}

View file

@ -1,7 +1,7 @@
#pragma once
#include <psemek/ecs/detail/query_cache.hpp>
#include <psemek/ecs/detail/component_hash.hpp>
#include <psemek/ecs/detail/ordered_component_hash.hpp>
#include <psemek/ecs/detail/table_container.hpp>
#include <psemek/util/hash_table.hpp>
@ -14,7 +14,7 @@ namespace psemek::ecs::detail
{
std::size_t operator()(std::pair<util::span<util::uuid const>, util::span<util::uuid const>> const & uuids) const
{
return component_hash(uuids.first, uuids.second);
return ordered_component_hash(uuids.first, uuids.second);
}
std::size_t operator()(std::shared_ptr<query_cache> const & cache) const
@ -55,7 +55,7 @@ namespace psemek::ecs::detail
cache->with_uuids.assign(with_uuids.begin(), with_uuids.end());
cache->without_uuids.assign(without_uuids.begin(), without_uuids.end());
cache->hash = component_hash(with_uuids, without_uuids);
cache->hash = ordered_component_hash(with_uuids, without_uuids);
table_container.apply([&](table & table){
cache->add(&table);

View file

@ -1,7 +1,6 @@
#pragma once
#include <psemek/ecs/handle.hpp>
#include <psemek/ecs/detail/component_hash.hpp>
#include <psemek/ecs/detail/column.hpp>
#include <psemek/ecs/detail/callback.hpp>
#include <psemek/util/uuid.hpp>

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/ecs/detail/component_hash.hpp>
#include <psemek/ecs/detail/unordered_component_hash.hpp>
#include <psemek/ecs/detail/table.hpp>
#include <psemek/util/hash_table.hpp>
@ -11,7 +11,7 @@ namespace psemek::ecs::detail
{
std::size_t operator()(util::span<util::uuid const> const & uuids) const
{
return component_hash<true>(uuids);
return unordered_component_hash<true>(uuids);
}
std::size_t operator()(std::unique_ptr<table> const & table) const

View file

@ -7,7 +7,7 @@ namespace psemek::ecs::detail
{
template <bool With>
struct component_hasher
struct unordered_component_hasher
{
std::size_t result = 0xcd5694d2b3f3443eull;
@ -21,18 +21,18 @@ namespace psemek::ecs::detail
};
template <bool With, typename UUIDs>
std::size_t component_hash(UUIDs const & uuids)
std::size_t unordered_component_hash(UUIDs const & uuids)
{
component_hasher<With> hasher;
unordered_component_hasher<With> hasher;
for (auto const & uuid : uuids)
hasher(uuid);
return hasher.result;
}
template <typename WithUUIDs, typename WithoutUUIDs>
std::size_t component_hash(WithUUIDs const & with_uuids, WithoutUUIDs const & without_uuids)
std::size_t unordered_component_hash(WithUUIDs const & with_uuids, WithoutUUIDs const & without_uuids)
{
return component_hash<true>(with_uuids) ^ component_hash<false>(without_uuids);
return unordered_component_hash<true>(with_uuids) ^ unordered_component_hash<false>(without_uuids);
}
}

View file

@ -1,12 +1,12 @@
#include <psemek/ecs/detail/table.hpp>
#include <psemek/ecs/detail/component_hash.hpp>
#include <psemek/ecs/detail/unordered_component_hash.hpp>
namespace psemek::ecs::detail
{
table::table(std::vector<std::unique_ptr<detail::column>> columns)
{
component_hasher<true> hasher;
unordered_component_hasher<true> hasher;
for (std::size_t i = 0; i < columns.size(); ++i)
{
auto const & column = columns[i];