Created
November 14, 2018 22:20
-
-
Save ArnCarveris/414bfbab2be5a367346942baf9bb63c7 to your computer and use it in GitHub Desktop.
EnTT Entity Exporter/Importer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef ENTT_ENTITY_EXPORTER_HPP | |
| #define ENTT_ENTITY_EXPORTER_HPP | |
| #include <array> | |
| #include <cstddef> | |
| #include <utility> | |
| #include <cassert> | |
| #include <iterator> | |
| #include <type_traits> | |
| #include <unordered_map> | |
| #include "../config/config.h" | |
| #include "entt_traits.hpp" | |
| #include "utility.hpp" | |
| namespace entt { | |
| /** | |
| * @brief Forward declaration of the registry class. | |
| */ | |
| template<typename> | |
| class Registry; | |
| template<typename Entity> | |
| class Prototype; | |
| template<typename Entity, typename KeyType, template<class> class KeyValuePair> | |
| class Exporter final { | |
| friend class Registry<Entity>; | |
| Exporter(const Registry<Entity> ®istry) ENTT_NOEXCEPT | |
| : registry{ registry } | |
| {} | |
| template<typename Component> | |
| inline KeyValuePair<Component> make_kvp(KeyType key, Component&& component) const { | |
| return KeyValuePair<Component>{key, component}; | |
| } | |
| template<typename Component, typename Archive> | |
| void component(Archive &archive, const Entity& entity, KeyType key) const { | |
| if (registry.template has<Component>(entity)) { | |
| archive(make_kvp(key, registry.template get<Component>(entity))); | |
| } | |
| } | |
| template<typename Component, typename Archive> | |
| void component(Archive &archive, const Prototype<Entity>& prototype, KeyType key) const { | |
| if (prototype.has<Component>()) { | |
| archive(make_kvp(key, prototype.get<Component>())); | |
| } | |
| } | |
| template<typename... Component, typename Archive, typename Source, std::size_t... Indexes> | |
| void components(Archive &archive, const Source& source, const std::array<KeyType, sizeof...(Component)>& keys, std::index_sequence<Indexes...>) const { | |
| using accumulator_type = int[]; | |
| accumulator_type accumulator = { (component<Component>(archive, source, keys[Indexes]), 0)... }; | |
| (void)accumulator; | |
| } | |
| template<typename Tag, typename Archive> | |
| void tag(Archive &archive, const Entity& entity, KeyType key) const { | |
| if (registry.template has<Tag>() && registry.template attachee<Tag>() == entity) { | |
| archive(make_kvp(key, registry.template get<Tag>())); | |
| } | |
| } | |
| template<typename... Tag, typename Archive, std::size_t... Indexes> | |
| void tags(Archive &archive, const Entity& entity, const std::array<KeyType, sizeof...(Tag)>& keys, std::index_sequence<Indexes...>) const { | |
| using accumulator_type = int[]; | |
| accumulator_type accumulator = { (tag<Tag>(archive, entity, keys[Indexes]), 0)... }; | |
| (void)accumulator; | |
| } | |
| public: | |
| /*! @brief Copying a exporter isn't allowed. */ | |
| Exporter(const Exporter &) = delete; | |
| /*! @brief Default move constructor. */ | |
| Exporter(Exporter &&) = default; | |
| /*! @brief Copying a exporter isn't allowed. @return This exporter. */ | |
| Exporter & operator=(const Exporter &) = delete; | |
| /*! @brief Default move assignment operator. @return This exporter. */ | |
| Exporter & operator=(Exporter &&) = default; | |
| template<typename... Component, typename Archive, typename Source> | |
| const Exporter & component(Archive &archive, const Source& source, const std::array<KeyType, sizeof...(Component)>& keys) const { | |
| components<Component...>(archive, source, keys, std::make_index_sequence<sizeof...(Component)>{}); | |
| return *this; | |
| } | |
| template<typename... Tag, typename Archive> | |
| const Exporter & tag(Archive &archive, const Entity& entity, const std::array<KeyType, sizeof...(Tag)>& keys) const { | |
| tags<Tag...>(archive, entity, keys, std::make_index_sequence<sizeof...(Tag)>{}); | |
| return *this; | |
| } | |
| private: | |
| const Registry<Entity> ®istry; | |
| }; | |
| } | |
| #endif // ENTT_ENTITY_EXPORTER_HPP |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef ENTT_ENTITY_IMPORTER_HPP | |
| #define ENTT_ENTITY_IMPORTER_HPP | |
| #include <array> | |
| #include <cstddef> | |
| #include <utility> | |
| #include <cassert> | |
| #include <iterator> | |
| #include <type_traits> | |
| #include <unordered_map> | |
| #include "../config/config.h" | |
| #include "entt_traits.hpp" | |
| #include "utility.hpp" | |
| namespace entt { | |
| /** | |
| * @brief Forward declaration of the registry class. | |
| */ | |
| template<typename> | |
| class Registry; | |
| template<typename Entity> | |
| class Prototype; | |
| template<typename Entity, typename KeyType, template<class> class KeyValuePair> | |
| class Importer final { | |
| friend class Registry<Entity>; | |
| Importer(Registry<Entity> ®istry) ENTT_NOEXCEPT | |
| : registry{ registry } | |
| {} | |
| template<typename Type, typename Func, typename... Args> | |
| void build(Entity& entity, Func&& func, Args... args) const { | |
| registry.template build<Type>(std::move(func), std::forward<Args>(args)...); | |
| } | |
| template<typename Type, typename Func, typename... Args> | |
| void build(Prototype<Entity>& prototype, Func&& func, Args... args) const { | |
| prototype.build<Type>(std::move(func), std::forward<Args>(args)...); | |
| } | |
| template<typename Type, typename Archive, typename Predicate, typename Destination> | |
| bool load(Archive &archive, const Predicate& predicate, Destination& destination, KeyType key) const { | |
| if (predicate(archive, key)) { | |
| build<Type>(destination, [](Type& value, Archive &archive, KeyType& key) { | |
| archive(KeyValuePair<Type>{ key, value }); | |
| }, archive, key); | |
| return true; | |
| } | |
| return false; | |
| } | |
| template<typename... Component, typename Archive, typename Predicate, typename Destination, std::size_t... Indexes> | |
| void components(Archive &archive, const Predicate& predicate, Destination& destination, const std::array<KeyType, sizeof...(Component)>& keys, std::index_sequence<Indexes...>) const { | |
| using accumulator_type = int[]; | |
| accumulator_type accumulator = { (load<Component>(archive, predicate, destination, keys[Indexes]), 0)... }; | |
| (void)accumulator; | |
| } | |
| template<typename... Tag, typename Archive, typename Predicate, std::size_t... Indexes> | |
| void tags(Archive &archive, const Predicate& predicate, Entity& entity, const std::array<KeyType, sizeof...(Tag)>& keys, std::index_sequence<Indexes...>) const { | |
| using accumulator_type = int[]; | |
| accumulator_type accumulator = { (load<Tag>(archive, predicate, entity, keys[Indexes], tag_t{}), 0)... }; | |
| (void)accumulator; | |
| } | |
| public: | |
| /*! @brief Copying a importer isn't allowed. */ | |
| Importer(const Importer &) = delete; | |
| /*! @brief Default move constructor. */ | |
| Importer(Importer &&) = default; | |
| /*! @brief Copying a importer isn't allowed. @return This importer. */ | |
| Importer & operator=(const Importer &) = delete; | |
| /*! @brief Default move assignment operator. @return This importer. */ | |
| Importer & operator=(Importer &&) = default; | |
| template<typename... Component, typename Archive, typename Predicate, typename Destination> | |
| const Importer & component(Archive &archive, const Predicate& predicate, Destination& destination, const std::array<KeyType, sizeof...(Component)>& keys) const { | |
| components<Component...>(archive, predicate, destination, keys, std::make_index_sequence<sizeof...(Component)>{}); | |
| return *this; | |
| } | |
| template<typename... Tag, typename Archive, typename Predicate> | |
| const Importer & tag(Archive &archive, const Predicate& predicate, Entity& entity, const std::array<KeyType, sizeof...(Tag)>& keys) const { | |
| tags<Tag...>(archive, predicate, entity, keys, std::make_index_sequence<sizeof...(Tag)>{}); | |
| return *this; | |
| } | |
| private: | |
| Registry<Entity> ®istry; | |
| }; | |
| } | |
| #endif // ENTT_ENTITY_IMPORTER_HPP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment