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 #pragma once
#include <psemek/ecs/detail/query_cache.hpp> #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/ecs/detail/table_container.hpp>
#include <psemek/util/hash_table.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 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 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->with_uuids.assign(with_uuids.begin(), with_uuids.end());
cache->without_uuids.assign(without_uuids.begin(), without_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){ table_container.apply([&](table & table){
cache->add(&table); cache->add(&table);

View file

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

View file

@ -1,6 +1,6 @@
#pragma once #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/ecs/detail/table.hpp>
#include <psemek/util/hash_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 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 std::size_t operator()(std::unique_ptr<table> const & table) const

View file

@ -7,7 +7,7 @@ namespace psemek::ecs::detail
{ {
template <bool With> template <bool With>
struct component_hasher struct unordered_component_hasher
{ {
std::size_t result = 0xcd5694d2b3f3443eull; std::size_t result = 0xcd5694d2b3f3443eull;
@ -21,18 +21,18 @@ namespace psemek::ecs::detail
}; };
template <bool With, typename UUIDs> 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) for (auto const & uuid : uuids)
hasher(uuid); hasher(uuid);
return hasher.result; return hasher.result;
} }
template <typename WithUUIDs, typename WithoutUUIDs> 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/table.hpp>
#include <psemek/ecs/detail/component_hash.hpp> #include <psemek/ecs/detail/unordered_component_hash.hpp>
namespace psemek::ecs::detail namespace psemek::ecs::detail
{ {
table::table(std::vector<std::unique_ptr<detail::column>> columns) 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) for (std::size_t i = 0; i < columns.size(); ++i)
{ {
auto const & column = columns[i]; auto const & column = columns[i];