Michele Caini 7 лет назад
Родитель
Сommit
17d57ee49a
5 измененных файлов с 748 добавлено и 603 удалено
  1. 1 0
      TODO
  2. 39 28
      docs/meta.md
  3. 9 45
      src/entt/meta/factory.hpp
  4. 378 206
      src/entt/meta/meta.hpp
  5. 321 324
      test/entt/meta/meta.cpp

+ 1 - 0
TODO

@@ -14,6 +14,7 @@
 * work stealing job system (see #100)
 * composable looper so as to pack erased systems, compose runners at different rates and run them at once in the loop
 * meta: sort of meta view based on meta stuff to iterate entities, void * and meta info objects
+* meta: move to head elements and forms LRU lists
 * registry::probe<component>(entt) (returns a component * if entt has the component, nullptr otherwise)
 * hashed string: add implicit check on construction for uniqueness (optional)
 * add a note about multithreading support to the README file

+ 39 - 28
docs/meta.md

@@ -162,11 +162,11 @@ entt::meta_any empty{};
 
 It can be constructed or assigned by copy and move and it takes the burden of
 destroying the contained object when required.<br/>
-A meta any object has a `type` member function that returns a pointer to the
-meta type of the contained value, if any. The member functions `can_cast` and
-`can_convert` are used to know if the underlying object has a given type as a
-base or if it can be converted implicitly to it. Similarly, `cast` and `convert`
-do what they promise and return the expected value.
+A meta any object has a `type` member function that returns the meta type of the
+contained value, if any. The member functions `can_cast` and `can_convert` are
+used to know if the underlying object has a given type as a base or if it can be
+converted implicitly to it. Similarly, `cast` and `convert` do what they promise
+and return the expected value.
 
 # Enjoy the runtime
 
@@ -181,25 +181,25 @@ both cases, the search can be done by means of the `resolve` function:
 
 ```cpp
 // search for a reflected type by type
-auto *by_type = entt::resolve<my_type>();
+auto by_type = entt::resolve<my_type>();
 
 // search for a reflected type by name
-auto *by_name = entt::resolve("reflected_type");
+auto by_name = entt::resolve("reflected_type");
 ```
 
 There exits also a third overload of the `resolve` function to use to iterate
 all the reflected types at once:
 
 ```cpp
-resolve([](auto *type) {
+resolve([](auto type) {
     // ...
 });
 ```
 
-In all cases, the returned value is a pointer to a `meta_type` object. This type
-of objects offer an API to know the _runtime name_ of the type, to iterate all
-the meta objects associated with them and even to build or destroy instances of
-the underlying type.<br/>
+In all cases, the returned value is an instance of `meta_type`. This type of
+objects offer an API to know the _runtime name_ of the type, to iterate all the
+meta objects associated with them and even to build or destroy instances of the
+underlying type.<br/>
 Refer to the inline documentation for all the details.
 
 The meta objects that compose a meta type are accessed in the following ways:
@@ -207,10 +207,10 @@ The meta objects that compose a meta type are accessed in the following ways:
 * _Meta constructors_. They are accessed by types of arguments:
 
   ```cpp
-  auto *ctor = entt::resolve<my_type>()->ctor<int, char>();
+  auto ctor = entt::resolve<my_type>().ctor<int, char>();
   ```
 
-  The returned type is `meta_ctor *` and may be null if there is no constructor
+  The returned type is `meta_ctor` and may be invalid if there is no constructor
   that accepts the supplied arguments or at least some types from which they are
   derived or to which they can be converted.<br/>
   A meta constructor offers an API to know the number of arguments, the expected
@@ -220,21 +220,21 @@ The meta objects that compose a meta type are accessed in the following ways:
 * _Meta destructor_. It's returned by a dedicated function:
 
   ```cpp
-  auto *dtor = entt::resolve<my_type>()->dtor();
+  auto dtor = entt::resolve<my_type>().dtor();
   ```
 
-  The returned type is `meta_dtor *` and may be null if there is no custom
-  destructor set for the gven meta type.<br/>
+  The returned type is `meta_dtor` and may be invalid if there is no custom
+  destructor set for the given meta type.<br/>
   All what a meta destructor has to offer is a way to invoke it on a given
   instance. Be aware that the result may not be what is expected.
 
 * _Meta data_. They are accessed by name:
 
   ```cpp
-  auto *data = entt::resolve<my_type>()->data("member");
+  auto data = entt::resolve<my_type>().data("member");
   ```
 
-  The returned type is `meta_data *` and may be null if there is no meta data
+  The returned type is `meta_data` and may be invalid if there is no meta data
   object associated with the given name.<br/>
   A meta data object offers an API to query the underlying type (ie to know if
   it's a const or a static one), to get the meta type of the variable and to set
@@ -243,10 +243,10 @@ The meta objects that compose a meta type are accessed in the following ways:
 * _Meta functions_. They are accessed by name:
 
   ```cpp
-  auto *func = entt::resolve<my_type>()->func("member");
+  auto func = entt::resolve<my_type>().func("member");
   ```
 
-  The returned type is `meta_func *` and may be null if there is no meta
+  The returned type is `meta_func` and may be invalid if there is no meta
   function object associated with the given name.<br/>
   A meta function object offers an API to query the underlying type (ie to know
   if it's a const or a static function), to know the number of arguments, the
@@ -258,10 +258,10 @@ The meta objects that compose a meta type are accessed in the following ways:
 * _Meta bases_. They are accessed through the name of the base types:
 
   ```cpp
-  auto *base = entt::resolve<derived_type>()->base("base");
+  auto base = entt::resolve<derived_type>().base("base");
   ```
 
-  The returned type is `meta_base *` and may be null if there is no meta base
+  The returned type is `meta_base` and may be invalid if there is no meta base
   object associated with the given name.<br/>
   Meta bases aren't meant to be used directly, even though they are freely
   accessible. They expose only a few methods to use to know the meta type of the
@@ -270,22 +270,33 @@ The meta objects that compose a meta type are accessed in the following ways:
 * _Meta conversion functions_. They are accessed by type:
 
   ```cpp
-  auto *conv = entt::resolve<double>()->conv<int>();
+  auto conv = entt::resolve<double>().conv<int>();
   ```
 
-  The returned type is `meta_conv *` and may be null if there is no meta
+  The returned type is `meta_conv` and may be invalid if there is no meta
   conversion function associated with the given type.<br/>
   The meta conversion functions are as thin as the meta bases and with a very
   similar interface. The sole difference is that they return a newly created
   instance wrapped in a meta any object when they convert between different
   types.
 
+All the objects thus obtained as well as the meta types can be explicitly
+converted to a boolean value to check if they are valid:
+
+```cpp
+auto func = entt::resolve<my_type>().func("member");
+
+if(func) {
+    // ...
+}
+```
+
 Furthermore, all meta objects with the exception of meta destructors can be
 iterated through an overload that accepts a callback through which to return
 them. As an example:
 
 ```cpp
-entt::resolve<my_type>()->data([](auto *data) {
+entt::resolve<my_type>().data([](auto data) {
     // ...
 });
 ```
@@ -326,12 +337,12 @@ named `prop` to iterate them at once and to search a specific property by key:
 
 ```cpp
 // iterate all the properties of a meta type
-entt::resolve<my_type>()->prop([](auto *prop) {
+entt::resolve<my_type>().prop([](auto prop) {
     // ...
 });
 
 // search for a given property by name
-auto *prop = entt::resolve<my_type>()->prop("tooltip"_hs);
+auto prop = entt::resolve<my_type>().prop("tooltip"_hs);
 ```
 
 Meta properties are objects having a fairly poor interface, all in all. They

+ 9 - 45
src/entt/meta/factory.hpp

@@ -74,10 +74,6 @@ class meta_factory {
             },
             []() -> meta_any {
                 return std::get<1>(prop);
-            },
-            []() {
-                static meta_prop meta{&node};
-                return &meta;
             }
         };
 
@@ -101,11 +97,7 @@ class meta_factory {
             std::is_member_pointer_v<Type>,
             std::is_arithmetic_v<Type>,
             std::is_compound_v<Type>,
-            &internal::destroy<Type>,
-            []() {
-                static meta_type meta{&node};
-                return &meta;
-            }
+            &internal::destroy<Type>
         };
 
         assert(!duplicate(name, node.next));
@@ -138,10 +130,6 @@ public:
             &internal::meta_info<Base>::resolve,
             [](void *instance) -> void * {
                 return static_cast<Base *>(static_cast<Type *>(instance));
-            },
-            []() {
-                static meta_base meta{&node};
-                return &meta;
             }
         };
 
@@ -172,10 +160,6 @@ public:
             &internal::meta_info<To>::resolve,
             [](void *instance) -> meta_any {
                 return static_cast<std::decay_t<To>>(*static_cast<Type *>(instance));
-            },
-            []() {
-                static meta_conv meta{&node};
-                return &meta;
             }
         };
 
