1#ifndef ENTT_ENTITY_SNAPSHOT_HPP
2#define ENTT_ENTITY_SNAPSHOT_HPP
10#include "../config/config.h"
11#include "../container/dense_map.hpp"
12#include "../core/type_traits.hpp"
26template<
typename Registry>
27void orphans(Registry ®istry) {
28 auto view =
registry.template view<typename Registry::entity_type>();
30 for(
auto entt: view) {
54template<
typename Registry>
56 static_assert(!std::is_const_v<Registry>,
"Non-const registry type required");
57 using traits_type =
typename Registry::traits_type;
86 template<typename Type, typename Archive>
89 archive(
static_cast<typename traits_type::entity_type
>(
storage->
size()));
91 if constexpr(std::is_same_v<Type, entity_type>) {
92 archive(
static_cast<typename traits_type::entity_type
>(
storage->in_use()));
99 std::apply([&archive](
auto &&...args) { (archive(std::forward<
decltype(args)>(args)), ...); }, elem);
103 archive(
typename traits_type::entity_type{});
121 template<
typename Type,
typename Archive,
typename It>
123 static_assert(!std::is_same_v<Type, entity_type>,
"Entity types not supported");
126 archive(
static_cast<typename traits_type::entity_type
>(std::distance(first, last)));
128 for(; first != last; ++first) {
131 std::apply([&archive](
auto &&...args) { (archive(std::forward<
decltype(args)>(args)), ...); },
storage->
get_as_tuple(
entt));
137 archive(
typename traits_type::entity_type{});
149 template<
typename Archive>
151 return get<entity_type>(archive);
161 template<
typename... Component,
typename Archive>
163 return (get<Component>(archive), ...);
177 template<
typename... Component,
typename Archive,
typename It>
178 [[deprecated(
"use .get<Type>(archive, first, last) instead")]]
const basic_snapshot &
component(Archive &archive, It first, It last)
const {
179 return (get<Component>(archive, first, last), ...);
196template<
typename Registry>
198 static_assert(!std::is_const_v<Registry>,
"Non-const registry type required");
199 using traits_type =
typename Registry::traits_type;
214 ENTT_ASSERT(reg->empty(),
"Registry must be empty");
231 template<typename Type, typename Archive>
234 typename traits_type::entity_type length{};
238 if constexpr(std::is_same_v<Type, entity_type>) {
239 typename traits_type::entity_type in_use{};
257 ENTT_ASSERT(
entity ==
entt,
"Entity not available for use");
259 if constexpr(Registry::template storage_for_type<Type>::traits_type::page_size == 0u) {
277 template<
typename Archive>
279 return get<entity_type>(archive);
293 template<
typename... Component,
typename Archive>
295 return (get<Component>(archive), ...);
309 internal::orphans(*reg);
333template<
typename Registry>
335 static_assert(!std::is_const_v<Registry>,
"Non-const registry type required");
336 using traits_type =
typename Registry::traits_type;
338 void restore(
typename Registry::entity_type
entt) {
340 if(!reg->valid(remloc[
entity].second)) {
341 remloc[
entity].second = reg->create();
348 template<
typename Container>
349 auto update(
int, Container &container) ->
decltype(
typename Container::mapped_type{}, void()) {
353 for(
auto &&pair: container) {
354 using first_type = std::remove_const_t<
typename std::decay_t<
decltype(pair)>::first_type>;
355 using second_type =
typename std::decay_t<
decltype(pair)>::second_type;
357 if constexpr(std::is_same_v<first_type, entity_type> && std::is_same_v<second_type, entity_type>) {
358 other.emplace(
map(pair.first),
map(pair.second));
359 }
else if constexpr(std::is_same_v<first_type, entity_type>) {
360 other.emplace(
map(pair.first), std::move(pair.second));
362 static_assert(std::is_same_v<second_type, entity_type>,
"Neither the key nor the value are of entity type");
363 other.emplace(std::move(pair.first),
map(pair.second));
368 swap(container, other);
371 template<
typename Container>
372 auto update(
char, Container &container) ->
decltype(
typename Container::value_type{}, void()) {
374 static_assert(std::is_same_v<typename Container::value_type, entity_type>,
"Invalid value type");
376 for(
auto &&
entt: container) {
381 template<
typename Component,
typename Other,
typename Member>
382 void update([[maybe_unused]] Component &instance, [[maybe_unused]] Member Other::*member) {
383 if constexpr(!std::is_same_v<Component, Other>) {
385 }
else if constexpr(std::is_same_v<Member, entity_type>) {
386 instance.*member =
map(instance.*member);
389 update(0, instance.*member);
404 : remloc{source.get_allocator()},
427 template<
typename Type,
typename Archive>
430 typename traits_type::entity_type length{};
435 if constexpr(std::is_same_v<Type, entity_type>) {
436 typename traits_type::entity_type in_use{};
441 for(std::size_t pos{}; pos < in_use; ++pos) {
446 for(std::size_t pos = in_use; pos < length; ++pos) {
450 if(reg->valid(remloc[
entity].second)) {
451 reg->destroy(remloc[
entity].second);
458 for(
auto &&ref: remloc) {
466 if constexpr(Registry::template storage_for_type<Type>::traits_type::page_size == 0u) {
487 template<
typename Archive>
489 return get<entity_type>(archive);
507 template<
typename... Component,
typename Archive,
typename... Member,
typename... Clazz>
510 for(
auto &&ref: remloc) {
514 typename traits_type::entity_type length{};
523 if constexpr(std::remove_reference_t<
decltype(
storage)>::traits_type::page_size == 0u) {
528 (update(elem, member), ...);
561 internal::orphans(*reg);
572 return it != remloc.
cend() && it->second.first ==
entt;
582 return it->second.second;
Utility class for continuous loading.
basic_continuous_loader & operator=(basic_continuous_loader &&)=default
Default move assignment operator.
basic_continuous_loader & shrink()
Helps to purge entities that no longer have a counterpart.
basic_continuous_loader(basic_continuous_loader &&)=default
Default move constructor.
basic_continuous_loader(registry_type &source) noexcept
Constructs an instance that is bound to a given registry.
basic_continuous_loader & component(Archive &archive, Member Clazz::*...member)
Serializes all elements of a type with associated identifiers.
typename registry_type::entity_type entity_type
Underlying entity identifier.
bool contains(entity_type entt) const noexcept
Tests if a loader knows about a given entity.
entity_type map(entity_type entt) const noexcept
Returns the identifier to which an entity refers.
basic_continuous_loader & get(Archive &archive, const id_type id=type_hash< Type >::value())
Restores all elements of a type with associated identifiers.
basic_continuous_loader & entities(Archive &archive)
Restores all identifiers, including those to be recycled.
basic_continuous_loader & orphans()
Destroys those entities that have no components.
Utility class to restore a snapshot as a whole.
basic_snapshot_loader & component(Archive &archive)
Restores all elements of a type with associated identifiers.
basic_snapshot_loader & entities(Archive &archive)
Restores all identifiers, including those to be recycled.
basic_snapshot_loader(registry_type &source) noexcept
Constructs an instance that is bound to a given registry.
typename registry_type::entity_type entity_type
Underlying entity identifier.
basic_snapshot_loader(basic_snapshot_loader &&) noexcept=default
Default move constructor.
basic_snapshot_loader & orphans()
Destroys those entities that have no components.
Utility class to create snapshots from a registry.
basic_snapshot(const registry_type &source) noexcept
Constructs an instance that is bound to a given registry.
typename registry_type::entity_type entity_type
Underlying entity identifier.
const basic_snapshot & component(Archive &archive, It first, It last) const
Serializes all elements of a type with associated identifiers for the entities in a range.
const basic_snapshot & entities(Archive &archive) const
Serializes all identifiers, including those to be recycled.
const basic_snapshot & component(Archive &archive) const
Serializes all elements of a type with associated identifiers.
const basic_snapshot & get(Archive &archive, It first, It last, const id_type id=type_hash< Type >::value()) const
Serializes all elements of a type with associated identifiers for the entities in a range.
basic_snapshot(basic_snapshot &&) noexcept=default
Default move constructor.
pointer data() const noexcept
Direct access to the internal packed array.
size_type size() const noexcept
Returns the number of elements in a sparse set.
bool contains(const entity_type entt) const noexcept
Checks if a sparse set contains an entity.
bool empty() const noexcept
Checks whether a sparse set is empty.
bool remove(const entity_type entt)
Removes an entity from a sparse set if it exists.
Basic storage implementation.
reverse_iterable reach() noexcept
Returns a reverse iterable object to use to visit a storage.
void reserve(const size_type cap) override
Increases the capacity of a storage.
value_type & emplace(const entity_type entt, Args &&...args)
Assigns an entity to a storage and constructs its object.
std::tuple< const value_type & > get_as_tuple(const entity_type entt) const noexcept
Returns the object assigned to an entity as a tuple.
Associative container for key-value pairs with unique keys.
bool contains(const key_type &key) const
Checks if the container contains an element with a given key.
const_iterator cend() const noexcept
Returns an iterator to the end.
iterator find(const key_type &key)
Finds an element with a given key.
iterator erase(const_iterator pos)
Removes an element from a given position.
std::pair< iterator, bool > insert_or_assign(const key_type &key, Arg &&value)
Inserts an element into the container or assigns to the current element if the key already exists.
entity
Default entity identifier.
constexpr entt_traits< Entity >::entity_type to_entity(const Entity value) noexcept
Returns the entity part once converted to the underlying type.
std::uint32_t id_type
Alias declaration for type identifiers.
constexpr null_t null
Compile-time constant for null entities.
basic_view< type_list_transform_t< Get, storage_for >, type_list_transform_t< Exclude, storage_for > > view
Alias declaration for the most common use case.
basic_storage< Type > storage
Alias declaration for the most common use case.
constexpr void swap(compressed_pair< First, Second > &lhs, compressed_pair< First, Second > &rhs)
Swaps two compressed pair objects.
constexpr get_t< Type... > get
Variable template for lists of observed components.
basic_registry<> registry
Alias declaration for the most common use case.