Преглед на файлове

doc: updated core section

Michele Caini преди 6 години
родител
ревизия
30d426d667
променени са 1 файла, в които са добавени 86 реда и са изтрити 60 реда
  1. 86 60
      docs/md/core.md

+ 86 - 60
docs/md/core.md

@@ -6,17 +6,20 @@
 # Table of Contents
 
 * [Introduction](#introduction)
-* [Compile-time identifiers](#compile-time-identifiers)
-* [Runtime identifiers](#runtime-identifiers)
+* [Unique sequential identifiers](#unique-sequential-identifiers)
+  * [Compile-time generator](#compile-time-generator)
+  * [Runtime generator](#runtime-generator)
 * [Hashed strings](#hashed-strings)
   * [Wide characters](wide-characters)
   * [Conflicts](#conflicts)
 * [Monostate](#monostate)
 * [Type info](#type-info)
-  * [Almost unique identifiers](#almost-unique-identifiers)
+  * [Type identifier](#type-identifier)
+    * [Almost unique identifiers](#almost-unique-identifiers)
+  * [Type index](#type-index)
 * [Traits](#traits)
   * [Member class type](#member-class-type)
-  * [Tags](#tags)
+  * [Integral constant](#integral-constant)
 <!--
 @endcond TURN_OFF_DOXYGEN
 -->
@@ -28,19 +31,20 @@ of the library itself.<br/>
 Hardly users will include these features in their code, but it's worth
 describing what `EnTT` offers so as not to reinvent the wheel in case of need.
 
-# Compile-time identifiers
+# Unique sequential identifiers
 
-Sometimes it's useful to be able to give unique identifiers to types at
-compile-time.<br/>
-There are plenty of different solutions out there and I could have used one of
-them. However, I decided to spend my time to define a compact and versatile tool
+Sometimes it's useful to be able to give unique, sequential numeric identifiers
+to types either at compile-time or runtime.<br/>
+There are plenty of different solutions for this out there and I could have used
+one of them. However, I decided to spend my time to define a couple of tools
 that fully embraces what the modern C++ has to offer.
 
-The _result of my efforts_ is the `identifier` class template:
+## Compile-time generator
 
-```cpp
-#include <ident.hpp>
+To generate sequential numeric identifiers at compile-time, `EnTT` offers the
+`identifier` class template:
 
+```cpp
 // defines the identifiers for the given types
 using id = entt::identifier<a_type, another_type>;
 
@@ -58,14 +62,14 @@ default:
 }
 ```
 
-This is all what the class template has to offer: a `type` inline variable that
-contains a numerical identifier for the given type. It can be used in any
-context where constant expressions are required.
+This is all what this class template has to offer: a `type` inline variable that
+contains a numeric identifier for the given type. It can be used in any context
+where constant expressions are required.
 
-As long as the list remains unchanged, identifiers are also guaranteed to be the
-same for every run. In case they have been used in a production environment and
-a type has to be removed, one can just use a placeholder to left the other
-identifiers unchanged:
+As long as the list remains unchanged, identifiers are also guaranteed to be
+stable across different runs. In case they have been used in a production
+environment and a type has to be removed, one can just use a placeholder to left
+the other identifiers unchanged:
 
 ```cpp
 template<typename> struct ignore_type {};
@@ -77,35 +81,30 @@ using id = entt::identifier<
 >;
 ```
 
-A bit ugly to see, but it works at least.
-
-# Runtime identifiers
+Perhaps a bit ugly to see in a codebase but it gets the job done at least.
 
-Sometimes it's useful to be able to give unique identifiers to types at
-runtime.<br/>
-There are plenty of different solutions out there and I could have used one of
-them. In fact, I adapted the most common one to my requirements and used it
-extensively within the entire library.
+## Runtime generator
 
-It's the `family` class. Here is an example of use directly from the
-entity-component system:
+To generate sequential numeric identifiers at runtime, `EnTT` offers the
+`family` class template:
 
 ```cpp
-using component_family = entt::family<struct internal_registry_component_family>;
+// defines a custom generator
+using id = entt::family<struct my_tag>;
 
 // ...
 
-template<typename Component>
-component_type component() const noexcept {
-    return component_family::type<Component>;
-}
+const auto a_type_id = id::type<a_type>;
+const auto another_type_id = id::type<another_type>;
 ```
 
 This is all what a _family_ has to offer: a `type` inline variable that contains
-a numerical identifier for the given type.
+a numeric identifier for the given type.<br/>
+The generator is customizable, so as to get different _sequences_ for different
+purposes if needed.
 
-Please, note that identifiers aren't guaranteed to be the same for every run.
-Indeed it mostly depends on the flow of execution.
+Please, note that identifiers aren't guaranteed to be stable across different
+runs. Indeed it mostly depends on the flow of execution.
 
 # Hashed strings
 
@@ -192,8 +191,14 @@ const int i = entt::monostate<entt::hashed_string{"mykey"}>{};
 
 The `type_info` class template is meant to provide some basic information about
 types of all kinds.<br/>
-Currently, the only information available is the numeric identifier associated
-with a given type:
+It's not a drop-in replacement for `std::type_info` but can provide similar
+information which are not implementation defined. Therefore, they can sometimes
+be even more reliable than those obtained otherwise.
+
+## Type identifier
+
+One of the available information is the numeric identifier associated with a
+given type:
 
 ```cpp
 auto id = entt::type_info<my_type>::id();
@@ -201,10 +206,10 @@ auto id = entt::type_info<my_type>::id();
 
 In general, the `id` function is also `constexpr` but this isn't guaranteed for
 all compilers and platforms (although it's valid with the most well-known and
-popular compilers).<br/>
+popular ones).<br/>
 This function **can** use non-standard features of the language for its own
 purposes. This allows it to provide compile-time identifiers that remain stable
-between different runs. However, it's possible to force the use of standard
+across different runs. However, it's possible to force the use of standard
 features only by defining the macro `ENTT_STANDARD_CPP`. In this case, there is
 no guarantee that the identifiers are stable across executions though. Moreover,
 identifiers are generated at runtime and are no longer a compile-time thing.
@@ -224,10 +229,10 @@ struct entt::type_info<Type, std::void_d<decltype(Type::custom_id())>> {
 
 Note that this class template and its specializations are widely used within
 `EnTT`. It also plays a very important role in making `EnTT` work transparently
-across boundaries.<br/>
+across boundaries in many cases.<br/>
 Please refer to the dedicated section for more details.
 
-## Almost unique identifiers
+### Almost unique identifiers
 
 Since the default non-standard, compile-time implementation makes use of hashed
 strings, it may happen that two types are assigned the same numeric
@@ -237,14 +242,13 @@ In fact, although this is quite rare, it's not entirely excluded.
 Another case where two types are assigned the same identifier is when classes
 from different contexts (for example two or more libraries loaded at runtime)
 have the same fully qualified name.<br/>
-Since the default model is based on the name of the classes, if the types belong
-to the same namespace then their identifiers _could_ be identical (they won't
-necessarily be the same though).
+If the types have the same name and belong to the same namespace then their
+identifiers _could_ be identical (they won't necessarily be the same though).
 
 Fortunately, there are several easy ways to deal with this:
 
-* The most trivial one is to define the `ENTT_STANDARD_CPP` macro. Note that
-  runtime identifiers don't suffer from the sam problem. However, this solution
+* The most trivial one is to define the `ENTT_STANDARD_CPP` macro. Runtime
+  identifiers don't suffer from the same problem in fact. However, this solution
   doesn't work well with a plugin system, where the libraries aren't linked.
 
 * Another possibility is to specialize the `type_info` class for one of the
@@ -260,6 +264,27 @@ their types, this problem is in any case easy to solve and should not worry too
 much.<br/>
 In all likelihood, it will never happen to run into a conflict anyway.
 
+## Type index
+
+Types in `EnTT` are assigned also unique, sequential _indexes_ generated at
+runtime:
+
+```cpp
+auto index = entt::type_info<my_type>::index();
+```
+
+This value may differ from the numeric identifier of a type and isn't guaranteed
+to be stable across different runs. However, it can be very useful as index in
+associative and unordered associative containers or for positional accesses in a
+vector or an array.
+
+So as not to conflict with the other tools available, the `family` class isn't
+used to generate these indexes. Therefore, the numeric identifiers returned by
+the two tools may differ.<br/>
+On the other hand, this leaves users with full powers over the `family` class
+and therefore the generation of custom runtime sequences of indices for their
+own purposes, if necessary.
+
 # Traits
 
 This section contains a handful of utilities and traits not present in the
@@ -277,20 +302,21 @@ template<typename Member>
 using clazz = entt::member_class_t<Member>;
 ```
 
-## Tags
+## Integral constant
 
-Since in `EnTT` the type identified by `ENTT_ID_TYPE` is very important and
-widely used, there is a more user-friendly shortcut for the creation of integral
-constants based on it.<br/>
-This shortcut is the alias template `entt::tag`.
-
-If used in combination with hashed strings, it helps to use human-readable names
-where types would be required otherwise. As an example:
+Since `std::integral_constant` may be annoying because of its form that requires
+to specify both a type and a value of that type, there is a more user-friendly
+shortcut for the creation of integral constants.<br/>
+This shortcut is the alias template `entt::integral_constant`:
 
 ```cpp
-registry.assign<entt::tag<"enemy"_hs>>(entity);
+constexpr auto constant = entt::integral_constant<42>;
 ```
 
-However, this isn't the only permitted use. Literally any value convertible to
-`ENTT_ID_TYPE` is a good candidate, such as the named constants of an unscoped
-enum.
+Among the other uses, when combined with a hashed string it helps to define tags
+as human-readable _names_ where actual types would be required otherwise:
+
+```cpp
+constexpr auto enemy_tag = entt::integral_constant<"enemy"_hs>;
+registry.emplace<enemy_tag>(entity);
+```