|
|
@@ -20,6 +20,7 @@
|
|
|
* [Named constants and enums](#named-constants-and-enums)
|
|
|
* [Properties and meta objects](#properties-and-meta-objects)
|
|
|
* [Unregister types](#unregister-types)
|
|
|
+ * [Meta context](#meta-context)
|
|
|
<!--
|
|
|
@endcond TURN_OFF_DOXYGEN
|
|
|
-->
|
|
|
@@ -43,7 +44,7 @@ when it comes to working with names and identifiers. It does this by offering an
|
|
|
API that works with opaque identifiers that may or may not be generated by means
|
|
|
of a hashed string.<br/>
|
|
|
This means that users can assign any type of identifier to the meta objects, as
|
|
|
-long as they are numeric. It doesn't matter if they are generated at runtime, at
|
|
|
+long as they're numeric. It doesn't matter if they're generated at runtime, at
|
|
|
compile-time or with custom functions.
|
|
|
|
|
|
That being said, the examples in the following sections are all based on the
|
|
|
@@ -55,10 +56,10 @@ follows:
|
|
|
auto factory = entt::meta<my_type>().type("reflected_type"_hs);
|
|
|
```
|
|
|
|
|
|
-For what it's worth, this is likely completely equivalent to:
|
|
|
+For what it's worth, this is completely equivalent to:
|
|
|
|
|
|
```cpp
|
|
|
-auto factory = entt::meta<my_type>().type(42);
|
|
|
+auto factory = entt::meta<my_type>().type(42u);
|
|
|
```
|
|
|
|
|
|
Obviously, human-readable identifiers are more convenient to use and highly
|
|
|
@@ -76,18 +77,15 @@ type to reflect as a template parameter:
|
|
|
auto factory = entt::meta<my_type>();
|
|
|
```
|
|
|
|
|
|
-This isn't enough to _export_ the given type and make it visible though.<br/>
|
|
|
The returned value is a factory object to use to continue building the meta
|
|
|
-type. In order to make the type _visible_, users can assign it an identifier:
|
|
|
+type.
|
|
|
|
|
|
-```cpp
|
|
|
-auto factory = entt::meta<my_type>().type("reflected_type"_hs);
|
|
|
-```
|
|
|
-
|
|
|
-Or use the default one, that is, the built-in identifier for the given type:
|
|
|
+By default, a meta type is associated with the identifier returned by the
|
|
|
+runtime type identification system built-in in `EnTT`.<br/>
|
|
|
+However, it's also possible to assign custom identifiers to meta types:
|
|
|
|
|
|
```cpp
|
|
|
-auto factory = entt::meta<my_type>().type();
|
|
|
+auto factory = entt::meta<my_type>().type("reflected_type"_hs);
|
|
|
```
|
|
|
|
|
|
Identifiers are important because users can retrieve meta types at runtime by
|
|
|
@@ -263,20 +261,20 @@ the reflected types at once. It returns an iterable object that can be used in a
|
|
|
range-for loop:
|
|
|
|
|
|
```cpp
|
|
|
-for(auto type: entt::resolve()) {
|
|
|
+for(auto &&[id, type]: entt::resolve()) {
|
|
|
// ...
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-In all cases, the returned value is an instance of `meta_type`. This kind of
|
|
|
-objects offer an API to know their _runtime identifiers_, to iterate all the
|
|
|
-meta objects associated with them and even to build instances of the underlying
|
|
|
-type.<br/>
|
|
|
+In all cases, the returned value is an instance of `meta_type` (possibly with
|
|
|
+its id). This kind of objects offer an API to know their _runtime identifiers_,
|
|
|
+to iterate all the meta objects associated with them and even to build 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:
|
|
|
+Meta data members and functions are accessed by name among the other things:
|
|
|
|
|
|
-* _Meta data_. They are accessed by _name_:
|
|
|
+* Meta data members:
|
|
|
|
|
|
```cpp
|
|
|
auto data = entt::resolve<my_type>().data("member"_hs);
|
|
|
@@ -288,7 +286,7 @@ The meta objects that compose a meta type are accessed in the following ways:
|
|
|
know if it's a const or a static one), to get the meta type of the variable
|
|
|
and to set or get the contained value.
|
|
|
|
|
|
-* _Meta functions_. They are accessed by _name_:
|
|
|
+* Meta function members:
|
|
|
|
|
|
```cpp
|
|
|
auto func = entt::resolve<my_type>().func("member"_hs);
|
|
|
@@ -302,16 +300,7 @@ The meta objects that compose a meta type are accessed in the following ways:
|
|
|
addition, a meta function object can be used to invoke the underlying function
|
|
|
and then get the return value in the form of a `meta_any` object.
|
|
|
|
|
|
-* _Meta bases_. They are accessed through the _name_ of the base types:
|
|
|
-
|
|
|
- ```cpp
|
|
|
- auto base = entt::resolve<derived_type>().base("base"_hs);
|
|
|
- ```
|
|
|
-
|
|
|
- The returned type is `meta_type` and may be invalid if there is no meta base
|
|
|
- object associated with the given identifier.
|
|
|
-
|
|
|
-All the objects thus obtained as well as the meta types can be explicitly
|
|
|
+All the meta objects thus obtained as well as the meta types can be explicitly
|
|
|
converted to a boolean value to check if they are valid:
|
|
|
|
|
|
```cpp
|
|
|
@@ -320,16 +309,17 @@ if(auto func = entt::resolve<my_type>().func("member"_hs); func) {
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-Furthermore, all them are also returned by specific overloads that provide the
|
|
|
-caller with iterable ranges of top-level elements. As an example:
|
|
|
+Furthermore, all them (and a few more, like meta basis) are returned by a bunch
|
|
|
+of overloads that provide the caller with iterable ranges of top-level elements.
|
|
|
+As an example:
|
|
|
|
|
|
```cpp
|
|
|
-for(auto data: entt::resolve<my_type>().data()) {
|
|
|
+for(auto &&[id, type]: entt::resolve<my_type>().base()) {
|
|
|
// ...
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-A meta type can be used to `construct` actual instances of the underlying
|
|
|
+A meta type can also be used to `construct` actual instances of the underlying
|
|
|
type.<br/>
|
|
|
In particular, the `construct` member function accepts a variable number of
|
|
|
arguments and searches for a match. It then returns a `meta_any` object that may
|
|
|
@@ -366,6 +356,7 @@ particular:
|
|
|
|
|
|
* `std::vector`, `std::array`, `std::deque` and `std::list` (but not
|
|
|
`std::forward_list`) are supported as _sequence containers_.
|
|
|
+
|
|
|
* `std::map`, `std::set` and their unordered counterparts are supported as
|
|
|
_associative containers_.
|
|
|
|
|
|
@@ -905,7 +896,7 @@ Sometimes (for example, when it comes to creating an editor) it might be useful
|
|
|
to attach properties to the meta objects created. Fortunately, this is possible
|
|
|
for most of them.<br/>
|
|
|
For the meta objects that support properties, the member functions of the
|
|
|
-factory used for registering them will return a decorated version of the factory
|
|
|
+factory used for registering them will return an extended version of the factory
|
|
|
itself. The latter can be used to attach properties to the last created meta
|
|
|
object.<br/>
|
|
|
Apparently, it's more difficult to say than to do:
|
|
|
@@ -914,41 +905,19 @@ Apparently, it's more difficult to say than to do:
|
|
|
entt::meta<my_type>().type("reflected_type"_hs).prop("tooltip"_hs, "message");
|
|
|
```
|
|
|
|
|
|
-Properties are always in the key/value form. There are no restrictions on the
|
|
|
-type of the key or value, as long as they are copy constructible objects.<br/>
|
|
|
-Multiple formats are supported when it comes to defining a property:
|
|
|
-
|
|
|
-* Properties as key/value pairs:
|
|
|
-
|
|
|
- ```cpp
|
|
|
- entt::meta<my_type>().type("reflected_type"_hs).prop("tooltip"_hs, "message");
|
|
|
- ```
|
|
|
-
|
|
|
-* Properties as `std::pair`s:
|
|
|
-
|
|
|
- ```cpp
|
|
|
- entt::meta<my_type>().type("reflected_type"_hs).prop(std::make_pair("tooltip"_hs, "message"));
|
|
|
- ```
|
|
|
-
|
|
|
-* Key only properties:
|
|
|
-
|
|
|
- ```cpp
|
|
|
- entt::meta<my_type>().type("reflected_type"_hs).prop(my_enum::key_only);
|
|
|
- ```
|
|
|
-
|
|
|
-* Properties as `std::tuple`s:
|
|
|
+Properties are always in the key/value form. The key is a numeric identifier,
|
|
|
+mostly similar to the identifier used to register meta objects. There are no
|
|
|
+restrictions on the type of the value instead, as long as it's movable.<br/>
|
|
|
+Key only properties are also supported out of the box:
|
|
|
|
|
|
- ```cpp
|
|
|
- entt::meta<my_type>().type("reflected_type"_hs).prop(std::make_tuple(std::make_pair("tooltip"_hs, "message"), my_enum::key_only));
|
|
|
- ```
|
|
|
-
|
|
|
- A tuple contains one or more properties. All of them are treated individually.
|
|
|
+```cpp
|
|
|
+entt::meta<my_type>().type("reflected_type"_hs).prop(my_enum::key_only);
|
|
|
+```
|
|
|
|
|
|
-Note that it's not possible to invoke `prop` multiple times for the same meta
|
|
|
-object and trying to do that will result in a compilation error.<br/>
|
|
|
-However, the `props` function is available to associate several properties at
|
|
|
-once. In this case, properties in the key/value form aren't allowed, since they
|
|
|
-would be interpreted as two different properties rather than a single one.
|
|
|
+To attach multiple properties to a meta object, it's possible to invoke `prop`
|
|
|
+more than once.<br/>
|
|
|
+It's also possible to invoke `prop` at different times, as long as the factory
|
|
|
+is reset to the meta object of interest.
|
|
|
|
|
|
The meta objects for which properties are supported are currently meta types,
|
|
|
meta data and meta functions.<br/>
|
|
|
@@ -957,7 +926,7 @@ properties at once or to search a specific property by key:
|
|
|
|
|
|
```cpp
|
|
|
// iterate all properties of a meta type
|
|
|
-for(auto prop: entt::resolve<my_type>().prop()) {
|
|
|
+for(auto &&[id, prop]: entt::resolve<my_type>().prop()) {
|
|
|
// ...
|
|
|
}
|
|
|
|
|
|
@@ -966,37 +935,54 @@ auto prop = entt::resolve<my_type>().prop("tooltip"_hs);
|
|
|
```
|
|
|
|
|
|
Meta properties are objects having a fairly poor interface, all in all. They
|
|
|
-only provide the `key` and the `value` member functions to be used to retrieve
|
|
|
-the key and the value contained in the form of `meta_any` objects, respectively.
|
|
|
+only provide the `value` member function to retrieve the contained value in the
|
|
|
+form of a `meta_any` object.
|
|
|
|
|
|
## Unregister types
|
|
|
|
|
|
A type registered with the reflection system can also be unregistered. This
|
|
|
means unregistering all its data members, member functions, conversion functions
|
|
|
and so on. However, base classes aren't unregistered as well, since they don't
|
|
|
-necessarily depend on it. Similarly, implicitly generated types (as an example,
|
|
|
-the meta types implicitly generated for function parameters when needed) aren't
|
|
|
-unregistered.<br/>
|
|
|
+necessarily depend on it.<br/>
|
|
|
Roughly speaking, unregistering a type means disconnecting all associated meta
|
|
|
-objects from it and making its identifier no longer visible. The underlying node
|
|
|
-will remain available though, as if it were implicitly generated:
|
|
|
+objects from it and making its identifier no longer available:
|
|
|
|
|
|
```cpp
|
|
|
entt::meta_reset<my_type>();
|
|
|
```
|
|
|
|
|
|
-It's also possible to reset types by their unique identifiers if required:
|
|
|
+It's also possible to reset types by their unique identifiers:
|
|
|
|
|
|
```cpp
|
|
|
entt::meta_reset("my_type"_hs);
|
|
|
```
|
|
|
|
|
|
Finally, there exists a non-template overload of the `meta_reset` function that
|
|
|
-doesn't accept argument and resets all searchable types (that is, all types that
|
|
|
-were assigned an unique identifier):
|
|
|
+doesn't accept arguments and resets all meta types at once:
|
|
|
|
|
|
```cpp
|
|
|
entt::meta_reset();
|
|
|
```
|
|
|
|
|
|
-All types can be re-registered later with a completely different name and form.
|
|
|
+A type can be re-registered later with a completely different name and form.
|
|
|
+
|
|
|
+## Meta context
|
|
|
+
|
|
|
+All meta types and their parts are created at runtime and stored in a default
|
|
|
+_context_. This can be reached via a service locator as:
|
|
|
+
|
|
|
+```cpp
|
|
|
+auto &&context = entt::locator<entt::meta_context>::value_or();
|
|
|
+```
|
|
|
+
|
|
|
+By itself, a context is an opaque object that the user cannot do much with.
|
|
|
+However, users can replace an existing context with another at any time:
|
|
|
+
|
|
|
+```cpp
|
|
|
+entt::meta_context other{};
|
|
|
+auto &&context = entt::locator<entt::meta_context>::value_or();
|
|
|
+std::swap(context, other);
|
|
|
+```
|
|
|
+
|
|
|
+This can be useful for testing purposes or to define multiple contexts with
|
|
|
+different meta objects to be used as appropriate.
|