Kaynağa Gözat

added monostate (built-in config system)

Michele Caini 7 yıl önce
ebeveyn
işleme
f8310b1296
6 değiştirilmiş dosya ile 107 ekleme ve 1 silme
  1. 24 0
      README.md
  2. 0 1
      TODO
  3. 61 0
      src/entt/core/monostate.hpp
  4. 1 0
      src/entt/entt.hpp
  5. 1 0
      test/CMakeLists.txt
  6. 20 0
      test/entt/core/monostate.cpp

+ 24 - 0
README.md

@@ -43,6 +43,7 @@
    * [Compile-time identifiers](#compile-time-identifiers)
    * [Compile-time identifiers](#compile-time-identifiers)
    * [Runtime identifiers](#runtime-identifiers)
    * [Runtime identifiers](#runtime-identifiers)
    * [Hashed strings](#hashed-strings)
    * [Hashed strings](#hashed-strings)
+   * [Monostate](#monostate)
 * [Crash Course: service locator](#crash-course-service-locator)
 * [Crash Course: service locator](#crash-course-service-locator)
 * [Crash Course: cooperative scheduler](#crash-course-cooperative-scheduler)
 * [Crash Course: cooperative scheduler](#crash-course-cooperative-scheduler)
    * [The process](#the-process)
    * [The process](#the-process)
@@ -1697,6 +1698,29 @@ and over which users have not the control. Choosing a slightly different
 identifier is probably the best solution to make the conflict disappear in this
 identifier is probably the best solution to make the conflict disappear in this
 case.
 case.
 
 
+## Monostate
+
+The monostate pattern is often presented as an alternative to a singleton based
+configuration system. This is exactly its purpose in `EnTT`. Moreover, this
+implementation is thread safe by design (hopefully).<br/>
+Keys are represented by hashed strings, values are basic types like `int`s or
+`bool`s. Values of different types can be associated to each key, even more than
+one at a time. Because of this, users must pay attention to use the same type
+both during an assignment and when they try to read back their data. Otherwise,
+they will probably incur in unexpected results.
+
+Example of use:
+
+```cpp
+entt::Monostate<entt::HashedString{"mykey"}>{} = true;
+entt::Monostate<"mykey"_hs>{} = 42;
+
+// ...
+
+const bool b = entt::Monostate<"mykey"_hs>{};
+const int i = entt::Monostate<entt::HashedString{"mykey"}>{};
+```
+
 # Crash Course: service locator
 # Crash Course: service locator
 
 
 Usually service locators are tightly bound to the services they expose and it's
 Usually service locators are tightly bound to the services they expose and it's

+ 0 - 1
TODO

@@ -7,7 +7,6 @@
 * define systems as composable mixins (initializazion, reactive, update, whatever) with flexible auto-detected arguments (registry, views, etc)
 * define systems as composable mixins (initializazion, reactive, update, whatever) with flexible auto-detected arguments (registry, views, etc)
 * create dedicated flat map based on types implementation (sort of "type map") for types to use within the registry and so on...
 * create dedicated flat map based on types implementation (sort of "type map") for types to use within the registry and so on...
 * ease the assignment of tags as string (type-less assign member function + user defined literal for hashed strings)
 * ease the assignment of tags as string (type-less assign member function + user defined literal for hashed strings)
-* config system with atomic (something like Config<"foobar"_hs>::set(true) and Config<"foobar"_hs>::get<bool>())
 * work stealing job system (see #100)
 * work stealing job system (see #100)
 * C++17. That's all.
 * C++17. That's all.
 * AOB
 * AOB

+ 61 - 0
src/entt/core/monostate.hpp

@@ -0,0 +1,61 @@
+#ifndef ENTT_CORE_MONOSTATE_HPP
+#define ENTT_CORE_MONOSTATE_HPP
+
+
+#include <atomic>
+#include <cassert>
+#include "family.hpp"
+#include "hashed_string.hpp"
+
+
+namespace entt {
+
+
+/**
+ * @brief Minimal implementation of the monostate pattern.
+ *
+ * A minimal, yet complete configuration system built on top of the monostate
+ * pattern. Thread safe by design, it works only with basic types like `int`s or
+ * `bool`s.<br/>
+ * Multiple types and therefore more than one value can be associated with a
+ * single key. Because of this, users must pay attention to use the same type
+ * both during an assignment and when they try to read back their data.
+ * Otherwise, they can incur in unexpected results.
+ */
+template<HashedString::hash_type>
+struct Monostate {
+    /**
+     * @brief Assigns a value of a specific type to a given key.
+     * @tparam Type Type of the value to assign.
+     * @param val User data to assign to the given key.
+     */
+    template<typename Type>
+    void operator=(Type val) const ENTT_NOEXCEPT {
+        Monostate::value<Type> = val;
+    }
+
+    /**
+     * @brief Gets a value of a specific type for a given key.
+     * @tparam Type Type of the value to get.
+     * @return Stored value, if any.
+     */
+    template<typename Type>
+    operator Type() const ENTT_NOEXCEPT {
+        return Monostate::value<Type>;
+    }
+
+private:
+    template<typename Type>
+    static std::atomic<Type> value;
+};
+
+
+template<HashedString::hash_type ID>
+template<typename Type>
+std::atomic<Type> Monostate<ID>::value{};
+
+
+}
+
+
+#endif // ENTT_CORE_MONOSTATE_HPP

+ 1 - 0
src/entt/entt.hpp

@@ -2,6 +2,7 @@
 #include "core/family.hpp"
 #include "core/family.hpp"
 #include "core/hashed_string.hpp"
 #include "core/hashed_string.hpp"
 #include "core/ident.hpp"
 #include "core/ident.hpp"
+#include "core/monostate.hpp"
 #include "entity/actor.hpp"
 #include "entity/actor.hpp"
 #include "entity/entity.hpp"
 #include "entity/entity.hpp"
 #include "entity/entt_traits.hpp"
 #include "entity/entt_traits.hpp"

+ 1 - 0
test/CMakeLists.txt

@@ -70,6 +70,7 @@ ADD_ENTT_TEST(algorithm entt/core/algorithm.cpp)
 ADD_ENTT_TEST(family entt/core/family.cpp)
 ADD_ENTT_TEST(family entt/core/family.cpp)
 ADD_ENTT_TEST(hashed_string entt/core/hashed_string.cpp)
 ADD_ENTT_TEST(hashed_string entt/core/hashed_string.cpp)
 ADD_ENTT_TEST(ident entt/core/ident.cpp)
 ADD_ENTT_TEST(ident entt/core/ident.cpp)
+ADD_ENTT_TEST(monostate entt/core/monostate.cpp)
 
 
 # Test entity
 # Test entity
 
 

+ 20 - 0
test/entt/core/monostate.cpp

@@ -0,0 +1,20 @@
+#include <gtest/gtest.h>
+#include <entt/core/hashed_string.hpp>
+#include <entt/core/monostate.hpp>
+
+TEST(Monostate, Functionalities) {
+    const bool bPre = entt::Monostate<entt::HashedString{"foobar"}>{};
+    const int iPre = entt::Monostate<"foobar"_hs>{};
+
+    ASSERT_FALSE(bPre);
+    ASSERT_EQ(iPre, int{});
+
+    entt::Monostate<"foobar"_hs>{} = true;
+    entt::Monostate<"foobar"_hs>{} = 42;
+
+    const bool &bPost = entt::Monostate<"foobar"_hs>{};
+    const int &iPost = entt::Monostate<entt::HashedString{"foobar"}>{};
+
+    ASSERT_TRUE(bPost);
+    ASSERT_EQ(iPost, 42);
+}