75 lines
44 KiB
HTML
75 lines
44 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://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.13"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
<title>uvw: README.md Source File</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">uvw
|
|
 <span id="projectnumber">1.4.0</span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<!-- end header part -->
|
|
<!-- Generated by Doxygen 1.8.13 -->
|
|
<script type="text/javascript">
|
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
|
</script>
|
|
<script type="text/javascript" src="menudata.js"></script>
|
|
<script type="text/javascript" src="menu.js"></script>
|
|
<script type="text/javascript">
|
|
$(function() {
|
|
initMenu('',true,false,'search.php','Search');
|
|
$(document).ready(function() { init_search(); });
|
|
});
|
|
</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">
|
|
<iframe src="javascript:void(0)" frameborder="0"
|
|
name="MSearchResults" id="MSearchResults">
|
|
</iframe>
|
|
</div>
|
|
|
|
<div class="header">
|
|
<div class="headertitle">
|
|
<div class="title">README.md</div> </div>
|
|
</div><!--header-->
|
|
<div class="contents">
|
|
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>  **Sponsored and contributed by [Cynny SpA](https://www.cynny.com/).**</div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span> </div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span> # uvw - libuv wrapper in modern C++</div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span> </div><div class="line"><a name="l00005"></a><span class="lineno"> 5</span> [](https://travis-ci.org/skypjack/uvw)</div><div class="line"><a name="l00006"></a><span class="lineno"> 6</span> [](https://ci.appveyor.com/project/skypjack/uvw)</div><div class="line"><a name="l00007"></a><span class="lineno"> 7</span> [](https://coveralls.io/github/skypjack/uvw?branch=master)</div><div class="line"><a name="l00008"></a><span class="lineno"> 8</span> [](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=W2HF9FESD5LJY&lc=IT&item_name=Michele%20Caini&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted)</div><div class="line"><a name="l00009"></a><span class="lineno"> 9</span> </div><div class="line"><a name="l00010"></a><span class="lineno"> 10</span> # Introduction</div><div class="line"><a name="l00011"></a><span class="lineno"> 11</span> </div><div class="line"><a name="l00012"></a><span class="lineno"> 12</span> `uvw` is a header-only, event based, tiny and easy to use *libuv* wrapper in modern C++.<br/></div><div class="line"><a name="l00013"></a><span class="lineno"> 13</span> The basic idea is to hide completely the *C-ish* interface of *libuv* behind a graceful C++ API. Currently, no `uv_*_t` data structure is actually exposed by the library.<br/></div><div class="line"><a name="l00014"></a><span class="lineno"> 14</span> Note that `uvw` stays true to the API of *libuv* and it doesn't add anything to its interface. For the same reasons, users of the library must follow the same rules who are used to follow with *libuv*.<br/></div><div class="line"><a name="l00015"></a><span class="lineno"> 15</span> As an example, a *handle* should be initialized before any other operation and closed once it is no longer in use.</div><div class="line"><a name="l00016"></a><span class="lineno"> 16</span> </div><div class="line"><a name="l00017"></a><span class="lineno"> 17</span> ## Code Example</div><div class="line"><a name="l00018"></a><span class="lineno"> 18</span> </div><div class="line"><a name="l00019"></a><span class="lineno"> 19</span> ```cpp</div><div class="line"><a name="l00020"></a><span class="lineno"> 20</span> #include <uvw.hpp></div><div class="line"><a name="l00021"></a><span class="lineno"> 21</span> #include <memory></div><div class="line"><a name="l00022"></a><span class="lineno"> 22</span> </div><div class="line"><a name="l00023"></a><span class="lineno"> 23</span> void listen(uvw::Loop &loop) {</div><div class="line"><a name="l00024"></a><span class="lineno"> 24</span>  std::shared_ptr<uvw::TcpHandle> tcp = loop.resource<uvw::TcpHandle>();</div><div class="line"><a name="l00025"></a><span class="lineno"> 25</span> </div><div class="line"><a name="l00026"></a><span class="lineno"> 26</span>  tcp->once<uvw::ListenEvent>([](const uvw::ListenEvent &, uvw::TcpHandle &srv) {</div><div class="line"><a name="l00027"></a><span class="lineno"> 27</span>  std::shared_ptr<uvw::TcpHandle> client = srv.loop().resource<uvw::TcpHandle>();</div><div class="line"><a name="l00028"></a><span class="lineno"> 28</span> </div><div class="line"><a name="l00029"></a><span class="lineno"> 29</span>  client->on<uvw::CloseEvent>([ptr = srv.shared_from_this()](const uvw::CloseEvent &, uvw::TcpHandle &) { ptr->close(); });</div><div class="line"><a name="l00030"></a><span class="lineno"> 30</span>  client->on<uvw::EndEvent>([](const uvw::EndEvent &, uvw::TcpHandle &client) { client.close(); });</div><div class="line"><a name="l00031"></a><span class="lineno"> 31</span> </div><div class="line"><a name="l00032"></a><span class="lineno"> 32</span>  srv.accept(*client);</div><div class="line"><a name="l00033"></a><span class="lineno"> 33</span>  client->read();</div><div class="line"><a name="l00034"></a><span class="lineno"> 34</span>  });</div><div class="line"><a name="l00035"></a><span class="lineno"> 35</span> </div><div class="line"><a name="l00036"></a><span class="lineno"> 36</span>  tcp->bind("127.0.0.1", 4242);</div><div class="line"><a name="l00037"></a><span class="lineno"> 37</span>  tcp->listen();</div><div class="line"><a name="l00038"></a><span class="lineno"> 38</span> }</div><div class="line"><a name="l00039"></a><span class="lineno"> 39</span> </div><div class="line"><a name="l00040"></a><span class="lineno"> 40</span> void conn(uvw::Loop &loop) {</div><div class="line"><a name="l00041"></a><span class="lineno"> 41</span>  auto tcp = loop.resource<uvw::TcpHandle>();</div><div class="line"><a name="l00042"></a><span class="lineno"> 42</span> </div><div class="line"><a name="l00043"></a><span class="lineno"> 43</span>  tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TcpHandle &) { /* handle errors */ });</div><div class="line"><a name="l00044"></a><span class="lineno"> 44</span> </div><div class="line"><a name="l00045"></a><span class="lineno"> 45</span>  tcp->once<uvw::ConnectEvent>([](const uvw::ConnectEvent &, uvw::TcpHandle &tcp) {</div><div class="line"><a name="l00046"></a><span class="lineno"> 46</span>  auto dataWrite = std::unique_ptr<char[]>(new char[2]{ 'b', 'c' });</div><div class="line"><a name="l00047"></a><span class="lineno"> 47</span>  tcp.write(std::move(dataWrite), 2);</div><div class="line"><a name="l00048"></a><span class="lineno"> 48</span>  tcp.close();</div><div class="line"><a name="l00049"></a><span class="lineno"> 49</span>  });</div><div class="line"><a name="l00050"></a><span class="lineno"> 50</span> </div><div class="line"><a name="l00051"></a><span class="lineno"> 51</span>  tcp->connect(std::string{"127.0.0.1"}, 4242);</div><div class="line"><a name="l00052"></a><span class="lineno"> 52</span> }</div><div class="line"><a name="l00053"></a><span class="lineno"> 53</span> </div><div class="line"><a name="l00054"></a><span class="lineno"> 54</span> int main() {</div><div class="line"><a name="l00055"></a><span class="lineno"> 55</span>  auto loop = uvw::Loop::getDefault();</div><div class="line"><a name="l00056"></a><span class="lineno"> 56</span>  listen(*loop);</div><div class="line"><a name="l00057"></a><span class="lineno"> 57</span>  conn(*loop);</div><div class="line"><a name="l00058"></a><span class="lineno"> 58</span>  loop->run();</div><div class="line"><a name="l00059"></a><span class="lineno"> 59</span> }</div><div class="line"><a name="l00060"></a><span class="lineno"> 60</span> ```</div><div class="line"><a name="l00061"></a><span class="lineno"> 61</span> </div><div class="line"><a name="l00062"></a><span class="lineno"> 62</span> ## Motivation</div><div class="line"><a name="l00063"></a><span class="lineno"> 63</span> </div><div class="line"><a name="l00064"></a><span class="lineno"> 64</span> The main reason for which `uvw` has been written is the fact that it does not exist a valid *libuv* wrapper in C++. That's all.</div><div class="line"><a name="l00065"></a><span class="lineno"> 65</span> </div><div class="line"><a name="l00066"></a><span class="lineno"> 66</span> # Build Instructions</div><div class="line"><a name="l00067"></a><span class="lineno"> 67</span> </div><div class="line"><a name="l00068"></a><span class="lineno"> 68</span> ## Requirements</div><div class="line"><a name="l00069"></a><span class="lineno"> 69</span> </div><div class="line"><a name="l00070"></a><span class="lineno"> 70</span> To be able to use `uvw`, users must provide the following system-wide tools:</div><div class="line"><a name="l00071"></a><span class="lineno"> 71</span> </div><div class="line"><a name="l00072"></a><span class="lineno"> 72</span> * A full-featured compiler that supports at least C++14.</div><div class="line"><a name="l00073"></a><span class="lineno"> 73</span> * `libuv` (which version depends on the tag of `uvw` in use).</div><div class="line"><a name="l00074"></a><span class="lineno"> 74</span> </div><div class="line"><a name="l00075"></a><span class="lineno"> 75</span> The requirements below are mandatory to compile the tests and to extract the documentation:</div><div class="line"><a name="l00076"></a><span class="lineno"> 76</span> </div><div class="line"><a name="l00077"></a><span class="lineno"> 77</span> * CMake version 3.2 or later.</div><div class="line"><a name="l00078"></a><span class="lineno"> 78</span> * Doxygen version 1.8 or later.</div><div class="line"><a name="l00079"></a><span class="lineno"> 79</span> </div><div class="line"><a name="l00080"></a><span class="lineno"> 80</span> Note that `libuv` is part of the dependencies of the project and it will be cloned by `cmake` (see below for further details).<br/></div><div class="line"><a name="l00081"></a><span class="lineno"> 81</span> Because of that, users have not to install it to compile and execute the tests.</div><div class="line"><a name="l00082"></a><span class="lineno"> 82</span> </div><div class="line"><a name="l00083"></a><span class="lineno"> 83</span> ## Library</div><div class="line"><a name="l00084"></a><span class="lineno"> 84</span> </div><div class="line"><a name="l00085"></a><span class="lineno"> 85</span> `uvw` is a header-only library.<br/></div><div class="line"><a name="l00086"></a><span class="lineno"> 86</span> This means that including the `uvw.hpp` header or one of the other `uvw/*.hpp` headers is enough to use it.<br/></div><div class="line"><a name="l00087"></a><span class="lineno"> 87</span> It's a matter of adding the following line at the top of a file:</div><div class="line"><a name="l00088"></a><span class="lineno"> 88</span> </div><div class="line"><a name="l00089"></a><span class="lineno"> 89</span> ```cpp</div><div class="line"><a name="l00090"></a><span class="lineno"> 90</span> #include <uvw.hpp></div><div class="line"><a name="l00091"></a><span class="lineno"> 91</span> ```</div><div class="line"><a name="l00092"></a><span class="lineno"> 92</span> </div><div class="line"><a name="l00093"></a><span class="lineno"> 93</span> Then pass the proper `-I` argument to the compiler to add the `src` directory to the include paths.<br/></div><div class="line"><a name="l00094"></a><span class="lineno"> 94</span> Note that users are demanded to correctly setup include directories and libraries search paths for *libuv*.</div><div class="line"><a name="l00095"></a><span class="lineno"> 95</span> </div><div class="line"><a name="l00096"></a><span class="lineno"> 96</span> ## Versioning</div><div class="line"><a name="l00097"></a><span class="lineno"> 97</span> </div><div class="line"><a name="l00098"></a><span class="lineno"> 98</span> Starting with tag _v1.12.0_ of `libuv`, `uvw` follows the [semantic versioning](http://semver.org/) scheme.<br/></div><div class="line"><a name="l00099"></a><span class="lineno"> 99</span> The problem is that any version of `uvw` also requires to track explicitly the version of `libuv` to which it is bound.<br/></div><div class="line"><a name="l00100"></a><span class="lineno"> 100</span> Because of that, the latter wil be appended to the version of `uvw`. As an example:</div><div class="line"><a name="l00101"></a><span class="lineno"> 101</span> </div><div class="line"><a name="l00102"></a><span class="lineno"> 102</span>  vU.V.W_libuv-vX.Y</div><div class="line"><a name="l00103"></a><span class="lineno"> 103</span> </div><div class="line"><a name="l00104"></a><span class="lineno"> 104</span> In particular, the following applies:</div><div class="line"><a name="l00105"></a><span class="lineno"> 105</span> </div><div class="line"><a name="l00106"></a><span class="lineno"> 106</span> * _U.V.W_ are major, minor and patch versions of `uvw`.</div><div class="line"><a name="l00107"></a><span class="lineno"> 107</span> * _X.Y_ is the version of `libuv` to which to refer (where any patch version is valid).</div><div class="line"><a name="l00108"></a><span class="lineno"> 108</span> </div><div class="line"><a name="l00109"></a><span class="lineno"> 109</span> In other terms, tags will look like this from now on:</div><div class="line"><a name="l00110"></a><span class="lineno"> 110</span> </div><div class="line"><a name="l00111"></a><span class="lineno"> 111</span>  v1.0.0_libuv-v1.12</div><div class="line"><a name="l00112"></a><span class="lineno"> 112</span> </div><div class="line"><a name="l00113"></a><span class="lineno"> 113</span> Branch `master` of `uvw` will be a work in progress branch that follows branch _v1.x_ of `libuv` (at least as long as it remains their _master_ branch).<br/></div><div class="line"><a name="l00114"></a><span class="lineno"> 114</span> </div><div class="line"><a name="l00115"></a><span class="lineno"> 115</span> ## Documentation</div><div class="line"><a name="l00116"></a><span class="lineno"> 116</span> </div><div class="line"><a name="l00117"></a><span class="lineno"> 117</span> The documentation is based on [`doxygen`](http://www.stack.nl/~dimitri/doxygen/). To build it:</div><div class="line"><a name="l00118"></a><span class="lineno"> 118</span> </div><div class="line"><a name="l00119"></a><span class="lineno"> 119</span> * `$ cd build`</div><div class="line"><a name="l00120"></a><span class="lineno"> 120</span> * `$ cmake ..`</div><div class="line"><a name="l00121"></a><span class="lineno"> 121</span> * `$ make docs`</div><div class="line"><a name="l00122"></a><span class="lineno"> 122</span> </div><div class="line"><a name="l00123"></a><span class="lineno"> 123</span> The API reference will be created in HTML format within the directory `build/docs/html`.<br/></div><div class="line"><a name="l00124"></a><span class="lineno"> 124</span> To navigate it with your favorite browser:</div><div class="line"><a name="l00125"></a><span class="lineno"> 125</span> </div><div class="line"><a name="l00126"></a><span class="lineno"> 126</span> * `$ cd build`</div><div class="line"><a name="l00127"></a><span class="lineno"> 127</span> * `$ your_favorite_browser docs/html/index.html`</div><div class="line"><a name="l00128"></a><span class="lineno"> 128</span> </div><div class="line"><a name="l00129"></a><span class="lineno"> 129</span> The API reference is also available [online](https://skypjack.github.io/uvw/) for the latest version.</div><div class="line"><a name="l00130"></a><span class="lineno"> 130</span> </div><div class="line"><a name="l00131"></a><span class="lineno"> 131</span> ### Note</div><div class="line"><a name="l00132"></a><span class="lineno"> 132</span> </div><div class="line"><a name="l00133"></a><span class="lineno"> 133</span> The documentation is mostly inspired by the official [libuv API documentation](http://docs.libuv.org/en/v1.x/) for obvious reasons.<br/></div><div class="line"><a name="l00134"></a><span class="lineno"> 134</span> If you are mainly interested in the way `uvw` imports `libuv` in a `cmake` based project, I suggest you to take a look at [this](https://github.com/skypjack/libuv_cmake) repository instead.</div><div class="line"><a name="l00135"></a><span class="lineno"> 135</span> </div><div class="line"><a name="l00136"></a><span class="lineno"> 136</span> ## Tests</div><div class="line"><a name="l00137"></a><span class="lineno"> 137</span> </div><div class="line"><a name="l00138"></a><span class="lineno"> 138</span> To compile and run the tests, `uvw` requires *libuv* and *googletest*.<br/></div><div class="line"><a name="l00139"></a><span class="lineno"> 139</span> `cmake` will download and compile both the libraries before to compile anything else.</div><div class="line"><a name="l00140"></a><span class="lineno"> 140</span> </div><div class="line"><a name="l00141"></a><span class="lineno"> 141</span> To build the tests:</div><div class="line"><a name="l00142"></a><span class="lineno"> 142</span> </div><div class="line"><a name="l00143"></a><span class="lineno"> 143</span> * `$ cd build`</div><div class="line"><a name="l00144"></a><span class="lineno"> 144</span> * `$ cmake ..`</div><div class="line"><a name="l00145"></a><span class="lineno"> 145</span> * `$ make`</div><div class="line"><a name="l00146"></a><span class="lineno"> 146</span> * `$ make test`</div><div class="line"><a name="l00147"></a><span class="lineno"> 147</span> </div><div class="line"><a name="l00148"></a><span class="lineno"> 148</span> # Crash Course</div><div class="line"><a name="l00149"></a><span class="lineno"> 149</span> </div><div class="line"><a name="l00150"></a><span class="lineno"> 150</span> ## Vademecum</div><div class="line"><a name="l00151"></a><span class="lineno"> 151</span> </div><div class="line"><a name="l00152"></a><span class="lineno"> 152</span> There is only one rule when using `uvw`: always initialize the resources and terminate them.</div><div class="line"><a name="l00153"></a><span class="lineno"> 153</span> </div><div class="line"><a name="l00154"></a><span class="lineno"> 154</span> Resources belong mainly to two families: _handles_ and _requests_.<br/></div><div class="line"><a name="l00155"></a><span class="lineno"> 155</span> Handles represent long-lived objects capable of performing certain operations while active.<br/></div><div class="line"><a name="l00156"></a><span class="lineno"> 156</span> Requests represent (typically) short-lived operations performed either over a handle or standalone.</div><div class="line"><a name="l00157"></a><span class="lineno"> 157</span> </div><div class="line"><a name="l00158"></a><span class="lineno"> 158</span> The following sections will explain in short what it means to initialize and terminate these kinds of resources.<br/></div><div class="line"><a name="l00159"></a><span class="lineno"> 159</span> For more details, please refer to the [online documentation](https://skypjack.github.io/uvw/).</div><div class="line"><a name="l00160"></a><span class="lineno"> 160</span> </div><div class="line"><a name="l00161"></a><span class="lineno"> 161</span> ## Handles</div><div class="line"><a name="l00162"></a><span class="lineno"> 162</span> </div><div class="line"><a name="l00163"></a><span class="lineno"> 163</span> Initialization is usually performed under the hood and can be even passed over, as far as handles are created using the `Loop::resource` member function.<br/></div><div class="line"><a name="l00164"></a><span class="lineno"> 164</span> On the other side, handles keep themselves alive until one explicitly closes them. Because of that, memory usage will grow up if users simply forget about a handle.<br/></div><div class="line"><a name="l00165"></a><span class="lineno"> 165</span> Therefore the rule quickly becomes *always close your handles*. It's as simple as calling the `close` member function on them.</div><div class="line"><a name="l00166"></a><span class="lineno"> 166</span> </div><div class="line"><a name="l00167"></a><span class="lineno"> 167</span> ## Requests</div><div class="line"><a name="l00168"></a><span class="lineno"> 168</span> </div><div class="line"><a name="l00169"></a><span class="lineno"> 169</span> Usually initializing a request object is not required. Anyway, the recommended way to create a request is still through the `Loop::resource` member function.<br/></div><div class="line"><a name="l00170"></a><span class="lineno"> 170</span> Requests will keep themselves alive as long as they are bound to unfinished underlying activities. This means that users have not to discard explicitly a request.<br/></div><div class="line"><a name="l00171"></a><span class="lineno"> 171</span> Therefore the rule quickly becomes *feel free to make a request and forget about it*. It's as simple as calling a member function on them.</div><div class="line"><a name="l00172"></a><span class="lineno"> 172</span> </div><div class="line"><a name="l00173"></a><span class="lineno"> 173</span> ## The Loop and the Resource</div><div class="line"><a name="l00174"></a><span class="lineno"> 174</span> </div><div class="line"><a name="l00175"></a><span class="lineno"> 175</span> The first thing to do to use `uvw` is to create a loop. In case the default one is enough, it's easy as doing this:</div><div class="line"><a name="l00176"></a><span class="lineno"> 176</span> </div><div class="line"><a name="l00177"></a><span class="lineno"> 177</span> ```cpp</div><div class="line"><a name="l00178"></a><span class="lineno"> 178</span> auto loop = uvw::Loop::getDefault();</div><div class="line"><a name="l00179"></a><span class="lineno"> 179</span> ```</div><div class="line"><a name="l00180"></a><span class="lineno"> 180</span> </div><div class="line"><a name="l00181"></a><span class="lineno"> 181</span> Note that loop objects don't require to be closed explicitly, even if they offer the `close` member function in case an user wants to do that.<br/></div><div class="line"><a name="l00182"></a><span class="lineno"> 182</span> Loops can be started using the `run` member function. The two calls below are equivalent:</div><div class="line"><a name="l00183"></a><span class="lineno"> 183</span> </div><div class="line"><a name="l00184"></a><span class="lineno"> 184</span> ```cpp</div><div class="line"><a name="l00185"></a><span class="lineno"> 185</span> loop->run();</div><div class="line"><a name="l00186"></a><span class="lineno"> 186</span> loop->run<uvw::Loop::Mode::DEFAULT></div><div class="line"><a name="l00187"></a><span class="lineno"> 187</span> ```</div><div class="line"><a name="l00188"></a><span class="lineno"> 188</span> </div><div class="line"><a name="l00189"></a><span class="lineno"> 189</span> Available modes are: `DEFAULT`, `ONCE`, `NOWAIT`. Please refer to the documentation of *libuv* for further details.</div><div class="line"><a name="l00190"></a><span class="lineno"> 190</span> </div><div class="line"><a name="l00191"></a><span class="lineno"> 191</span> In order to create a resource and to bind it to the given loop, just do the following:</div><div class="line"><a name="l00192"></a><span class="lineno"> 192</span> </div><div class="line"><a name="l00193"></a><span class="lineno"> 193</span> ```cpp</div><div class="line"><a name="l00194"></a><span class="lineno"> 194</span> auto tcp = loop.resource<uvw::TcpHandle>();</div><div class="line"><a name="l00195"></a><span class="lineno"> 195</span> ```</div><div class="line"><a name="l00196"></a><span class="lineno"> 196</span> </div><div class="line"><a name="l00197"></a><span class="lineno"> 197</span> The line above will create and initialize a tcp handle, then a shared pointer to that resource will be returned.<br/></div><div class="line"><a name="l00198"></a><span class="lineno"> 198</span> Users should check if pointers have been correctly initialized: in case of errors, they won't be.<br/></div><div class="line"><a name="l00199"></a><span class="lineno"> 199</span> Another way to create a resource is:</div><div class="line"><a name="l00200"></a><span class="lineno"> 200</span> </div><div class="line"><a name="l00201"></a><span class="lineno"> 201</span> ```cpp</div><div class="line"><a name="l00202"></a><span class="lineno"> 202</span> auto tcp = TcpHandle::create(loop);</div><div class="line"><a name="l00203"></a><span class="lineno"> 203</span> tcp->init();</div><div class="line"><a name="l00204"></a><span class="lineno"> 204</span> ```</div><div class="line"><a name="l00205"></a><span class="lineno"> 205</span> </div><div class="line"><a name="l00206"></a><span class="lineno"> 206</span> Pretty annoying indeed. Using a loop is the recommended approach.</div><div class="line"><a name="l00207"></a><span class="lineno"> 207</span> </div><div class="line"><a name="l00208"></a><span class="lineno"> 208</span> The resources also accept arbitrary user-data that won't be touched in any case.<br/></div><div class="line"><a name="l00209"></a><span class="lineno"> 209</span> Users can set and get them through the `data` member function as it follows:</div><div class="line"><a name="l00210"></a><span class="lineno"> 210</span> </div><div class="line"><a name="l00211"></a><span class="lineno"> 211</span> ```cpp</div><div class="line"><a name="l00212"></a><span class="lineno"> 212</span> resource->data(std::make_shared<int>(42));</div><div class="line"><a name="l00213"></a><span class="lineno"> 213</span> std::shared_ptr<void> data = resource->data();</div><div class="line"><a name="l00214"></a><span class="lineno"> 214</span> ```</div><div class="line"><a name="l00215"></a><span class="lineno"> 215</span> </div><div class="line"><a name="l00216"></a><span class="lineno"> 216</span> Resources expect a `std::shared_pointer<void>` and return it, therefore any kind of data is welcome.<br/></div><div class="line"><a name="l00217"></a><span class="lineno"> 217</span> Users can explicitly specify a type other than `void` when calling the `data` member function:</div><div class="line"><a name="l00218"></a><span class="lineno"> 218</span> </div><div class="line"><a name="l00219"></a><span class="lineno"> 219</span> ```cpp</div><div class="line"><a name="l00220"></a><span class="lineno"> 220</span> std::shared_ptr<int> data = resource->data<int>();</div><div class="line"><a name="l00221"></a><span class="lineno"> 221</span> ```</div><div class="line"><a name="l00222"></a><span class="lineno"> 222</span> </div><div class="line"><a name="l00223"></a><span class="lineno"> 223</span> Remember from the previous section that a handle will keep itself alive until one invokes the `close` member function on it.<br/></div><div class="line"><a name="l00224"></a><span class="lineno"> 224</span> To know what are the handles that are still alive and bound to a given loop, just do the following:</div><div class="line"><a name="l00225"></a><span class="lineno"> 225</span> </div><div class="line"><a name="l00226"></a><span class="lineno"> 226</span> ```cpp</div><div class="line"><a name="l00227"></a><span class="lineno"> 227</span> loop.walk([](uvw::BaseHandle &){ /* application code here */ });</div><div class="line"><a name="l00228"></a><span class="lineno"> 228</span> ```</div><div class="line"><a name="l00229"></a><span class="lineno"> 229</span> </div><div class="line"><a name="l00230"></a><span class="lineno"> 230</span> `BaseHandle` exposes a few methods and cannot be promoted to the original type of the handle (even though `type` and `category` member functions fill the gap somehow).<br/></div><div class="line"><a name="l00231"></a><span class="lineno"> 231</span> Anyway, it can be used to close the handle that originated from it. As an example, all the pending handles can be closed easily as it follows:</div><div class="line"><a name="l00232"></a><span class="lineno"> 232</span> </div><div class="line"><a name="l00233"></a><span class="lineno"> 233</span> ```cpp</div><div class="line"><a name="l00234"></a><span class="lineno"> 234</span> loop.walk([](uvw::BaseHandle &h){ h.close(); });</div><div class="line"><a name="l00235"></a><span class="lineno"> 235</span> ```</div><div class="line"><a name="l00236"></a><span class="lineno"> 236</span> </div><div class="line"><a name="l00237"></a><span class="lineno"> 237</span> No need to keep track of them.</div><div class="line"><a name="l00238"></a><span class="lineno"> 238</span> </div><div class="line"><a name="l00239"></a><span class="lineno"> 239</span> To know what are the available resources' types, please refer the API reference.</div><div class="line"><a name="l00240"></a><span class="lineno"> 240</span> </div><div class="line"><a name="l00241"></a><span class="lineno"> 241</span> ## The event-based approach</div><div class="line"><a name="l00242"></a><span class="lineno"> 242</span> </div><div class="line"><a name="l00243"></a><span class="lineno"> 243</span> For `uvw` offers an event-based approach, resources are small event emitters to which listeners can be attached.<br/></div><div class="line"><a name="l00244"></a><span class="lineno"> 244</span> Attaching a listener to a resource is the recommended way to be notified about changes.<br/></div><div class="line"><a name="l00245"></a><span class="lineno"> 245</span> Listeners must be callable objects of type `void(EventType &, ResourceType &)`, where:</div><div class="line"><a name="l00246"></a><span class="lineno"> 246</span> </div><div class="line"><a name="l00247"></a><span class="lineno"> 247</span> * `EventType` is the type of the event for which they have been designed.</div><div class="line"><a name="l00248"></a><span class="lineno"> 248</span> * `ResourceType` is the type of the resource that has originated the event.</div><div class="line"><a name="l00249"></a><span class="lineno"> 249</span> </div><div class="line"><a name="l00250"></a><span class="lineno"> 250</span> It means that the following function types are all valid:</div><div class="line"><a name="l00251"></a><span class="lineno"> 251</span> </div><div class="line"><a name="l00252"></a><span class="lineno"> 252</span> * `void(EventType &, ResourceType &)`</div><div class="line"><a name="l00253"></a><span class="lineno"> 253</span> * `void(const EventType &, ResourceType &)`</div><div class="line"><a name="l00254"></a><span class="lineno"> 254</span> * `void(EventType &, const ResourceType &)`</div><div class="line"><a name="l00255"></a><span class="lineno"> 255</span> * `void(const EventType &, const ResourceType &)`</div><div class="line"><a name="l00256"></a><span class="lineno"> 256</span> </div><div class="line"><a name="l00257"></a><span class="lineno"> 257</span> Once more, please note that there is no need to keep around references to the resources: they will pass themselves as an argument whenever an event is published.</div><div class="line"><a name="l00258"></a><span class="lineno"> 258</span> </div><div class="line"><a name="l00259"></a><span class="lineno"> 259</span> There exist two methods to attach an event to a resource:</div><div class="line"><a name="l00260"></a><span class="lineno"> 260</span> </div><div class="line"><a name="l00261"></a><span class="lineno"> 261</span> * `resource.once<EventType>(listener)`: the listener will be automatically removed after the first event of the given type.</div><div class="line"><a name="l00262"></a><span class="lineno"> 262</span> * `resource.on<EventType>(listener)`: to be used for long-running listeners.</div><div class="line"><a name="l00263"></a><span class="lineno"> 263</span> </div><div class="line"><a name="l00264"></a><span class="lineno"> 264</span> Both of them return an object of type `ResourceType::Connection` (as an example, `TcpHandle::Connection`).<br/></div><div class="line"><a name="l00265"></a><span class="lineno"> 265</span> A connection object can be used later as an argument to the `erase` member function of the resource to remove the listener.<br/></div><div class="line"><a name="l00266"></a><span class="lineno"> 266</span> There exists also the `clear` member function to drop all the listeners at once.</div><div class="line"><a name="l00267"></a><span class="lineno"> 267</span> </div><div class="line"><a name="l00268"></a><span class="lineno"> 268</span> Almost all the resources use to emit `ErrorEvent` events in case of errors.<br/></div><div class="line"><a name="l00269"></a><span class="lineno"> 269</span> All the other events are specific for the given resource and documented in the API reference.</div><div class="line"><a name="l00270"></a><span class="lineno"> 270</span> </div><div class="line"><a name="l00271"></a><span class="lineno"> 271</span> The code below shows how to create a simple tcp server using `uvw`:</div><div class="line"><a name="l00272"></a><span class="lineno"> 272</span> </div><div class="line"><a name="l00273"></a><span class="lineno"> 273</span> ```cpp</div><div class="line"><a name="l00274"></a><span class="lineno"> 274</span> auto loop = uvw::Loop::getDefault();</div><div class="line"><a name="l00275"></a><span class="lineno"> 275</span> auto tcp = loop.resource<uvw::TcpHandle>();</div><div class="line"><a name="l00276"></a><span class="lineno"> 276</span> </div><div class="line"><a name="l00277"></a><span class="lineno"> 277</span> tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TcpHandle &) { /* something went wrong */ });</div><div class="line"><a name="l00278"></a><span class="lineno"> 278</span> </div><div class="line"><a name="l00279"></a><span class="lineno"> 279</span> tcp->on<uvw::ListenEvent>([](const uvw::ListenEvent &, uvw::TcpHandle &srv) {</div><div class="line"><a name="l00280"></a><span class="lineno"> 280</span>  std::shared_ptr<uvw::TcpHandle> client = srv.loop().resource<uvw::TcpHandle>();</div><div class="line"><a name="l00281"></a><span class="lineno"> 281</span>  client->once<uvw::EndEvent>([](const uvw::EndEvent &, uvw::TcpHandle &client) { client.close(); });</div><div class="line"><a name="l00282"></a><span class="lineno"> 282</span>  client->on<uvw::DataEvent>([](const uvw::DataEvent &, uvw::TcpHandle &) { /* data received */ });</div><div class="line"><a name="l00283"></a><span class="lineno"> 283</span>  srv.accept(*client);</div><div class="line"><a name="l00284"></a><span class="lineno"> 284</span>  client->read();</div><div class="line"><a name="l00285"></a><span class="lineno"> 285</span> });</div><div class="line"><a name="l00286"></a><span class="lineno"> 286</span> </div><div class="line"><a name="l00287"></a><span class="lineno"> 287</span> tcp->bind("127.0.0.1", 4242);</div><div class="line"><a name="l00288"></a><span class="lineno"> 288</span> tcp->listen();</div><div class="line"><a name="l00289"></a><span class="lineno"> 289</span> ```</div><div class="line"><a name="l00290"></a><span class="lineno"> 290</span> </div><div class="line"><a name="l00291"></a><span class="lineno"> 291</span> Note also that `uvw::TcpHandle` already supports _IPv6_ out-of-the-box. The statement above is equivalent to `tcp->bind<uvw::IPv4>("127.0.0.1", 4242)`.<br/></div><div class="line"><a name="l00292"></a><span class="lineno"> 292</span> It's suffice to explicitly specify `uvw::IPv6` as the underlying protocol to use it.</div><div class="line"><a name="l00293"></a><span class="lineno"> 293</span> </div><div class="line"><a name="l00294"></a><span class="lineno"> 294</span> The API reference is the recommended documentation for further details about resources and their methods.</div><div class="line"><a name="l00295"></a><span class="lineno"> 295</span> </div><div class="line"><a name="l00296"></a><span class="lineno"> 296</span> # Contributors</div><div class="line"><a name="l00297"></a><span class="lineno"> 297</span> </div><div class="line"><a name="l00298"></a><span class="lineno"> 298</span> If you want to contribute, please send patches as pull requests against the branch master.<br/></div><div class="line"><a name="l00299"></a><span class="lineno"> 299</span> Check the [contributors list](https://github.com/skypjack/uvw/blob/master/AUTHORS) to see who has partecipated so far.</div><div class="line"><a name="l00300"></a><span class="lineno"> 300</span> </div><div class="line"><a name="l00301"></a><span class="lineno"> 301</span> # Projects that use `uvw`</div><div class="line"><a name="l00302"></a><span class="lineno"> 302</span> </div><div class="line"><a name="l00303"></a><span class="lineno"> 303</span> Below an incomplete list of projects that use `uvw`:</div><div class="line"><a name="l00304"></a><span class="lineno"> 304</span> </div><div class="line"><a name="l00305"></a><span class="lineno"> 305</span> * Internal tools (not publicly available) at **[Cynny SpA](https://www.morphcast.com/)** and **[Cynny Space](http://www.cynnyspace.com/)**.</div><div class="line"><a name="l00306"></a><span class="lineno"> 306</span> * **[Calaos.fr](https://www.calaos.fr/en/)** (Open source home automation) on [GitHub](https://github.com/calaos).</div><div class="line"><a name="l00307"></a><span class="lineno"> 307</span> * **[Iroha](http://iroha.tech/en/) - A simple, decentralized ledger** on [Github](https://github.com/hyperledger/iroha).</div><div class="line"><a name="l00308"></a><span class="lineno"> 308</span> * **Iroha blockchain core** on [Github](https://github.com/finshield/iroha-core).</div><div class="line"><a name="l00309"></a><span class="lineno"> 309</span> * **Ecwid Console Downloader** on [GitHub](https://github.com/dvetutnev/Ecwid-Console-downloader).</div><div class="line"><a name="l00310"></a><span class="lineno"> 310</span> * **Simple network ping pong for lazy students** on [GitHub](https://github.com/dvetutnev/ping_pong).</div><div class="line"><a name="l00311"></a><span class="lineno"> 311</span> </div><div class="line"><a name="l00312"></a><span class="lineno"> 312</span> If you know of other projects that use `libuv` through `uvw`, feel free to open a PR and I'll be glad to add them to the list.</div><div class="line"><a name="l00313"></a><span class="lineno"> 313</span> </div><div class="line"><a name="l00314"></a><span class="lineno"> 314</span> # License</div><div class="line"><a name="l00315"></a><span class="lineno"> 315</span> </div><div class="line"><a name="l00316"></a><span class="lineno"> 316</span> Code and documentation Copyright (c) 2017 Michele Caini.<br/></div><div class="line"><a name="l00317"></a><span class="lineno"> 317</span> Code released under [the MIT license](https://github.com/skypjack/uvw/blob/master/LICENSE).<br/></div><div class="line"><a name="l00318"></a><span class="lineno"> 318</span> Docs released under [Creative Commons](https://github.com/skypjack/uvw/blob/master/docs/LICENSE).</div><div class="line"><a name="l00319"></a><span class="lineno"> 319</span> </div><div class="line"><a name="l00320"></a><span class="lineno"> 320</span> # Donation</div><div class="line"><a name="l00321"></a><span class="lineno"> 321</span> </div><div class="line"><a name="l00322"></a><span class="lineno"> 322</span> Developing and maintaining `uvw` takes some time and lots of coffee. It still lacks a proper test suite, documentation is partially incomplete and not all functionalities have been fully implemented yet.<br/></div><div class="line"><a name="l00323"></a><span class="lineno"> 323</span> If you want to support this project, you can offer me an espresso. I'm from Italy, we're used to turning the best coffee ever in code. If you find that it's not enough, feel free to support me the way you prefer.<br/></div><div class="line"><a name="l00324"></a><span class="lineno"> 324</span> Take a look at the donation button at the top of the page for more details or just click [here](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=W2HF9FESD5LJY&lc=IT&item_name=Michele%20Caini&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted).</div></div><!-- fragment --></div><!-- contents -->
|
|
<!-- start footer part -->
|
|
<hr class="footer"/><address class="footer"><small>
|
|
Generated by  <a href="http://www.doxygen.org/index.html">
|
|
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
|
</a> 1.8.13
|
|
</small></address>
|
|
</body>
|
|
</html>
|