uvw/index.html
2023-05-22 11:13:58 +02:00

343 lines
34 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" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>uvw: uvw</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 id="projectrow">
<td id="projectalign">
<div id="projectname">uvw<span id="projectnumber">&#160;3.1.0</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.6 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @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:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- 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">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div><div class="header">
<div class="headertitle"><div class="title">uvw </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><a class="anchor" id="md_README"></a> <img src="https://user-images.githubusercontent.com/1812216/46069406-c977a600-c17b-11e8-9a47-9bba6f412c57.png" alt="uvw - libuv wrapper in modern C++" class="inline"/></p>
<h1><a class="anchor" id="autotoc_md0"></a>
Introduction</h1>
<p><code>uvw</code> started as a header-only, event based, tiny and easy to use wrapper for <a href="https://github.com/libuv/libuv"><code>libuv</code></a> written in modern C++.<br />
Now it's finally available also as a compilable static library.</p>
<p>The basic idea is to wrap the <em>C-ish</em> interface of <code>libuv</code> behind a graceful C++ API.<br />
Note that <code>uvw</code> stays true to the API of <code>libuv</code> and it doesn't add anything to its interface. For the same reasons, users of the library must follow the same rules which are used with <code>libuv</code>.<br />
As an example, a <em>handle</em> should be initialized before any other operation and closed once it is no longer in use.</p>
<h2><a class="anchor" id="autotoc_md1"></a>
Code Example</h2>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;uvw.hpp&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;memory&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> listen(<a class="code hl_class" href="classuvw_1_1loop.html">uvw::loop</a> &amp;loop) {</div>
<div class="line"> std::shared_ptr&lt;uvw::tcp_handle&gt; tcp = loop.<a class="code hl_function" href="classuvw_1_1loop.html#a36e1eb17d55ab7b8d089e55823015618">resource</a>&lt;<a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a>&gt;();</div>
<div class="line"> </div>
<div class="line"> tcp-&gt;<a class="code hl_function" href="classuvw_1_1emitter.html#ab913fa1c005a33c73b2eb2b0d1051b1f">on</a>&lt;<a class="code hl_struct" href="structuvw_1_1listen__event.html">uvw::listen_event</a>&gt;([](<span class="keyword">const</span> <a class="code hl_struct" href="structuvw_1_1listen__event.html">uvw::listen_event</a> &amp;, <a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a> &amp;srv) {</div>
<div class="line"> std::shared_ptr&lt;uvw::tcp_handle&gt; client = srv.parent().resource&lt;<a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a>&gt;();</div>
<div class="line"> </div>
<div class="line"> client-&gt;<a class="code hl_function" href="classuvw_1_1emitter.html#ab913fa1c005a33c73b2eb2b0d1051b1f">on</a>&lt;<a class="code hl_struct" href="structuvw_1_1close__event.html">uvw::close_event</a>&gt;([ptr = srv.shared_from_this()](<span class="keyword">const</span> <a class="code hl_struct" href="structuvw_1_1close__event.html">uvw::close_event</a> &amp;, <a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a> &amp;) { ptr-&gt;close(); });</div>
<div class="line"> client-&gt;on&lt;<a class="code hl_struct" href="structuvw_1_1end__event.html">uvw::end_event</a>&gt;([](<span class="keyword">const</span> <a class="code hl_struct" href="structuvw_1_1end__event.html">uvw::end_event</a> &amp;, <a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a> &amp;client) { client.close(); });</div>
<div class="line"> </div>
<div class="line"> srv.accept(*client);</div>
<div class="line"> client-&gt;read();</div>
<div class="line"> });</div>
<div class="line"> </div>
<div class="line"> tcp-&gt;bind(<span class="stringliteral">&quot;127.0.0.1&quot;</span>, 4242);</div>
<div class="line"> tcp-&gt;listen();</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> conn(<a class="code hl_class" href="classuvw_1_1loop.html">uvw::loop</a> &amp;loop) {</div>
<div class="line"> <span class="keyword">auto</span> tcp = loop.<a class="code hl_function" href="classuvw_1_1loop.html#a36e1eb17d55ab7b8d089e55823015618">resource</a>&lt;<a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a>&gt;();</div>
<div class="line"> </div>
<div class="line"> tcp-&gt;<a class="code hl_function" href="classuvw_1_1emitter.html#ab913fa1c005a33c73b2eb2b0d1051b1f">on</a>&lt;<a class="code hl_struct" href="structuvw_1_1error__event.html">uvw::error_event</a>&gt;([](<span class="keyword">const</span> <a class="code hl_struct" href="structuvw_1_1error__event.html">uvw::error_event</a> &amp;, <a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a> &amp;) { <span class="comment">/* handle errors */</span> });</div>
<div class="line"> </div>
<div class="line"> tcp-&gt;on&lt;<a class="code hl_struct" href="structuvw_1_1connect__event.html">uvw::connect_event</a>&gt;([](<span class="keyword">const</span> <a class="code hl_struct" href="structuvw_1_1connect__event.html">uvw::connect_event</a> &amp;, <a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a> &amp;tcp) {</div>
<div class="line"> <span class="keyword">auto</span> dataWrite = std::unique_ptr&lt;char[]&gt;(<span class="keyword">new</span> <span class="keywordtype">char</span>[2]{ <span class="charliteral">&#39;b&#39;</span>, <span class="charliteral">&#39;c&#39;</span> });</div>
<div class="line"> tcp.write(std::move(dataWrite), 2);</div>
<div class="line"> tcp.close();</div>
<div class="line"> });</div>
<div class="line"> </div>
<div class="line"> tcp-&gt;connect(std::string{<span class="stringliteral">&quot;127.0.0.1&quot;</span>}, 4242);</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main() {</div>
<div class="line"> <span class="keyword">auto</span> loop = <a class="code hl_function" href="classuvw_1_1loop.html#a6392ce48b55f9b5644eeec2d6ce0e6d4">uvw::loop::get_default</a>();</div>
<div class="line"> listen(*loop);</div>
<div class="line"> conn(*loop);</div>
<div class="line"> loop-&gt;<a class="code hl_function" href="classuvw_1_1loop.html#a199e23bce642f5618e3d0c2b1e8d0cdf">run</a>();</div>
<div class="line">}</div>
<div class="ttc" id="aclassuvw_1_1emitter_html_ab913fa1c005a33c73b2eb2b0d1051b1f"><div class="ttname"><a href="classuvw_1_1emitter.html#ab913fa1c005a33c73b2eb2b0d1051b1f">uvw::emitter::on</a></div><div class="ttdeci">void on(listener_t&lt; U &gt; f)</div><div class="ttdoc">Registers a long-lived listener with the event emitter.</div><div class="ttdef"><b>Definition:</b> <a href="emitter_8h_source.html#l00123">emitter.h:123</a></div></div>
<div class="ttc" id="aclassuvw_1_1loop_html"><div class="ttname"><a href="classuvw_1_1loop.html">uvw::loop</a></div><div class="ttdoc">The loop class.</div><div class="ttdef"><b>Definition:</b> <a href="loop_8h_source.html#l00060">loop.h:60</a></div></div>
<div class="ttc" id="aclassuvw_1_1loop_html_a199e23bce642f5618e3d0c2b1e8d0cdf"><div class="ttname"><a href="classuvw_1_1loop.html#a199e23bce642f5618e3d0c2b1e8d0cdf">uvw::loop::run</a></div><div class="ttdeci">int run(run_mode mode=run_mode::DEFAULT) noexcept</div><div class="ttdoc">Runs the event loop.</div></div>
<div class="ttc" id="aclassuvw_1_1loop_html_a36e1eb17d55ab7b8d089e55823015618"><div class="ttname"><a href="classuvw_1_1loop.html#a36e1eb17d55ab7b8d089e55823015618">uvw::loop::resource</a></div><div class="ttdeci">std::shared_ptr&lt; R &gt; resource(Args &amp;&amp;...args)</div><div class="ttdoc">Creates resources of any type.</div><div class="ttdef"><b>Definition:</b> <a href="loop_8h_source.html#l00154">loop.h:154</a></div></div>
<div class="ttc" id="aclassuvw_1_1loop_html_a6392ce48b55f9b5644eeec2d6ce0e6d4"><div class="ttname"><a href="classuvw_1_1loop.html#a6392ce48b55f9b5644eeec2d6ce0e6d4">uvw::loop::get_default</a></div><div class="ttdeci">static std::shared_ptr&lt; loop &gt; get_default()</div><div class="ttdoc">Gets the initialized default loop.</div></div>
<div class="ttc" id="aclassuvw_1_1tcp__handle_html"><div class="ttname"><a href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a></div><div class="ttdoc">The TCP handle.</div><div class="ttdef"><b>Definition:</b> <a href="tcp_8h_source.html#l00043">tcp.h:43</a></div></div>
<div class="ttc" id="astructuvw_1_1close__event_html"><div class="ttname"><a href="structuvw_1_1close__event.html">uvw::close_event</a></div><div class="ttdoc">Close event.</div><div class="ttdef"><b>Definition:</b> <a href="handle_8hpp_source.html#l00015">handle.hpp:15</a></div></div>
<div class="ttc" id="astructuvw_1_1connect__event_html"><div class="ttname"><a href="structuvw_1_1connect__event.html">uvw::connect_event</a></div><div class="ttdoc">Connect event.</div><div class="ttdef"><b>Definition:</b> <a href="stream_8h_source.html#l00018">stream.h:18</a></div></div>
<div class="ttc" id="astructuvw_1_1end__event_html"><div class="ttname"><a href="structuvw_1_1end__event.html">uvw::end_event</a></div><div class="ttdoc">End event.</div><div class="ttdef"><b>Definition:</b> <a href="stream_8h_source.html#l00021">stream.h:21</a></div></div>
<div class="ttc" id="astructuvw_1_1error__event_html"><div class="ttname"><a href="structuvw_1_1error__event.html">uvw::error_event</a></div><div class="ttdoc">Error event.</div><div class="ttdef"><b>Definition:</b> <a href="emitter_8h_source.html#l00023">emitter.h:23</a></div></div>
<div class="ttc" id="astructuvw_1_1listen__event_html"><div class="ttname"><a href="structuvw_1_1listen__event.html">uvw::listen_event</a></div><div class="ttdoc">Listen event.</div><div class="ttdef"><b>Definition:</b> <a href="stream_8h_source.html#l00024">stream.h:24</a></div></div>
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md2"></a>
Motivation</h2>
<p>The main reason for which <code>uvw</code> has been written is the fact that there does not exist a valid <code>libuv</code> wrapper in C++. That's all.</p>
<h1><a class="anchor" id="autotoc_md3"></a>
Build Instructions</h1>
<h2><a class="anchor" id="autotoc_md4"></a>
Requirements</h2>
<p>To be able to use <code>uvw</code>, users must provide the following system-wide tools:</p>
<ul>
<li>A full-featured compiler that supports at least C++17.</li>
<li><code>libuv</code> (which version depends on the tag of <code>uvw</code> in use).</li>
</ul>
<p>The requirements below are mandatory to compile the tests and to extract the documentation:</p>
<ul>
<li>CMake version 3.13 or later.</li>
<li>Doxygen version 1.8 or later.</li>
</ul>
<p>Note that <code>libuv</code> is part of the dependencies of the project and may be cloned by <code>CMake</code> in some cases (see below for further details).<br />
Because of that, users don't have to install it to run the tests or when <code>uvw</code> libraries are compiled through <code>CMake</code>.</p>
<h2><a class="anchor" id="autotoc_md5"></a>
Library</h2>
<p><code>uvw</code> is a dual-mode library. It can be used in its header-only form or as a compiled static library.<br />
The following sections describe what to do in both cases to get <code>uvw</code> up and runningin your own project.</p>
<h3><a class="anchor" id="autotoc_md6"></a>
Header-only</h3>
<p>To use <code>uvw</code> as a header-only library, all is needed is to include the <code><a class="el" href="uvw_8hpp_source.html">uvw.hpp</a></code> header or one of the other <code>uvw/*.hpp</code> files.<br />
It's a matter of adding the following line at the top of a file:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;uvw.hpp&gt;</span></div>
</div><!-- fragment --><p>Then pass the proper <code>-I</code> argument to the compiler to add the <code>src</code> directory to the include paths.<br />
Note that users are required to correctly setup the include directories and libraries search paths for <code>libuv</code> in this case.</p>
<p>When used through <code>CMake</code>, the <code>uvw::uvw</code> target is exported for convenience.</p>
<h3><a class="anchor" id="autotoc_md7"></a>
Static</h3>
<p>To use <code>uvw</code> as a compiled library, set the <code>BUILD_UVW_LIBS</code> options in cmake before including the project.<br />
This option triggers the generation of a targets named <code>uvw::uvw-static</code>. The matching version of <code>libuv</code> is also compiled and exported as <code>uv::uv-static</code> for convenience.</p>
<p>In case you don't use or don't want to use <code>CMake</code>, you can still compile all <code>.cpp</code> files and include all <code>.h</code> files to get the job done. In this case, users are required to correctly setup the include directories and libraries search paths for <code>libuv</code>.</p>
<h2><a class="anchor" id="autotoc_md8"></a>
Versioning</h2>
<p>Starting with tag <em>v1.12.0</em> of <code>libuv</code>, <code>uvw</code> follows the <a href="http://semver.org/">semantic versioning</a> scheme.<br />
The problem is that any version of <code>uvw</code> also requires to track explicitly the version of <code>libuv</code> to which it is bound.<br />
Because of that, the latter wil be appended to the version of <code>uvw</code>. As an example: </p><pre class="fragment">vU.V.W_libuv-vX.Y
</pre><p> In particular, the following applies:</p>
<ul>
<li><em>U.V.W</em> are major, minor and patch versions of <code>uvw</code>.</li>
<li><em>X.Y</em> is the version of <code>libuv</code> to which to refer (where any patch version is valid).</li>
</ul>
<p>In other terms, tags will look like this from now on: </p><pre class="fragment">v1.0.0_libuv-v1.12
</pre><p> Branch <code>master</code> of <code>uvw</code> will be a work in progress branch that follows branch <em>v1.x</em> of <code>libuv</code> (at least as long as it remains their <em>master</em> branch).<br />
</p>
<h2><a class="anchor" id="autotoc_md9"></a>
Documentation</h2>
<p>The documentation is based on <a href="https://www.doxygen.nl/"><code>doxygen</code></a>. To build it:</p>
<ul>
<li><code>$ cd build</code></li>
<li><code>$ cmake ..</code></li>
<li><code>$ make docs</code></li>
</ul>
<p>The API reference will be created in HTML format within the directory <code>build/docs/html</code>.<br />
To navigate it with your favorite browser:</p>
<ul>
<li><code>$ cd build</code></li>
<li><code>$ your_favorite_browser docs/html/index.html</code></li>
</ul>
<p>The same version is also available <a href="https://skypjack.github.io/uvw/">online</a> for the latest release, that is the last stable tag.</p>
<h3><a class="anchor" id="autotoc_md10"></a>
Note</h3>
<p>The documentation is mostly inspired by the official <a href="http://docs.libuv.org/en/v1.x/">libuv API documentation</a> for obvious reasons.</p>
<h2><a class="anchor" id="autotoc_md11"></a>
Tests</h2>
<p>To compile and run the tests, <code>uvw</code> requires <code>libuv</code> and <code>googletest</code>.<br />
<code>CMake</code> will download and compile both the libraries before compiling anything else.</p>
<p>To build the tests:</p>
<ul>
<li><code>$ cd build</code></li>
<li><code>$ cmake .. -DBUILD_TESTING=ON</code></li>
<li><code>$ make</code></li>
<li><code>$ ctest -j4 -R uvw</code></li>
</ul>
<p>Omit <code>-R uvw</code> if you also want to test <code>libuv</code> and other dependencies.</p>
<h1><a class="anchor" id="autotoc_md12"></a>
Crash Course</h1>
<h2><a class="anchor" id="autotoc_md13"></a>
Vademecum</h2>
<p>There is only one rule when using <code>uvw</code>: always initialize the resources and terminate them.</p>
<p>Resources belong mainly to two families: <em>handles</em> and <em>requests</em>.<br />
Handles represent long-lived objects capable of performing certain operations while active.<br />
Requests represent (typically) short-lived operations performed either over a handle or standalone.</p>
<p>The following sections will explain in short what it means to initialize and terminate these kinds of resources.<br />
For more details, please refer to the <a href="https://skypjack.github.io/uvw/">online documentation</a>.</p>
<h2><a class="anchor" id="autotoc_md14"></a>
Handles</h2>
<p>Initialization is usually performed under the hood and can be even passed over, as far as handles are created using the <code>loop::resource</code> member function.<br />
On the other side, handles keep themselves alive until one explicitly closes them. Because of that, memory usage will grow if users simply forget about a handle.<br />
Therefore the rule quickly becomes <em>always close your handles</em>. It's as simple as calling the <code>close</code> member function on them.</p>
<h2><a class="anchor" id="autotoc_md15"></a>
Requests</h2>
<p>Usually initializing a request object is not required. Anyway, the recommended way to create a request is still through the <code>loop::resource</code> member function.<br />
Requests will keep themselves alive as long as they are bound to unfinished underlying activities. This means that users don't have to discard a request explicitly .<br />
Therefore the rule quickly becomes <em>feel free to make a request and forget about it</em>. It's as simple as calling a member function on them.</p>
<h2><a class="anchor" id="autotoc_md16"></a>
The Loop and the Resource</h2>
<p>The first thing to do to use <code>uvw</code> is to create a loop. In case the default one is enough, it's easy as doing this:</p>
<div class="fragment"><div class="line"><span class="keyword">auto</span> loop = <a class="code hl_function" href="classuvw_1_1loop.html#a6392ce48b55f9b5644eeec2d6ce0e6d4">uvw::loop::get_default</a>();</div>
</div><!-- fragment --><p>Note that loop objects don't require being closed explicitly, even if they offer the <code>close</code> member function in case a user wants to do that.<br />
Loops can be started using the <code>run</code> member function. The two calls below are equivalent:</p>
<div class="fragment"><div class="line">loop-&gt;<a class="code hl_function" href="classuvw_1_1loop.html#a199e23bce642f5618e3d0c2b1e8d0cdf">run</a>();</div>
<div class="line">loop-&gt;<a class="code hl_function" href="classuvw_1_1loop.html#a199e23bce642f5618e3d0c2b1e8d0cdf">run</a>(uvw::loop::run_mode::DEFAULT);</div>
</div><!-- fragment --><p>Available modes are: <code>DEFAULT</code>, <code>ONCE</code>, <code>NOWAIT</code>. Please refer to the documentation of <code>libuv</code> for further details.</p>
<p>In order to create a resource and to bind it to the given loop, just do the following:</p>
<div class="fragment"><div class="line"><span class="keyword">auto</span> tcp = loop-&gt;<a class="code hl_function" href="classuvw_1_1loop.html#a36e1eb17d55ab7b8d089e55823015618">resource</a>&lt;<a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a>&gt;();</div>
</div><!-- fragment --><p>The line above creates and initializes a tcp handle, then a shared pointer to that resource is returned.<br />
Users should check if pointers have been correctly initialized: in case of errors, they won't be.<br />
It also is possible to create uninitialized resources to init later on as:</p>
<div class="fragment"><div class="line"><span class="keyword">auto</span> tcp = loop-&gt;<a class="code hl_function" href="classuvw_1_1loop.html#aef0dbe4d1e82e43a8df3df1c7386efca">uninitialized_resource</a>&lt;<a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a>&gt;();</div>
<div class="line">tcp-&gt;<a class="code hl_function" href="classuvw_1_1tcp__handle.html#a0cb5490996adb8ae112927a036aee85d">init</a>();</div>
<div class="ttc" id="aclassuvw_1_1loop_html_aef0dbe4d1e82e43a8df3df1c7386efca"><div class="ttname"><a href="classuvw_1_1loop.html#aef0dbe4d1e82e43a8df3df1c7386efca">uvw::loop::uninitialized_resource</a></div><div class="ttdeci">std::shared_ptr&lt; R &gt; uninitialized_resource(Args &amp;&amp;...args)</div><div class="ttdoc">Creates uninitialized resources of any type.</div><div class="ttdef"><b>Definition:</b> <a href="loop_8h_source.html#l00165">loop.h:165</a></div></div>
<div class="ttc" id="aclassuvw_1_1tcp__handle_html_a0cb5490996adb8ae112927a036aee85d"><div class="ttname"><a href="classuvw_1_1tcp__handle.html#a0cb5490996adb8ae112927a036aee85d">uvw::tcp_handle::init</a></div><div class="ttdeci">int init() final</div><div class="ttdoc">Initializes the handle. No socket is created as of yet.</div></div>
</div><!-- fragment --><p>All resources also accept arbitrary user-data that won't be touched in any case.<br />
Users can set and get them through the <code>data</code> member function as it follows:</p>
<div class="fragment"><div class="line">resource-&gt;data(std::make_shared&lt;int&gt;(42));</div>
<div class="line">std::shared_ptr&lt;void&gt; data = resource-&gt;data();</div>
</div><!-- fragment --><p>Resources expect a <code>std::shared_pointer&lt;void&gt;</code> and return it, therefore any kind of data is welcome.<br />
Users can explicitly specify a type other than <code>void</code> when calling the <code>data</code> member function:</p>
<div class="fragment"><div class="line">std::shared_ptr&lt;int&gt; data = resource-&gt;data&lt;<span class="keywordtype">int</span>&gt;();</div>
</div><!-- fragment --><p>Remember from the previous section that a handle will keep itself alive until one invokes the <code>close</code> member function on it.<br />
To know what are the handles that are still alive and bound to a given loop, there exists the <code>walk</code> member function. It returns handles with their types. Therefore, the use of <code>overloaded</code> is recommended to be able to intercept all types of interest:</p>
<div class="fragment"><div class="line">handle.parent().walk(<a class="code hl_struct" href="structuvw_1_1overloaded.html">uvw::overloaded</a>{</div>
<div class="line"> [](<a class="code hl_class" href="classuvw_1_1timer__handle.html">uvw::timer_handle</a> &amp;h){ <span class="comment">/* application code for timers here */</span> },</div>
<div class="line"> [](<span class="keyword">auto</span> &amp;&amp;){ <span class="comment">/* ignore all other types */</span> }</div>
<div class="line">});</div>
<div class="ttc" id="aclassuvw_1_1timer__handle_html"><div class="ttname"><a href="classuvw_1_1timer__handle.html">uvw::timer_handle</a></div><div class="ttdoc">The timer handle.</div><div class="ttdef"><b>Definition:</b> <a href="timer_8h_source.html#l00022">timer.h:22</a></div></div>
<div class="ttc" id="astructuvw_1_1overloaded_html"><div class="ttname"><a href="structuvw_1_1overloaded.html">uvw::overloaded</a></div><div class="ttdoc">Helper type for visitors.</div><div class="ttdef"><b>Definition:</b> <a href="util_8h_source.html#l00683">util.h:683</a></div></div>
</div><!-- fragment --><p>This function can also be used for a completely generic approach. For example, all the pending handles can be closed easily as it follows:</p>
<div class="fragment"><div class="line">loop-&gt;<a class="code hl_function" href="classuvw_1_1loop.html#aa46a050e186935c0be4eca7815cd9207">walk</a>([](<span class="keyword">auto</span> &amp;&amp;h){ h.close(); });</div>
<div class="ttc" id="aclassuvw_1_1loop_html_aa46a050e186935c0be4eca7815cd9207"><div class="ttname"><a href="classuvw_1_1loop.html#aa46a050e186935c0be4eca7815cd9207">uvw::loop::walk</a></div><div class="ttdeci">void walk(Func callback)</div><div class="ttdoc">Walks the list of handles.</div><div class="ttdef"><b>Definition:</b> <a href="loop_8h_source.html#l00280">loop.h:280</a></div></div>
</div><!-- fragment --><p>No need to keep track of them.</p>
<h2><a class="anchor" id="autotoc_md17"></a>
The event-based approach</h2>
<p><code>uvw</code> offers an event-based approach where resources are small event emitters to which listeners are attached.<br />
Attaching listeners to resources is the recommended way to receive notifications about their operations.<br />
Listeners are callable objects of type <code>void(event_type &amp;, resource_type &amp;)</code>, where:</p>
<ul>
<li><code>event_type</code> is the type of the event for which they have been designed.</li>
<li><code>resource_type</code> is the type of the resource that has originated the event.</li>
</ul>
<p>It means that the following function types are all valid:</p>
<ul>
<li><code>void(event_type &amp;, resource_type &amp;)</code></li>
<li><code>void(const event_type &amp;, resource_type &amp;)</code></li>
<li><code>void(event_type &amp;, const resource_type &amp;)</code></li>
<li><code>void(const event_type &amp;, const resource_type &amp;)</code></li>
</ul>
<p>Please note that there is no need to keep around references to the resources, since they pass themselves as an argument whenever an event is published.<br />
The <code>on</code> member function is the way to go to register long-running listeners:</p>
<div class="fragment"><div class="line">resource.on&lt;event_type&gt;(listener)</div>
</div><!-- fragment --><p>To know if a listener exists for a given type, the class offers a <code>has</code> function template. Similarly, the <code>reset</code> function template is be used to reset and thus disconnect listeners, if any. A non-template version of <code>reset</code> also exists to clear an emitter as a whole.</p>
<p>Almost all the resources emit <code>error_event</code> in case of errors.<br />
All the other events are specific for the given resource and documented in the API reference.</p>
<p>The code below shows how to create a simple tcp server using <code>uvw</code>:</p>
<div class="fragment"><div class="line"><span class="keyword">auto</span> loop = <a class="code hl_function" href="classuvw_1_1loop.html#a6392ce48b55f9b5644eeec2d6ce0e6d4">uvw::loop::get_default</a>();</div>
<div class="line"><span class="keyword">auto</span> tcp = loop-&gt;<a class="code hl_function" href="classuvw_1_1loop.html#a36e1eb17d55ab7b8d089e55823015618">resource</a>&lt;<a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a>&gt;();</div>
<div class="line"> </div>
<div class="line">tcp-&gt;<a class="code hl_function" href="classuvw_1_1emitter.html#ab913fa1c005a33c73b2eb2b0d1051b1f">on</a>&lt;<a class="code hl_struct" href="structuvw_1_1error__event.html">uvw::error_event</a>&gt;([](<span class="keyword">const</span> <a class="code hl_struct" href="structuvw_1_1error__event.html">uvw::error_event</a> &amp;, <a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a> &amp;) { <span class="comment">/* something went wrong */</span> });</div>
<div class="line"> </div>
<div class="line">tcp-&gt;on&lt;<a class="code hl_struct" href="structuvw_1_1listen__event.html">uvw::listen_event</a>&gt;([](<span class="keyword">const</span> <a class="code hl_struct" href="structuvw_1_1listen__event.html">uvw::listen_event</a> &amp;, <a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a> &amp;srv) {</div>
<div class="line"> std::shared_ptr&lt;uvw::tcp_handle&gt; client = srv.parent().resource&lt;<a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a>&gt;();</div>
<div class="line"> client-&gt;<a class="code hl_function" href="classuvw_1_1emitter.html#ab913fa1c005a33c73b2eb2b0d1051b1f">on</a>&lt;<a class="code hl_struct" href="structuvw_1_1end__event.html">uvw::end_event</a>&gt;([](<span class="keyword">const</span> <a class="code hl_struct" href="structuvw_1_1end__event.html">uvw::end_event</a> &amp;, <a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a> &amp;client) { client.close(); });</div>
<div class="line"> client-&gt;on&lt;<a class="code hl_struct" href="structuvw_1_1data__event.html">uvw::data_event</a>&gt;([](<span class="keyword">const</span> <a class="code hl_struct" href="structuvw_1_1data__event.html">uvw::data_event</a> &amp;, <a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a> &amp;) { <span class="comment">/* data received */</span> });</div>
<div class="line"> srv.accept(*client);</div>
<div class="line"> client-&gt;read();</div>
<div class="line">});</div>
<div class="line"> </div>
<div class="line">tcp-&gt;bind(<span class="stringliteral">&quot;127.0.0.1&quot;</span>, 4242);</div>
<div class="line">tcp-&gt;listen();</div>
<div class="ttc" id="astructuvw_1_1data__event_html"><div class="ttname"><a href="structuvw_1_1data__event.html">uvw::data_event</a></div><div class="ttdoc">Data event.</div><div class="ttdef"><b>Definition:</b> <a href="stream_8h_source.html#l00033">stream.h:33</a></div></div>
</div><!-- fragment --><p>Note also that <code><a class="el" href="classuvw_1_1tcp__handle.html" title="The TCP handle.">uvw::tcp_handle</a></code> already supports <em>IPv6</em> out-of-the-box.<br />
The API reference is the recommended documentation for further details about resources and their methods.</p>
<h2><a class="anchor" id="autotoc_md18"></a>
Going raw</h2>
<p>In case users need to use functionalities not wrapped yet by <code>uvw</code> or if they want to get the underlying data structures as defined by <code>libuv</code> for some other reasons, almost all the classes in <code>uvw</code> give direct access to them.<br />
Please, note that this functions should not be used directly unless users know exactly what they are doing and what are the risks. Going raw is dangerous, mainly because the lifetime management of a loop, a handle or a request is completely controlled by the library and working around it could quickly break things.</p>
<p>That being said, <em>going raw</em> is a matter of using the <code>raw</code> member functions:</p>
<div class="fragment"><div class="line"><span class="keyword">auto</span> loop = <a class="code hl_function" href="classuvw_1_1loop.html#a6392ce48b55f9b5644eeec2d6ce0e6d4">uvw::loop::get_default</a>();</div>
<div class="line"><span class="keyword">auto</span> tcp = loop-&gt;<a class="code hl_function" href="classuvw_1_1loop.html#a36e1eb17d55ab7b8d089e55823015618">resource</a>&lt;<a class="code hl_class" href="classuvw_1_1tcp__handle.html">uvw::tcp_handle</a>&gt;();</div>
<div class="line"> </div>
<div class="line">uv_loop_t *raw = loop-&gt;<a class="code hl_function" href="classuvw_1_1loop.html#a4e1f127cadc84b1729bc7835b697d3bf">raw</a>();</div>
<div class="line">uv_tcp_t *handle = tcp-&gt;raw();</div>
<div class="ttc" id="aclassuvw_1_1loop_html_a4e1f127cadc84b1729bc7835b697d3bf"><div class="ttname"><a href="classuvw_1_1loop.html#a4e1f127cadc84b1729bc7835b697d3bf">uvw::loop::raw</a></div><div class="ttdeci">const uv_loop_t * raw() const noexcept</div><div class="ttdoc">Gets the underlying raw data structure.</div></div>
</div><!-- fragment --><p>Go the raw way at your own risk, but do not expect any support in case of bugs.</p>
<h1><a class="anchor" id="autotoc_md19"></a>
Contributors</h1>
<p>If you want to contribute, please send patches as pull requests against the branch master.<br />
Check the <a href="https://github.com/skypjack/uvw/blob/master/AUTHORS">contributors list</a> to see who has partecipated so far.</p>
<h1><a class="anchor" id="autotoc_md20"></a>
License</h1>
<p>Code and documentation Copyright (c) 2016-2023 Michele Caini.<br />
Logo Copyright (c) 2018-2021 Richard Caseres.</p>
<p>Code and documentation released under <a href="https://github.com/skypjack/uvw/blob/master/LICENSE">the MIT license</a>.<br />
Logo released under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>. </p>
</div></div><!-- PageDoc -->
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.6
</small></address>
</body>
</html>