#include #include namespace psemek::ecs::detail { table::table(std::vector> columns) { component_hasher hasher; for (auto & column : columns) { auto uuid = column->uuid(); hasher(uuid); component_uuid_to_column_.insert({uuid, column.get()}); if (!column->copy_constructible()) non_copyable_components_.push_back(column->type()); } 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; } std::size_t table::copy_row(handle handle, table * from, std::size_t from_row) { for (std::size_t i = 0; i < columns_.size(); ++i) { auto from_column = from->columns_[i].get(); columns_[i]->insert_rows(from_column->data() + from_column->stride() * from_row, 1); } 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 table::grab_remove_queue() { return std::move(remove_queue_); } std::unique_ptr table::clone() const { std::vector> columns; for (auto const & column : columns_) columns.push_back(column->clone()); return std::make_unique
(std::move(columns)); } table * table::get_delayed_table() { if (!delayed_table_) delayed_table_ = clone(); return delayed_table_.get(); } util::span 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}; } std::vector const & table::non_copyable_components() const { return non_copyable_components_; } }