Browse Source

tag dispatching to disambiguate tags and components (#65)

Michele Caini 8 years ago
parent
commit
820178f006

+ 7 - 6
README.md

@@ -578,7 +578,8 @@ data structures or more complex and movable data structures with a proper
 constructor.<br/>
 constructor.<br/>
 Actually, the same type can be used both as a tag and as a component and the
 Actually, the same type can be used both as a tag and as a component and the
 registry will not complain about it. It is up to the users to properly manage
 registry will not complain about it. It is up to the users to properly manage
-their own types.
+their own types. In some cases, the `tag_type_t` must also be used in order to
+disambiguate overloads of member functions.
 
 
 Attaching tags to entities and removing them is trivial:
 Attaching tags to entities and removing them is trivial:
 
 
@@ -587,10 +588,10 @@ auto player = registry.create();
 auto camera = registry.create();
 auto camera = registry.create();
 
 
 // attaches a default-initialized tag to an entity
 // attaches a default-initialized tag to an entity
-registry.attach<PlayingCharacter>(player);
+registry.assign<PlayingCharacter>(entt::tag_type_t{}, player);
 
 
 // attaches a tag to an entity and initializes it
 // attaches a tag to an entity and initializes it
-registry.attach<Camera>(camera, player);
+registry.assign<Camera>(entt::tag_type_t{}, camera, player);
 
 
 // removes tags from their owners
 // removes tags from their owners
 registry.remove<PlayingCharacter>();
 registry.remove<PlayingCharacter>();
@@ -598,12 +599,12 @@ registry.remove<Camera>();
 ```
 ```
 
 
 In case a tag already has an owner, its content can be updated by means of the
 In case a tag already has an owner, its content can be updated by means of the
-`set` member function template and the ownership of the tag can be transferred
-to another entity using the `move` member function template:
+`replace` member function template and the ownership of the tag can be
+transferred to another entity using the `move` member function template:
 
 
 ```
 ```
 // replaces the content of the given tag
 // replaces the content of the given tag
-Point &point = registry.set<Point>(1.f, 1.f);
+Point &point = registry.replace<Point>(entt::tag_type_t{}, 1.f, 1.f);
 
 
 // transfers the ownership of the tag to another entity
 // transfers the ownership of the tag to another entity
 entity_type prev = registry.move<Point>(next);
 entity_type prev = registry.move<Point>(next);

+ 0 - 1
TODO

@@ -5,6 +5,5 @@
 * define a macro for the noexcept policy, so as to provide users with an easy way to disable exception handling
 * define a macro for the noexcept policy, so as to provide users with an easy way to disable exception handling
 * define basic reactive systems (track entities to which component is attached, track entities from which component is removed, and so on)
 * define basic reactive systems (track entities to which component is attached, track entities from which component is removed, and so on)
 * blueprint registry - kind of factory to create entitites template for initialization (use signals, it's trivial this way)
 * blueprint registry - kind of factory to create entitites template for initialization (use signals, it's trivial this way)
-* use tag dispatching to disambiguate between standard components and single instance components, then provide users with an common API
 * remove Actor::update (it's application dependent), allow tag instead
 * remove Actor::update (it's application dependent), allow tag instead
 * AOB
 * AOB

+ 132 - 131
src/entt/entity/registry.hpp

@@ -16,6 +16,7 @@
 #include "entt_traits.hpp"
 #include "entt_traits.hpp"
 #include "snapshot.hpp"
 #include "snapshot.hpp"
 #include "sparse_set.hpp"
 #include "sparse_set.hpp"
+#include "utility.hpp"
 #include "view.hpp"
 #include "view.hpp"
 
 
 
 
@@ -182,7 +183,7 @@ public:
      * @return Runtime numeric identifier of the given type of tag.
      * @return Runtime numeric identifier of the given type of tag.
      */
      */
     template<typename Tag>
     template<typename Tag>
-    tag_type tag() const noexcept {
+    tag_type type(tag_type_t) const noexcept {
         return tag_family::type<Tag>();
         return tag_family::type<Tag>();
     }
     }
 
 
@@ -199,7 +200,7 @@ public:
      * @return Runtime numeric identifier of the given type of component.
      * @return Runtime numeric identifier of the given type of component.
      */
      */
     template<typename Component>
     template<typename Component>
-    component_type component() const noexcept {
+    component_type type() const noexcept {
         return component_family::type<Component>();
         return component_family::type<Component>();
     }
     }
 
 
@@ -430,7 +431,7 @@ public:
      * @return A reference to the newly created tag.
      * @return A reference to the newly created tag.
      */
      */
     template<typename Tag, typename... Args>
     template<typename Tag, typename... Args>
-    Tag & attach(entity_type entity, Args &&... args) {
+    Tag & assign(tag_type_t, entity_type entity, Args &&... args) {
         assert(valid(entity));
         assert(valid(entity));
         assert(!has<Tag>());
         assert(!has<Tag>());
         const auto ttype = tag_family::type<Tag>();
         const auto ttype = tag_family::type<Tag>();
@@ -444,134 +445,6 @@ public:
         return static_cast<Attaching<Tag> *>(tags[ttype].get())->tag;
         return static_cast<Attaching<Tag> *>(tags[ttype].get())->tag;
     }
     }
 
 
-    /**
-     * @brief Removes the given tag from its owner, if any.
-     * @tparam Tag Type of tag to remove.
-     */
-    template<typename Tag>
-    void remove() {
-        if(has<Tag>()) {
-            tags[tag_family::type<Tag>()].reset();
-        }
-    }
-
-    /**
-     * @brief Checks if the given tag has an owner.
-     * @tparam Tag Type of tag for which to perform the check.
-     * @return True if the tag already has an owner, false otherwise.
-     */
-    template<typename Tag>
-    bool has() const noexcept {
-        const auto ttype = tag_family::type<Tag>();
-        return (ttype < tags.size() &&
-                // it's a valid tag
-                tags[ttype] &&
-                // the associated entity hasn't been destroyed in the meantime
-                tags[ttype]->entity == (entities[tags[ttype]->entity & traits_type::entity_mask]));
-    }
-
-    /**
-     * @brief Returns a reference to the given tag.
-     *
-     * @warning
-     * Attempting to get a tag that hasn't an owner results in undefined
-     * behavior.<br/>
-     * An assertion will abort the execution at runtime in debug mode if the
-     * tag hasn't been previously attached to an entity.
-     *
-     * @tparam Tag Type of tag to get.
-     * @return A reference to the tag.
-     */
-    template<typename Tag>
-    const Tag & get() const noexcept {
-        assert(has<Tag>());
-        return static_cast<Attaching<Tag> *>(tags[tag_family::type<Tag>()].get())->tag;
-    }
-
-    /**
-     * @brief Returns a reference to the given tag.
-     *
-     * @warning
-     * Attempting to get a tag that hasn't an owner results in undefined
-     * behavior.<br/>
-     * An assertion will abort the execution at runtime in debug mode if the
-     * tag hasn't been previously attached to an entity.
-     *
-     * @tparam Tag Type of tag to get.
-     * @return A reference to the tag.
-     */
-    template<typename Tag>
-    Tag & get() noexcept {
-        return const_cast<Tag &>(const_cast<const Registry *>(this)->get<Tag>());
-    }
-
-    /**
-     * @brief Replaces the given tag.
-     *
-     * A new instance of the given tag is created and initialized with the
-     * arguments provided (the tag must have a proper constructor or be of
-     * aggregate type).
-     *
-     * @warning
-     * Attempting to replace a tag that hasn't an owner results in undefined
-     * behavior.<br/>
-     * An assertion will abort the execution at runtime in debug mode if the
-     * tag hasn't been previously attached to an entity.
-     *
-     * @tparam Tag Type of tag to replace.
-     * @tparam Args Types of arguments to use to construct the tag.
-     * @param args Parameters to use to initialize the tag.
-     * @return A reference to the tag.
-     */
-    template<typename Tag, typename... Args>
-    Tag & set(Args &&... args) {
-        return get<Tag>() = Tag{std::forward<Args>(args)...};
-    }
-
-    /**
-     * @brief Changes the owner of the given tag.
-     *
-     * The ownership of the tag is transferred from one entity to another.
-     *
-     * @warning
-     * Attempting to use an invalid entity or to transfer the ownership of a tag
-     * that hasn't an owner results in undefined behavior.<br/>
-     * An assertion will abort the execution at runtime in debug mode in case of
-     * invalid entity or if the tag hasn't been previously attached to an
-     * entity.
-     *
-     * @tparam Tag Type of tag of which to transfer the ownership.
-     * @param entity A valid entity identifier.
-     * @return A valid entity identifier.
-     */
-    template<typename Tag>
-    entity_type move(entity_type entity) {
-        assert(valid(entity));
-        assert(has<Tag>());
-        const auto ttype = tag_family::type<Tag>();
-        const auto owner = tags[ttype]->entity;
-        tags[ttype]->entity = entity;
-        return owner;
-    }
-
-    /**
-     * @brief Gets the owner of the given tag, if any.
-     *
-     * @warning
-     * Attempting to get the owner of a tag that hasn't been previously attached
-     * to an entity results in undefined behavior.<br/>
-     * An assertion will abort the execution at runtime in debug mode if the
-     * tag hasn't an owner.
-     *
-     * @tparam Tag Type of tag of which to get the owner.
-     * @return A valid entity identifier.
-     */
-    template<typename Tag>
-    entity_type attachee() const noexcept {
-        assert(has<Tag>());
-        return tags[tag_family::type<Tag>()]->entity;
-    }
-
     /**
     /**
      * @brief Assigns the given component to an entity.
      * @brief Assigns the given component to an entity.
      *
      *
@@ -598,6 +471,17 @@ public:
         return assure<Component>().construct(entity, std::forward<Args>(args)...);
         return assure<Component>().construct(entity, std::forward<Args>(args)...);
     }
     }
 
 
+    /**
+     * @brief Removes the given tag from its owner, if any.
+     * @tparam Tag Type of tag to remove.
+     */
+    template<typename Tag>
+    void remove() {
+        if(has<Tag>()) {
+            tags[tag_family::type<Tag>()].reset();
+        }
+    }
+
     /**
     /**
      * @brief Removes the given component from an entity.
      * @brief Removes the given component from an entity.
      *
      *
@@ -617,6 +501,21 @@ public:
         pool<Component>().destroy(entity);
         pool<Component>().destroy(entity);
     }
     }
 
 
+    /**
+     * @brief Checks if the given tag has an owner.
+     * @tparam Tag Type of tag for which to perform the check.
+     * @return True if the tag already has an owner, false otherwise.
+     */
+    template<typename Tag>
+    bool has() const noexcept {
+        const auto ttype = tag_family::type<Tag>();
+        return (ttype < tags.size() &&
+                // it's a valid tag
+                tags[ttype] &&
+                // the associated entity hasn't been destroyed in the meantime
+                tags[ttype]->entity == (entities[tags[ttype]->entity & traits_type::entity_mask]));
+    }
+
     /**
     /**
      * @brief Checks if an entity has all the given components.
      * @brief Checks if an entity has all the given components.
      *
      *
@@ -639,6 +538,41 @@ public:
         return all;
         return all;
     }
     }
 
 
+    /**
+     * @brief Returns a reference to the given tag.
+     *
+     * @warning
+     * Attempting to get a tag that hasn't an owner results in undefined
+     * behavior.<br/>
+     * An assertion will abort the execution at runtime in debug mode if the
+     * tag hasn't been previously attached to an entity.
+     *
+     * @tparam Tag Type of tag to get.
+     * @return A reference to the tag.
+     */
+    template<typename Tag>
+    const Tag & get() const noexcept {
+        assert(has<Tag>());
+        return static_cast<Attaching<Tag> *>(tags[tag_family::type<Tag>()].get())->tag;
+    }
+
+    /**
+     * @brief Returns a reference to the given tag.
+     *
+     * @warning
+     * Attempting to get a tag that hasn't an owner results in undefined
+     * behavior.<br/>
+     * An assertion will abort the execution at runtime in debug mode if the
+     * tag hasn't been previously attached to an entity.
+     *
+     * @tparam Tag Type of tag to get.
+     * @return A reference to the tag.
+     */
+    template<typename Tag>
+    Tag & get() noexcept {
+        return const_cast<Tag &>(const_cast<const Registry *>(this)->get<Tag>());
+    }
+
     /**
     /**
      * @brief Returns a reference to the given component for an entity.
      * @brief Returns a reference to the given component for an entity.
      *
      *
@@ -718,6 +652,29 @@ public:
         return std::tuple<Component &...>{get<Component>(entity)...};
         return std::tuple<Component &...>{get<Component>(entity)...};
     }
     }
 
 
+    /**
+     * @brief Replaces the given tag.
+     *
+     * A new instance of the given tag is created and initialized with the
+     * arguments provided (the tag must have a proper constructor or be of
+     * aggregate type).
+     *
+     * @warning
+     * Attempting to replace a tag that hasn't an owner results in undefined
+     * behavior.<br/>
+     * An assertion will abort the execution at runtime in debug mode if the
+     * tag hasn't been previously attached to an entity.
+     *
+     * @tparam Tag Type of tag to replace.
+     * @tparam Args Types of arguments to use to construct the tag.
+     * @param args Parameters to use to initialize the tag.
+     * @return A reference to the tag.
+     */
+    template<typename Tag, typename... Args>
+    Tag & replace(tag_type_t, Args &&... args) {
+        return get<Tag>() = Tag{std::forward<Args>(args)...};
+    }
+
     /**
     /**
      * @brief Replaces the given component for an entity.
      * @brief Replaces the given component for an entity.
      *
      *
@@ -743,6 +700,50 @@ public:
         return (get<Component>(entity) = Component{std::forward<Args>(args)...});
         return (get<Component>(entity) = Component{std::forward<Args>(args)...});
     }
     }
 
 
+    /**
+     * @brief Changes the owner of the given tag.
+     *
+     * The ownership of the tag is transferred from one entity to another.
+     *
+     * @warning
+     * Attempting to use an invalid entity or to transfer the ownership of a tag
+     * that hasn't an owner results in undefined behavior.<br/>
+     * An assertion will abort the execution at runtime in debug mode in case of
+     * invalid entity or if the tag hasn't been previously attached to an
+     * entity.
+     *
+     * @tparam Tag Type of tag of which to transfer the ownership.
+     * @param entity A valid entity identifier.
+     * @return A valid entity identifier.
+     */
+    template<typename Tag>
+    entity_type move(entity_type entity) {
+        assert(valid(entity));
+        assert(has<Tag>());
+        const auto ttype = tag_family::type<Tag>();
+        const auto owner = tags[ttype]->entity;
+        tags[ttype]->entity = entity;
+        return owner;
+    }
+
+    /**
+     * @brief Gets the owner of the given tag, if any.
+     *
+     * @warning
+     * Attempting to get the owner of a tag that hasn't been previously attached
+     * to an entity results in undefined behavior.<br/>
+     * An assertion will abort the execution at runtime in debug mode if the
+     * tag hasn't an owner.
+     *
+     * @tparam Tag Type of tag of which to get the owner.
+     * @return A valid entity identifier.
+     */
+    template<typename Tag>
+    entity_type attachee() const noexcept {
+        assert(has<Tag>());
+        return tags[tag_family::type<Tag>()]->entity;
+    }
+
     /**
     /**
      * @brief Assigns or replaces the given component for an entity.
      * @brief Assigns or replaces the given component for an entity.
      *
      *

+ 8 - 16
src/entt/entity/snapshot.hpp

@@ -10,6 +10,7 @@
 #include <iterator>
 #include <iterator>
 #include <type_traits>
 #include <type_traits>
 #include "entt_traits.hpp"
 #include "entt_traits.hpp"
+#include "utility.hpp"
 
 
 
 
 namespace entt {
 namespace entt {
@@ -50,7 +51,7 @@ class Snapshot final {
 
 
     template<typename Component, typename Archive>
     template<typename Component, typename Archive>
     void get(Archive &archive, const Registry<Entity> &registry) {
     void get(Archive &archive, const Registry<Entity> &registry) {
-        const auto component = registry.template component<Component>();
+        const auto component = registry.template type<Component>();
         const auto sz = registry.template size<Component>();
         const auto sz = registry.template size<Component>();
         const auto *entities = raw(registry, component);
         const auto *entities = raw(registry, component);
 
 
@@ -216,21 +217,12 @@ class SnapshotLoader final {
         }
         }
     }
     }
 
 
-    template<typename Component, typename Archive>
-    void assign(Archive &archive) {
-        each(archive, [&archive, this](auto entity) {
-            static constexpr auto destroyed = false;
-            assure_fn(registry, entity, destroyed);
-            archive(registry.template assign<Component>(entity));
-        });
-    }
-
-    template<typename Tag, typename Archive>
-    void attach(Archive &archive) {
-        each(archive, [&archive, this](auto entity) {
+    template<typename Type, typename Archive, typename... Args>
+    void assign(Archive &archive, Args... args) {
+        each(archive, [&archive, this, args...](auto entity) {
             static constexpr auto destroyed = false;
             static constexpr auto destroyed = false;
             assure_fn(registry, entity, destroyed);
             assure_fn(registry, entity, destroyed);
-            archive(registry.template attach<Tag>(entity));
+            archive(registry.template assign<Type>(args..., entity));
         });
         });
     }
     }
 
 
@@ -322,7 +314,7 @@ public:
     template<typename... Tag, typename Archive>
     template<typename... Tag, typename Archive>
     SnapshotLoader & tag(Archive &archive) {
     SnapshotLoader & tag(Archive &archive) {
         using accumulator_type = int[];
         using accumulator_type = int[];
-        accumulator_type accumulator = { 0, (attach<Tag>(archive), 0)... };
+        accumulator_type accumulator = { 0, (assign<Tag>(archive, tag_type_t{}), 0)... };
         (void)accumulator;
         (void)accumulator;
         return *this;
         return *this;
     }
     }
@@ -471,7 +463,7 @@ class ContinuousLoader final {
 
 
         each(archive, [&archive, this](auto entity) {
         each(archive, [&archive, this](auto entity) {
             entity = restore(entity);
             entity = restore(entity);
-            archive(registry.template attach<Tag>(entity));
+            archive(registry.template assign<Tag>(tag_type_t{}, entity));
         });
         });
     }
     }
 
 

+ 20 - 0
src/entt/entity/utility.hpp

@@ -0,0 +1,20 @@
+#ifndef ENTT_ENTITY_UTILITY_HPP
+#define ENTT_ENTITY_UTILITY_HPP
+
+
+namespace entt {
+
+
+/**
+ * @brief Tag class type.
+ *
+ * An empty class type used to disambiguate the overloads of some member
+ * functions of the registry.
+ */
+struct tag_type_t final {};
+
+
+}
+
+
+#endif // ENTT_ENTITY_UTILITY_HPP

+ 1 - 0
src/entt/entt.hpp

@@ -6,6 +6,7 @@
 #include "entity/registry.hpp"
 #include "entity/registry.hpp"
 #include "entity/snapshot.hpp"
 #include "entity/snapshot.hpp"
 #include "entity/sparse_set.hpp"
 #include "entity/sparse_set.hpp"
+#include "entity/utility.hpp"
 #include "entity/view.hpp"
 #include "entity/view.hpp"
 #include "locator/locator.hpp"
 #include "locator/locator.hpp"
 #include "process/process.hpp"
 #include "process/process.hpp"

+ 9 - 9
test/entt/entity/registry.cpp

@@ -253,7 +253,7 @@ TEST(DefaultRegistry, Orphans) {
     registry.create();
     registry.create();
     registry.assign<int>(registry.create());
     registry.assign<int>(registry.create());
     registry.create();
     registry.create();
-    registry.attach<double>(registry.create());
+    registry.assign<double>(entt::tag_type_t{}, registry.create());
 
 
     registry.orphans([&](auto) { ++tot; });
     registry.orphans([&](auto) { ++tot; });
     ASSERT_EQ(tot, 2u);
     ASSERT_EQ(tot, 2u);
@@ -272,11 +272,11 @@ TEST(DefaultRegistry, Orphans) {
 TEST(DefaultRegistry, Types) {
 TEST(DefaultRegistry, Types) {
     entt::DefaultRegistry registry;
     entt::DefaultRegistry registry;
 
 
-    ASSERT_EQ(registry.tag<int>(), registry.tag<int>());
-    ASSERT_EQ(registry.component<int>(), registry.component<int>());
+    ASSERT_EQ(registry.type<int>(entt::tag_type_t{}), registry.type<int>(entt::tag_type_t{}));
+    ASSERT_EQ(registry.type<int>(), registry.type<int>());
 
 
-    ASSERT_NE(registry.tag<int>(), registry.tag<double>());
-    ASSERT_NE(registry.component<int>(), registry.component<double>());
+    ASSERT_NE(registry.type<int>(entt::tag_type_t{}), registry.type<double>(entt::tag_type_t{}));
+    ASSERT_NE(registry.type<int>(), registry.type<double>(entt::tag_type_t{}));
 }
 }
 
 
 TEST(DefaultRegistry, CreateDestroyEntities) {
 TEST(DefaultRegistry, CreateDestroyEntities) {
@@ -317,14 +317,14 @@ TEST(DefaultRegistry, AttachSetRemoveTags) {
     ASSERT_FALSE(registry.has<int>());
     ASSERT_FALSE(registry.has<int>());
 
 
     const auto entity = registry.create();
     const auto entity = registry.create();
-    registry.attach<int>(entity, 42);
+    registry.assign<int>(entt::tag_type_t{}, entity, 42);
 
 
     ASSERT_TRUE(registry.has<int>());
     ASSERT_TRUE(registry.has<int>());
     ASSERT_EQ(registry.get<int>(), 42);
     ASSERT_EQ(registry.get<int>(), 42);
     ASSERT_EQ(cregistry.get<int>(), 42);
     ASSERT_EQ(cregistry.get<int>(), 42);
     ASSERT_EQ(registry.attachee<int>(), entity);
     ASSERT_EQ(registry.attachee<int>(), entity);
 
 
-    registry.set<int>(3);
+    registry.replace<int>(entt::tag_type_t{}, 3);
 
 
     ASSERT_TRUE(registry.has<int>());
     ASSERT_TRUE(registry.has<int>());
     ASSERT_EQ(registry.get<int>(), 3);
     ASSERT_EQ(registry.get<int>(), 3);
@@ -343,7 +343,7 @@ TEST(DefaultRegistry, AttachSetRemoveTags) {
 
 
     ASSERT_FALSE(registry.has<int>());
     ASSERT_FALSE(registry.has<int>());
 
 
-    registry.attach<int>(entity, 42);
+    registry.assign<int>(entt::tag_type_t{}, entity, 42);
     registry.destroy(entity);
     registry.destroy(entity);
 
 
     ASSERT_FALSE(registry.has<int>());
     ASSERT_FALSE(registry.has<int>());
@@ -437,7 +437,7 @@ TEST(DefaultRegistry, CleanPersistentViewsAfterReset) {
 TEST(DefaultRegistry, CleanTagsAfterReset) {
 TEST(DefaultRegistry, CleanTagsAfterReset) {
     entt::DefaultRegistry registry;
     entt::DefaultRegistry registry;
     const auto entity = registry.create();
     const auto entity = registry.create();
-    registry.attach<int>(entity);
+    registry.assign<int>(entt::tag_type_t{}, entity);
 
 
     ASSERT_TRUE(registry.has<int>());
     ASSERT_TRUE(registry.has<int>());
 
 

+ 5 - 5
test/entt/entity/snapshot.cpp

@@ -63,10 +63,10 @@ TEST(Snapshot, Dump) {
 
 
     const auto e3 = registry.create();
     const auto e3 = registry.create();
     registry.assign<char>(e3, '0');
     registry.assign<char>(e3, '0');
-    registry.attach<float>(e3, .3f);
+    registry.assign<float>(entt::tag_type_t{}, e3, .3f);
 
 
     const auto e4 = registry.create();
     const auto e4 = registry.create();
-    registry.attach<AComponent>(e4);
+    registry.assign<AComponent>(entt::tag_type_t{}, e4);
 
 
     registry.destroy(e1);
     registry.destroy(e1);
     auto v1 = registry.current(e1);
     auto v1 = registry.current(e1);
@@ -152,10 +152,10 @@ TEST(Snapshot, Partial) {
 
 
     const auto e3 = registry.create();
     const auto e3 = registry.create();
     registry.assign<char>(e3, '0');
     registry.assign<char>(e3, '0');
-    registry.attach<float>(e3, .3f);
+    registry.assign<float>(entt::tag_type_t{}, e3, .3f);
 
 
     const auto e4 = registry.create();
     const auto e4 = registry.create();
-    registry.attach<AComponent>(e4);
+    registry.assign<AComponent>(entt::tag_type_t{}, e4);
 
 
     registry.destroy(e1);
     registry.destroy(e1);
     auto v1 = registry.current(e1);
     auto v1 = registry.current(e1);
@@ -281,7 +281,7 @@ TEST(Snapshot, Continuous) {
         if(i % 2) {
         if(i % 2) {
             src.assign<Foo>(entity, entity);
             src.assign<Foo>(entity, entity);
         } else if(i == 2) {
         } else if(i == 2) {
-            src.attach<double>(entity, .3);
+            src.assign<double>(entt::tag_type_t{}, entity, .3);
         }
         }
     }
     }
 
 

+ 4 - 4
test/mod/mod.cpp

@@ -157,7 +157,7 @@ class DuktapeRegistry {
     template<typename... Comp>
     template<typename... Comp>
     void reg() {
     void reg() {
         using accumulator_type = int[];
         using accumulator_type = int[];
-        accumulator_type acc = { (func[registry.component<Comp>()] = {
+        accumulator_type acc = { (func[registry.type<Comp>()] = {
                                      &::set<Comp>,
                                      &::set<Comp>,
                                      &::unset<Comp>,
                                      &::unset<Comp>,
                                      &::has<Comp>,
                                      &::has<Comp>,
@@ -186,7 +186,7 @@ class DuktapeRegistry {
         auto type = duk_require_uint(ctx, 1);
         auto type = duk_require_uint(ctx, 1);
 
 
         if(type >= udef) {
         if(type >= udef) {
-            type = registry.component<DuktapeRuntime>();
+            type = registry.type<DuktapeRuntime>();
         }
         }
 
 
         assert(func.find(type) != func.cend());
         assert(func.find(type) != func.cend());
@@ -248,7 +248,7 @@ public:
                     assert(func.find(type) != func.cend());
                     assert(func.find(type) != func.cend());
                     match = (registry.*func[type].test)(entity);
                     match = (registry.*func[type].test)(entity);
                 } else {
                 } else {
-                    const auto ctype = registry.component<DuktapeRuntime>();
+                    const auto ctype = registry.type<DuktapeRuntime>();
                     assert(func.find(ctype) != func.cend());
                     assert(func.find(ctype) != func.cend());
                     match = (registry.*func[ctype].test)(entity);
                     match = (registry.*func[ctype].test)(entity);
 
 
@@ -287,7 +287,7 @@ const duk_function_list_entry js_DuktapeRegistry_methods[] = {
 void exportTypes(duk_context *ctx, entt::DefaultRegistry &registry) {
 void exportTypes(duk_context *ctx, entt::DefaultRegistry &registry) {
     auto exportType = [](auto *ctx, auto &registry, auto idx, auto type, const auto *name) {
     auto exportType = [](auto *ctx, auto &registry, auto idx, auto type, const auto *name) {
         duk_push_string(ctx, name);
         duk_push_string(ctx, name);
-        duk_push_uint(ctx, registry.template component<typename decltype(type)::type>());
+        duk_push_uint(ctx, registry.template type<typename decltype(type)::type>());
         duk_def_prop(ctx, idx, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_CLEAR_WRITABLE);
         duk_def_prop(ctx, idx, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_CLEAR_WRITABLE);
     };
     };