Class basic_snapshot_loader

Synopsis

#include <src/entt/entity/snapshot.hpp>

template<typename Entity>
class basic_snapshot_loader

Description

Utility class to restore a snapshot as a whole.

A snapshot loader requires that the destination registry be empty and loads all the data at once while keeping intact the identifiers that the entities originally had.
An example of use is the implementation of a save/restore utility.

Template Parameters:

Entity - A valid entity type (see entt_traits for more details).

Methods

basic_snapshot_loaderConstructs an instance that is bound to a given registry.
componentRestores components and assigns them to the right entities.
entitiesRestores entities that were in use during serialization.
operator=Default move assignment operator.
orphansDestroys those entities that have no components.

Source

Lines 162-281 in src/entt/entity/snapshot.hpp.

template<typename Entity>
class basic_snapshot_loader {
    /*! @brief A registry is allowed to create snapshot loaders. */
    friend class basic_registry<Entity>;

    using traits_type = entt_traits<Entity>;

    template<typename Type, typename Archive>
    void assign(Archive &archive) const {
        typename traits_type::entity_type length{};
        archive(length);

        entity_type entt{};

        if constexpr(std::is_empty_v<Type>) {
            while(length--) {
                archive(entt);
                const auto entity = reg->valid(entt) ? entt : reg->create(entt);
                ENTT_ASSERT(entity == entt);
                reg->template emplace<Type>(entity);
            }
        } else {
            Type instance{};

            while(length--) {
                archive(entt, instance);
                const auto entity = reg->valid(entt) ? entt : reg->create(entt);
                ENTT_ASSERT(entity == entt);
                reg->template emplace<Type>(entity, std::move(instance));
            }
        }
    }

public:
    /*! @brief Underlying entity identifier. */
    using entity_type = Entity;

    /**
     * @brief Constructs an instance that is bound to a given registry.
     * @param source A valid reference to a registry.
     */
    basic_snapshot_loader(basic_registry<entity_type> &source) ENTT_NOEXCEPT
        : reg{&source}
    {
        // restoring a snapshot as a whole requires a clean registry
        ENTT_ASSERT(reg->empty());
    }

    /*! @brief Default move constructor. */
    basic_snapshot_loader(basic_snapshot_loader &&) = default;

    /*! @brief Default move assignment operator. @return This loader. */
    basic_snapshot_loader & operator=(basic_snapshot_loader &&) = default;

    /**
     * @brief Restores entities that were in use during serialization.
     *
     * This function restores the entities that were in use during serialization
     * and gives them the versions they originally had.
     *
     * @tparam Archive Type of input archive.
     * @param archive A valid reference to an input archive.
     * @return A valid loader to continue restoring data.
     */
    template<typename Archive>
    const basic_snapshot_loader & entities(Archive &archive) const {
        typename traits_type::entity_type length{};

        archive(length);
        std::vector<entity_type> all(length);

        for(decltype(length) pos{}; pos < length; ++pos) {
            archive(all[pos]);
        }

        reg->assign(all.cbegin(), all.cend());

        return *this;
    }

    /**
     * @brief Restores components and assigns them to the right entities.
     *
     * The template parameter list must be exactly the same used during
     * serialization. In the event that the entity to which the component is
     * assigned doesn't exist yet, the loader will take care to create it with
     * the version it originally had.
     *
     * @tparam Component Types of components to restore.
     * @tparam Archive Type of input archive.
     * @param archive A valid reference to an input archive.
     * @return A valid loader to continue restoring data.
     */
    template<typename... Component, typename Archive>
    const basic_snapshot_loader & component(Archive &archive) const {
        (assign<Component>(archive), ...);
        return *this;
    }

    /**
     * @brief Destroys those entities that have no components.
     *
     * In case all the entities were serialized but only part of the components
     * was saved, it could happen that some of the entities have no components
     * once restored.<br/>
     * This functions helps to identify and destroy those entities.
     *
     * @return A valid loader to continue restoring data.
     */
    const basic_snapshot_loader & orphans() const {
        reg->orphans([this](const auto entt) {
            reg->destroy(entt);
        });

        return *this;
    }

private:
    basic_registry<entity_type> *reg;
};





Add Discussion

Log in to comment