113 lines
2.6 KiB
C++
113 lines
2.6 KiB
C++
#include <psemek/ecs/detail/table.hpp>
|
|
#include <psemek/ecs/detail/component_hash.hpp>
|
|
|
|
namespace psemek::ecs::detail
|
|
{
|
|
|
|
table::table(std::vector<std::unique_ptr<detail::column>> columns)
|
|
{
|
|
component_hasher<true> hasher;
|
|
for (auto & column : columns)
|
|
{
|
|
auto uuid = column->uuid();
|
|
hasher(uuid);
|
|
component_uuid_to_column_.insert({uuid, column.get()});
|
|
}
|
|
hash_ = hasher.result;
|
|
|
|
columns_ = std::move(columns);
|
|
}
|
|
|
|
detail::column * table::column(util::uuid const & uuid) const
|
|
{
|
|
if (auto it = component_uuid_to_column_.find(uuid); it != component_uuid_to_column_.end())
|
|
return it->second;
|
|
return nullptr;
|
|
}
|
|
|
|
std::size_t table::push_row(handle handle)
|
|
{
|
|
for (auto & column : columns_)
|
|
column->push_row();
|
|
entity_handles_.push_back(handle);
|
|
return entity_handles_.size() - 1;
|
|
}
|
|
|
|
std::size_t table::move_row(handle handle, table * from, std::size_t from_row)
|
|
{
|
|
for (auto & column : columns_)
|
|
{
|
|
if (auto other_column = from->column(column->uuid()))
|
|
column->emplace_rows(other_column->data() + other_column->stride() * from_row, 1);
|
|
else
|
|
column->push_row();
|
|
}
|
|
entity_handles_.push_back(handle);
|
|
return entity_handles_.size() - 1;
|
|
}
|
|
|
|
void table::swap_rows(std::size_t row1, std::size_t row2)
|
|
{
|
|
for (auto & column : columns_)
|
|
column->swap_rows(row1, row2);
|
|
std::swap(entity_handles_[row1], entity_handles_[row2]);
|
|
}
|
|
|
|
void table::pop_row()
|
|
{
|
|
for (auto & column : columns_)
|
|
column->pop_row();
|
|
entity_handles_.pop_back();
|
|
}
|
|
|
|
void table::clear()
|
|
{
|
|
for (auto & column : columns_)
|
|
column->clear();
|
|
entity_handles_.clear();
|
|
}
|
|
|
|
void table::push_remove(std::uint32_t row)
|
|
{
|
|
remove_queue_.push_back(row);
|
|
}
|
|
|
|
std::vector<std::uint32_t> table::grab_remove_queue()
|
|
{
|
|
return std::move(remove_queue_);
|
|
}
|
|
|
|
std::unique_ptr<table> table::clone() const
|
|
{
|
|
std::vector<std::unique_ptr<detail::column>> columns;
|
|
for (auto const & column : columns_)
|
|
columns.push_back(column->clone());
|
|
return std::make_unique<table>(std::move(columns));
|
|
}
|
|
|
|
table * table::get_delayed_table()
|
|
{
|
|
if (!delayed_table_)
|
|
delayed_table_ = clone();
|
|
return delayed_table_.get();
|
|
}
|
|
|
|
util::span<handle const> table::flush_delayed()
|
|
{
|
|
if (!delayed_table_)
|
|
return {};
|
|
|
|
std::size_t count = delayed_table_->row_count();
|
|
for (std::size_t i = 0; i < columns_.size(); ++i)
|
|
{
|
|
auto * src_column = delayed_table_->columns_[i].get();
|
|
columns_[i]->emplace_rows(src_column->data(), count);
|
|
}
|
|
entity_handles_.insert(entity_handles_.end(), delayed_table_->entity_handles_.begin(), delayed_table_->entity_handles_.end());
|
|
|
|
delayed_table_->clear();
|
|
|
|
return {entity_handles_.data() + entity_handles_.size() - count, count};
|
|
}
|
|
|
|
}
|