Browse Source

added unset for context variables

Michele Caini 7 years ago
parent
commit
2779ad6c6f
4 changed files with 50 additions and 7 deletions
  1. 0 1
      TODO
  2. 9 4
      docs/entity.md
  3. 21 0
      src/entt/entity/registry.hpp
  4. 20 2
      test/entt/entity/registry.cpp

+ 0 - 1
TODO

@@ -22,4 +22,3 @@
 * add take functionality, eg registry.take(entity, other); where it takes the entity and all its components from registry and move them to other
 * add entity function to views/groups (component -> owner, see sparse sets)
 * what about paged pools? vector of fixed-size blocks
-* add unset for context variables

+ 9 - 4
docs/entity.md

@@ -829,10 +829,12 @@ const bool null = (entity == entt::null);
 ## Context variables
 
 It is often convenient to assign context variables to a registry, so as to make
-it the only source of truth of an application.<br/>
-This is possible through two member functions named `set` and `ctx`. The former
-is used to create a context variable from a given type, the latter to get the
-newly created instance later on:
+it the only _source of truth_ of an application.<br/>
+This is possible by means of a member function named `set` to use to create a
+context variable from a given type. Later on, `get` can be used to retrieve the
+newly created instance and `unset` is there to literally reset it if needed.
+
+Example of use:
 
 ```cpp
 // creates a new context variable initialized with the given values
@@ -841,6 +843,9 @@ registry.set<my_type>(42, 'c');
 if(auto *var = registry.ctx<my_type>(); var) {
     // uses the context variable associated with a registry, if any
 }
+
+// unsets the context variable
+registry.unset<my_type>();
 ```
 
 The type of a context variable must be such that it's default constructible and

+ 21 - 0
src/entt/entity/registry.hpp

@@ -1617,6 +1617,27 @@ public:
         return value;
     }
 
+    /**
+     * @brief Unsets a context variable if it exists.
+     * @tparam Type Type of object to set.
+     */
+    template<typename Type>
+    void unset() {
+        const auto ctype = runtime_type<Type, context_family>();
+
+        if constexpr(is_named_type_v<Type>) {
+            for(auto &&wrapper: vars) {
+                if(wrapper && wrapper->runtime_type == ctype) {
+                    wrapper.reset();
+                }
+            }
+        } else {
+            if(ctype < vars.size()) {
+                vars[ctype].reset();
+            }
+        }
+    }
+
     /**
      * @brief Returns a pointer to an object in the context of the registry.
      * @tparam Type Type of object to get.

+ 20 - 2
test/entt/entity/registry.cpp

@@ -35,10 +35,28 @@ struct listener {
 TEST(Registry, Context) {
     entt::registry registry;
 
+    ASSERT_EQ(registry.ctx<char>(), nullptr);
+    ASSERT_EQ(registry.ctx<int>(), nullptr);
+    ASSERT_EQ(registry.ctx<double>(), nullptr);
+
+    registry.set<char>();
+    registry.set<int>();
+    registry.set<double>();
+
+    ASSERT_NE(registry.ctx<char>(), nullptr);
+    ASSERT_NE(registry.ctx<int>(), nullptr);
+    ASSERT_NE(registry.ctx<double>(), nullptr);
+
+    registry.unset<int>();
+    registry.unset<double>();
+
+    ASSERT_NE(registry.ctx<char>(), nullptr);
+    ASSERT_EQ(registry.ctx<int>(), nullptr);
+    ASSERT_EQ(registry.ctx<double>(), nullptr);
+
     registry.set<char>('c');
-    registry.set<int>(0);
-    registry.set<double>(1.);
     registry.set<int>(42);
+    registry.set<double>(1.);
 
     ASSERT_EQ(*registry.ctx<char>(), 'c');
     ASSERT_NE(registry.ctx<char>(), nullptr);