@@ -214,10 +198,6 @@ public:
             &helper_type::arg,
             [](meta_any * const any) {
                 return internal::invoke<Type, Func>(nullptr, any, std::make_index_sequence<helper_type::size>{});
-            },
-            []() {
-                static meta_ctor meta{&node};
-                return &meta;
             }
         };
 
@@ -253,10 +233,6 @@ public:
             &helper_type::arg,
             [](meta_any * const any) {
                 return internal::construct<Type, Args...>(any, std::make_index_sequence<helper_type::size>{});
-            },
-            []() {
-                static meta_ctor meta{&node};
-                return &meta;
             }
         };
 
@@ -291,13 +267,9 @@ public:
         static internal::meta_dtor_node node{
             type,
             [](meta_handle handle) {
-                return handle.type() == internal::meta_info<Type>::resolve()->meta()
+                return handle.type() == internal::factory(internal::meta_info<Type>::resolve())
                         ? ((*Func)(*static_cast<Type *>(handle.data())), true)
                         : false;
-            },
-            []() {
-                static meta_dtor meta{&node};
-                return &meta;
             }
         };
 
@@ -336,11 +308,7 @@ public:
             !std::is_member_object_pointer_v<decltype(Data)>,
             &internal::meta_info<data_type<Data>>::resolve,
             &internal::setter<std::is_const_v<data_type<Data>>, Type, Data>,
-            &internal::getter<Type, Data>,
-            []() {
-                static meta_data meta{&node};
-                return &meta;
-            }
+            &internal::getter<Type, Data>
         };
 
         assert(!duplicate(hashed_string{str}, node.next));
@@ -381,10 +349,6 @@ public:
             &func_type<Func>::arg,
             [](meta_handle handle, meta_any *any) {
                 return internal::invoke<Type, Func>(handle, any, std::make_index_sequence<func_type<Func>::size>{});
-            },
-            []() {
-                static meta_func meta{&node};
-                return &meta;
             }
         };
 
@@ -444,8 +408,8 @@ inline meta_factory<Type> reflect() ENTT_NOEXCEPT {
  * @return The meta type associated with the given type, if any.
  */
 template<typename Type>
-inline meta_type * resolve() ENTT_NOEXCEPT {
-    return internal::meta_info<Type>::resolve()->meta();
+inline meta_type resolve() ENTT_NOEXCEPT {
+    return internal::factory(internal::meta_info<Type>::resolve());
 }
 
 
@@ -454,10 +418,10 @@ inline meta_type * resolve() ENTT_NOEXCEPT {
  * @param str The name to use to search for a meta type.
  * @return The meta type associated with the given name, if any.
  */
-inline meta_type * resolve(const char *str) ENTT_NOEXCEPT {
-    return internal::find_if([name = hashed_string{str}](auto *node) {
+inline meta_type resolve(const char *str) ENTT_NOEXCEPT {
+    return internal::factory(internal::find_if([name = hashed_string{str}](auto *node) {
         return node->name == name;
-    }, internal::meta_info<>::type);
+    }, internal::meta_info<>::type));
 }
 
 
@@ -469,7 +433,7 @@ inline meta_type * resolve(const char *str) ENTT_NOEXCEPT {
 template<typename Op>
 void resolve(Op op) ENTT_NOEXCEPT {
     internal::iterate([op = std::move(op)](auto *node) {
-        op(node->meta());
+        op(internal::factory(node));
     }, internal::meta_info<>::type);
 }
 

Разница между файлами не показана из-за своего большого размера
+ 378 - 206
src/entt/meta/meta.hpp


Разница между файлами не показана из-за своего большого размера
+ 321 - 324
test/entt/meta/meta.cpp


Некоторые файлы не были показаны из-за большого количества измененных файлов