|
|
@@ -15,9 +15,10 @@
|
|
|
* [From void to any](#from-void-to-any)
|
|
|
* [Policies: the more, the less](#policies-the-more-the-less)
|
|
|
* [Named constants and enums](#named-constants-and-enums)
|
|
|
- * [Properties vs traits](#properties-vs-traits)
|
|
|
+ * [User defined data](#user-defined-data)
|
|
|
* [Properties and meta objects](#properties-and-meta-objects)
|
|
|
- * [User defined traits](#user-defined-traits)
|
|
|
+ * [Traits](#traits)
|
|
|
+ * [Custom data](#custom-data)
|
|
|
* [Unregister types](#unregister-types)
|
|
|
* [Meta context](#meta-context)
|
|
|
|
|
|
@@ -837,27 +838,34 @@ auto max = entt::resolve<int>().data("max_int"_hs).get({}).cast<int>();
|
|
|
All this happens behind the scenes without any allocation because of the small
|
|
|
object optimization performed by the `meta_any` class.
|
|
|
|
|
|
-## Properties vs traits
|
|
|
+## User defined data
|
|
|
|
|
|
Sometimes (for example, when it comes to creating an editor) it might be useful
|
|
|
-to attach _properties_ and _traits_ to the meta objects created.
|
|
|
+to attach _properties_, _traits_ or arbitrary _custom data_ to the meta objects
|
|
|
+created.
|
|
|
|
|
|
-The biggest difference between the two is that traits are simple user-defined
|
|
|
-flags with much higher access performance while properties are usually key-only
|
|
|
-or key-value pairs with lower access performance.<br/>
|
|
|
-Another important difference is that `EnTT` reserves up to 16 bits for traits,
|
|
|
-that is 16 flags for a bitmask or 2^16 values otherwise. On the other hand,
|
|
|
-there is no limit on the number of properties available.
|
|
|
+The main difference between them is that:
|
|
|
|
|
|
-Both properties and traits are currently available only for meta types, meta
|
|
|
-data and meta functions.
|
|
|
+* Properties are usually key-only or key-value pairs with lower access
|
|
|
+ performance. They are deprecated today but have long been the only way to
|
|
|
+ bind user data with meta objects.
|
|
|
+
|
|
|
+* Traits are simple user-defined flags with much higher access performance. The
|
|
|
+ library reserves up to 16 bits for traits, that is 16 flags for a bitmask or
|
|
|
+ 2^16 values otherwise.
|
|
|
+
|
|
|
+* Custom data are stored in a generic quick access area reserved for the user
|
|
|
+ and which the library will never use under any circumstances.
|
|
|
+
|
|
|
+In all cases, this support is currently available only for meta types, meta data
|
|
|
+and meta functions.
|
|
|
|
|
|
### Properties and meta objects
|
|
|
|
|
|
Properties are set via a meta factory and are not editable once created:
|
|
|
|
|
|
```cpp
|
|
|
-entt::meta<my_type>().type("reflected_type"_hs).prop("tooltip"_hs, "message");
|
|
|
+entt::meta<my_type>().prop("tooltip"_hs, "message");
|
|
|
```
|
|
|
|
|
|
They are always in the key/value form. The key is a numeric identifier, mostly
|
|
|
@@ -866,7 +874,7 @@ 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(my_enum::key_only);
|
|
|
+entt::meta<my_type>().prop(my_enum::key_only);
|
|
|
```
|
|
|
|
|
|
To attach multiple properties to a meta object, just invoke `prop` more than
|
|
|
@@ -900,22 +908,24 @@ Meta properties are objects having a fairly poor interface, all in all. They
|
|
|
only provide the `value` member function to retrieve the contained value in the
|
|
|
form of a `meta_any` object.
|
|
|
|
|
|
-### User defined traits
|
|
|
+### Traits
|
|
|
|
|
|
-User-defined traits are also set via a meta factory:
|
|
|
+User-defined traits are set via a meta factory:
|
|
|
|
|
|
```cpp
|
|
|
-entt::meta<my_type>().type("reflected_type"_hs).traits(my_traits::required | my_traits::hidden);
|
|
|
+entt::meta<my_type>().traits(my_traits::required | my_traits::hidden);
|
|
|
```
|
|
|
|
|
|
-In the example above `EnTT` bitmask enum support is used but any integral value
|
|
|
+In the example above, `EnTT` bitmask enum support is used but any integral value
|
|
|
is fine, as long as it doesn't exceed 16 bits.<br/>
|
|
|
-As for traits, it's not possible to assign them at different times. Therefore,
|
|
|
-multiple calls to the `traits` function overwrite previous values. However, it's
|
|
|
-still possible to set traits later if necessary:
|
|
|
+It's not possible to assign traits at different times. Therefore, multiple calls
|
|
|
+to the `traits` function overwrite previous values. However, traits can be read
|
|
|
+from meta objects and used to update existing data with a factory, effectively
|
|
|
+extending them as needed.<br/>
|
|
|
+Likewise, users can also set traits on meta objects later if needed:
|
|
|
|
|
|
```cpp
|
|
|
-entt::meta<my_type>().func("invoke"_hs).traits(my_traits::internal);
|
|
|
+entt::meta<my_type>().data("member"_hs).traits(my_traits::internal);
|
|
|
```
|
|
|
|
|
|
The `data` and `func` overloads which accept only the name of the member to be
|
|
|
@@ -933,6 +943,40 @@ Note that the type is erased upon registration and must therefore be repeated
|
|
|
when traits are _extracted_, so as to allow the library to _reconstruct_ them
|
|
|
correctly.
|
|
|
|
|
|
+### Custom data
|
|
|
+
|
|
|
+Custom arbitrary data are set via a meta factory:
|
|
|
+
|
|
|
+```cpp
|
|
|
+entt::meta<my_type>().custom<type_data>("name");
|
|
|
+```
|
|
|
+
|
|
|
+The way to do this is by specifying the data type to the `custom` function and
|
|
|
+passing the necessary arguments to construct it correctly.<br/>
|
|
|
+It's not possible to assign custom data at different times. Therefore, multiple
|
|
|
+calls to the `custom` function overwrite previous values. However, this value
|
|
|
+can be read from meta objects and used to update existing data with a factory,
|
|
|
+effectively extending them as needed.<br/>
|
|
|
+Likewise, users can also set custom data on meta objects later if needed:
|
|
|
+
|
|
|
+```cpp
|
|
|
+entt::meta<my_type>().func("invoke"_hs).custom<function_data>("tooltip");
|
|
|
+```
|
|
|
+
|
|
|
+The `data` and `func` overloads which accept only the name of the member to be
|
|
|
+searched for assume that it already exists and make it the _current element_ for
|
|
|
+subsequent calls.
|
|
|
+
|
|
|
+Once created, all meta objects offer a member function named `custom` to get the
|
|
|
+currently set value as a const reference or as a pointer to a const element:
|
|
|
+
|
|
|
+```cpp
|
|
|
+const type_data &value = entt::resolve<my_type>().custom();
|
|
|
+```
|
|
|
+
|
|
|
+Note that the returned object performs an extra check in debug before converting
|
|
|
+to the requested type, so as to avoid subtle bugs.
|
|
|
+
|
|
|
## Unregister types
|
|
|
|
|
|
A type registered with the reflection system can also be _unregistered_. This
|