1515 * [ From void to any] ( #from-void-to-any )
1616 * [ Policies: the more, the less] ( #policies-the-more-the-less )
1717 * [ Named constants and enums] ( #named-constants-and-enums )
18- * [ Properties and meta objects] ( #properties-and-meta-objects )
18+ * [ Properties vs traits] ( #properties-and-traits )
19+ * [ Properties and meta objects] ( #properties-and-meta-objects )
20+ * [ User defined traits] ( #user-defined-traits )
1921 * [ Unregister types] ( #unregister-types )
2022 * [ Meta context] ( #meta-context )
2123
@@ -835,18 +837,31 @@ auto max = entt::resolve<int>().data("max_int"_hs).get({}).cast<int>();
835837All this happens behind the scenes without any allocation because of the small
836838object optimization performed by the ` meta_any ` class.
837839
838- ## Properties and meta objects
840+ ## Properties vs traits
839841
840842Sometimes (for example, when it comes to creating an editor) it might be useful
841- to attach properties to the meta objects created. Fortunately, this is possible
842- for most of them:
843+ to attach _ properties_ and _ traits_ to the meta objects created.
844+
845+ The biggest difference between the two is that traits are simple user-defined
846+ flags with much higher access performance while properties are usually key-only
847+ or key-value pairs with lower access performance.<br />
848+ Another important difference is that ` EnTT ` reserves up to 16 bits for traits,
849+ that is 16 flags for a bitmask or 2^16 values otherwise. On the other hand,
850+ there is no limit on the number of properties available.
851+
852+ Both properties and traits are currently available only for meta types, meta
853+ data and meta functions.
854+
855+ ### Properties and meta objects
856+
857+ Properties are set via a meta factory and are not editable once created:
843858
844859``` cpp
845860entt::meta<my_type>().type(" reflected_type" _hs).prop(" tooltip" _hs, " message" );
846861```
847862
848- Properties are always in the key/value form. The key is a numeric identifier,
849- mostly similar to the identifier used to register meta objects. There are no
863+ They are always in the key/value form. The key is a numeric identifier, mostly
864+ similar to the identifier used to register meta objects. There are no
850865restrictions on the type of the value instead, as long as it's movable.<br />
851866Key only properties are also supported out of the box:
852867
@@ -857,12 +872,19 @@ entt::meta<my_type>().type("reflected_type"_hs).prop(my_enum::key_only);
857872To attach multiple properties to a meta object, just invoke ` prop ` more than
858873once.<br />
859874It's also possible to call ` prop ` at different times, as long as the factory is
860- reset to the meta object of interest.
875+ reset to the meta object of interest. For example, to attach a property to an
876+ already existing meta data object:
877+
878+ ``` cpp
879+ entt::meta<my_type>().data(" member" _hs).prop(" key" _hs, value);
880+ ```
881+
882+ The ` data ` and ` func ` overloads which accept only the name of the member to be
883+ searched for assume that it already exists and make it the _ current element_ for
884+ subsequent calls.
861885
862- The meta objects for which properties are supported are currently meta types,
863- meta data and meta functions.<br />
864- These types also offer a couple of member functions named ` prop ` to iterate all
865- properties at once or to search a specific property by key:
886+ Once created, all meta objects offer a couple of member functions named ` prop `
887+ to iterate all properties at once or to search a specific property by key:
866888
867889``` cpp
868890// iterate all properties of a meta type
@@ -878,6 +900,39 @@ Meta properties are objects having a fairly poor interface, all in all. They
878900only provide the ` value ` member function to retrieve the contained value in the
879901form of a ` meta_any ` object.
880902
903+ ### User defined traits
904+
905+ User-defined traits are also set via a meta factory:
906+
907+ ``` cpp
908+ entt::meta<my_type>().type(" reflected_type" _hs).traits(my_traits::required | my_traits::hidden);
909+ ```
910+
911+ In the example above ` EnTT ` bitmask enum support is used but any integral value
912+ is fine, as long as it doesn't exceed 16 bits.<br />
913+ As for traits, it's not possible to assign them at different times. Therefore,
914+ multiple calls to the ` traits ` function overwrite previous values. However, it's
915+ still possible to set traits later if necessary:
916+
917+ ``` cpp
918+ entt::meta<my_type>().func(" invoke" _hs).traits(my_traits::internal);
919+ ```
920+
921+ The ` data ` and ` func ` overloads which accept only the name of the member to be
922+ searched for assume that it already exists and make it the _ current element_ for
923+ subsequent calls.
924+
925+ Once created, all meta objects offer a member function named ` traits ` to get the
926+ currently set value:
927+
928+ ``` cpp
929+ auto value = entt::resolve<my_type>().traits<my_traits>();
930+ ```
931+
932+ Note that the type is erased upon registration and must therefore be repeated
933+ when traits are _ extracted_ , so as to allow the library to _ reconstruct_ them
934+ correctly.
935+
881936## Unregister types
882937
883938A type registered with the reflection system can also be _ unregistered_ . This
0 commit comments