Files
entt/md_docs_md_core.html
2019-12-19 15:16:07 +01:00

171 lines
14 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.16"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>EnTT: Crash Course: core functionalities</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">EnTT
&#160;<span id="projectnumber">3.2.2</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.16 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
</div><!-- top -->
<div class="PageDoc"><div class="header">
<div class="headertitle">
<div class="title">Crash Course: core functionalities </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="autotoc_md1"></a>
Introduction</h1>
<p><code>EnTT</code> comes with a bunch of core functionalities mostly used by the other parts of the library itself.<br />
Hardly users will include these features in their code, but it's worth describing what <code>EnTT</code> offers so as not to reinvent the wheel in case of need.</p>
<h1><a class="anchor" id="autotoc_md2"></a>
Compile-time identifiers</h1>
<p>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 that fully embraces what the modern C++ has to offer.</p>
<p>The <em>result of my efforts</em> is the <code>identifier</code> class template:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;ident.hpp&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// defines the identifiers for the given types</span></div>
<div class="line"><span class="keyword">using</span> <span class="keywordtype">id</span> = <a class="code" href="classentt_1_1identifier.html">entt::identifier&lt;a_type, another_type&gt;</a>;</div>
<div class="line"> </div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordflow">switch</span>(a_type_identifier) {</div>
<div class="line"><span class="keywordflow">case</span> id::type&lt;a_type&gt;:</div>
<div class="line"> <span class="comment">// ...</span></div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"><span class="keywordflow">case</span> id::type&lt;another_type&gt;:</div>
<div class="line"> <span class="comment">// ...</span></div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"><span class="keywordflow">default</span>:</div>
<div class="line"> <span class="comment">// ...</span></div>
<div class="line">}</div>
</div><!-- fragment --><p>This is all what the class template has to offer: a <code>type</code> inline variable that contains a numerical identifier for the given type. It can be used in any context where constant expressions are required.</p>
<p>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:</p>
<div class="fragment"><div class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span>&gt; <span class="keyword">struct </span>ignore_type {};</div>
<div class="line"> </div>
<div class="line"><span class="keyword">using</span> <span class="keywordtype">id</span> = <a class="code" href="classentt_1_1identifier.html">entt::identifier</a>&lt;</div>
<div class="line"> a_type_still_valid,</div>
<div class="line"> ignore_type&lt;a_type_no_longer_valid&gt;,</div>
<div class="line"> another_type_still_valid</div>
<div class="line">&gt;;</div>
</div><!-- fragment --><p>A bit ugly to see, but it works at least.</p>
<h1><a class="anchor" id="autotoc_md3"></a>
Runtime identifiers</h1>
<p>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.</p>
<p>It's the <code>family</code> class. Here is an example of use directly from the entity-component system:</p>
<div class="fragment"><div class="line"><span class="keyword">using</span> component_family = <a class="code" href="classentt_1_1family.html">entt::family&lt;struct internal_registry_component_family&gt;</a>;</div>
<div class="line"> </div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> Component&gt;</div>
<div class="line">component_type component() const noexcept {</div>
<div class="line"> <span class="keywordflow">return</span> component_family::type&lt;Component&gt;;</div>
<div class="line">}</div>
</div><!-- fragment --><p>This is all what a <em>family</em> has to offer: a <code>type</code> inline variable that contains a numerical identifier for the given type.</p>
<p>Please, note that identifiers aren't guaranteed to be the same for every run. Indeed it mostly depends on the flow of execution.</p>
<h1><a class="anchor" id="autotoc_md4"></a>
Hashed strings</h1>
<p>A hashed string is a zero overhead unique identifier. Users can use human-readable identifiers in the codebase while using their numeric counterparts at runtime, thus without affecting performance.<br />
The class has an implicit <code>constexpr</code> constructor that chews a bunch of characters. Once created, all what one can do with it is getting back the original string or converting it into a number.<br />
The good part is that a hashed string can be used wherever a constant expression is required and no <em>string-to-number</em> conversion will take place at runtime if used carefully.</p>
<p>Example of use:</p>
<div class="fragment"><div class="line"><span class="keyword">auto</span> load(<a class="code" href="classentt_1_1basic__hashed__string.html#a7ee7dca5383cf4507949dc1261ca5efd">entt::hashed_string::hash_type</a> resource) {</div>
<div class="line"> <span class="comment">// uses the numeric representation of the resource to load and return it</span></div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keyword">auto</span> resource = load(<a class="code" href="classentt_1_1basic__hashed__string.html">entt::hashed_string</a>{<span class="stringliteral">&quot;gui/background&quot;</span>});</div>
</div><!-- fragment --><p>There is also a <em>user defined literal</em> dedicated to hashed strings to make them more user-friendly:</p>
<div class="fragment"><div class="line">constexpr <span class="keyword">auto</span> str = <span class="stringliteral">&quot;text&quot;</span>_hs;</div>
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md5"></a>
Wide characters</h2>
<p>The hashed string has a design that is close to that of an <code>std::basic_string</code>. It means that <code>hashed_string</code> is nothing more than an alias for <code>basic_hashed_string&lt;char&gt;</code>. For those who want to use the C++ type for wide character representation, there exists also the alias <code>hashed_wstring</code> for <code>basic_hashed_string&lt;wchar_t&gt;</code>.<br />
In this case, the user defined literal to use to create hashed strings on the fly is <code>_hws</code>:</p>
<div class="fragment"><div class="line">constexpr <span class="keyword">auto</span> str = <span class="stringliteral">&quot;text&quot;</span>_hws;</div>
</div><!-- fragment --><p>Note that the hash type of the <code>hashed_wstring</code> is the same of its counterpart.</p>
<h2><a class="anchor" id="autotoc_md6"></a>
Conflicts</h2>
<p>The hashed string class uses internally FNV-1a to compute the numeric counterpart of a string. Because of the <em>pigeonhole principle</em>, conflicts are possible. This is a fact.<br />
There is no silver bullet to solve the problem of conflicts when dealing with hashing functions. In this case, the best solution seemed to be to give up. That's all.<br />
After all, human-readable unique identifiers aren't something strictly defined and over which users have not the control. Choosing a slightly different identifier is probably the best solution to make the conflict disappear in this case.</p>
<h1><a class="anchor" id="autotoc_md7"></a>
Monostate</h1>
<p>The monostate pattern is often presented as an alternative to a singleton based configuration system. This is exactly its purpose in <code>EnTT</code>. Moreover, this implementation is thread safe by design (hopefully).<br />
Keys are represented by hashed strings, values are basic types like <code>int</code>s or <code>bool</code>s. Values of different types can be associated to each key, even more than one at a time. Because of this, users must pay attention to use the same type both during an assignment and when they try to read back their data. Otherwise, they will probably incur in unexpected results.</p>
<p>Example of use:</p>
<div class="fragment"><div class="line"><a class="code" href="structentt_1_1monostate.html">entt::monostate</a>&lt;<a class="code" href="classentt_1_1basic__hashed__string.html">entt::hashed_string</a>{<span class="stringliteral">&quot;mykey&quot;</span>}&gt;{} = <span class="keyword">true</span>;</div>
<div class="line"><a class="code" href="structentt_1_1monostate.html">entt::monostate</a>&lt;<span class="stringliteral">&quot;mykey&quot;</span>_hs&gt;{} = 42;</div>
<div class="line"> </div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">bool</span> b = <a class="code" href="structentt_1_1monostate.html">entt::monostate</a>&lt;<span class="stringliteral">&quot;mykey&quot;</span>_hs&gt;{};</div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">int</span> i = <a class="code" href="structentt_1_1monostate.html">entt::monostate</a>&lt;<a class="code" href="classentt_1_1basic__hashed__string.html">entt::hashed_string</a>{<span class="stringliteral">&quot;mykey&quot;</span>}&gt;{};</div>
</div><!-- fragment --> </div></div><!-- contents -->
</div><!-- PageDoc -->
<div class="ttc" id="astructentt_1_1monostate_html"><div class="ttname"><a href="structentt_1_1monostate.html">entt::monostate</a></div><div class="ttdoc">Minimal implementation of the monostate pattern.</div><div class="ttdef"><b>Definition:</b> <a href="monostate_8hpp_source.html#l00024">monostate.hpp:24</a></div></div>
<div class="ttc" id="aclassentt_1_1basic__hashed__string_html"><div class="ttname"><a href="classentt_1_1basic__hashed__string.html">entt::basic_hashed_string</a></div><div class="ttdoc">Zero overhead unique identifier.</div><div class="ttdef"><b>Definition:</b> <a href="hashed__string_8hpp_source.html#l00060">hashed_string.hpp:60</a></div></div>
<div class="ttc" id="aclassentt_1_1basic__hashed__string_html_a7ee7dca5383cf4507949dc1261ca5efd"><div class="ttname"><a href="classentt_1_1basic__hashed__string.html#a7ee7dca5383cf4507949dc1261ca5efd">entt::basic_hashed_string::hash_type</a></div><div class="ttdeci">ENTT_ID_TYPE hash_type</div><div class="ttdoc">Unsigned integer type.</div><div class="ttdef"><b>Definition:</b> <a href="hashed__string_8hpp_source.html#l00078">hashed_string.hpp:78</a></div></div>
<div class="ttc" id="aclassentt_1_1identifier_html"><div class="ttname"><a href="classentt_1_1identifier.html">entt::identifier</a></div><div class="ttdoc">Types identifiers.</div><div class="ttdef"><b>Definition:</b> <a href="ident_8hpp_source.html#l00042">ident.hpp:42</a></div></div>
<div class="ttc" id="aclassentt_1_1family_html"><div class="ttname"><a href="classentt_1_1family.html">entt::family</a></div><div class="ttdoc">Dynamic identifier generator.</div><div class="ttdef"><b>Definition:</b> <a href="family_8hpp_source.html#l00020">family.hpp:20</a></div></div>
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.16
</small></address>
</body>
</html>