index.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. <!DOCTYPE html>
  2. <!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
  3. <!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
  4. <head>
  5. <meta charset="utf-8">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8. <title>User Types - Luwra</title>
  9. <link rel="shortcut icon" href="../img/favicon.ico">
  10. <link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
  11. <link rel="stylesheet" href="../css/theme.css" type="text/css" />
  12. <link rel="stylesheet" href="../css/theme_extra.css" type="text/css" />
  13. <link rel="stylesheet" href="../css/highlight.css">
  14. <script>
  15. // Current page data
  16. var mkdocs_page_name = "User Types";
  17. var mkdocs_page_input_path = "user-types.md";
  18. var mkdocs_page_url = "/user-types/";
  19. </script>
  20. <script src="../js/jquery-2.1.1.min.js"></script>
  21. <script src="../js/modernizr-2.8.3.min.js"></script>
  22. <script type="text/javascript" src="../js/highlight.pack.js"></script>
  23. <script src="../js/theme.js"></script>
  24. </head>
  25. <body class="wy-body-for-nav" role="document">
  26. <div class="wy-grid-for-nav">
  27. <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
  28. <div class="wy-side-nav-search">
  29. <a href=".." class="icon icon-home"> Luwra</a>
  30. <div role="search">
  31. <form id ="rtd-search-form" class="wy-form" action="../search.html" method="get">
  32. <input type="text" name="q" placeholder="Search docs" />
  33. </form>
  34. </div>
  35. </div>
  36. <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
  37. <ul class="current">
  38. <li>
  39. <li class="toctree-l1 ">
  40. <a class="" href="..">Home</a>
  41. </li>
  42. <li>
  43. <li>
  44. <li class="toctree-l1 ">
  45. <a class="" href="../basics/">Basics</a>
  46. </li>
  47. <li>
  48. <li>
  49. <li class="toctree-l1 ">
  50. <a class="" href="../advanced/">Advanced Stack Interaction</a>
  51. </li>
  52. <li>
  53. <li>
  54. <li class="toctree-l1 ">
  55. <a class="" href="../wrapping/">Wrapping</a>
  56. </li>
  57. <li>
  58. <li>
  59. <li class="toctree-l1 current">
  60. <a class="current" href="./">User Types</a>
  61. <ul>
  62. <li class="toctree-l3"><a href="#user-types">User Types</a></li>
  63. <li><a class="toctree-l4" href="#register-user-type-with-constructor">Register user type with constructor</a></li>
  64. <li><a class="toctree-l4" href="#register-user-type-without-constructor">Register user type without constructor</a></li>
  65. <li><a class="toctree-l4" href="#usage-in-lua">Usage in Lua</a></li>
  66. <li><a class="toctree-l4" href="#manually-constructing-a-user-type">Manually constructing a user type</a></li>
  67. <li><a class="toctree-l4" href="#registry-names">Registry names</a></li>
  68. </ul>
  69. </li>
  70. <li>
  71. </ul>
  72. </div>
  73. &nbsp;
  74. </nav>
  75. <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
  76. <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
  77. <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
  78. <a href="..">Luwra</a>
  79. </nav>
  80. <div class="wy-nav-content">
  81. <div class="rst-content">
  82. <div role="navigation" aria-label="breadcrumbs navigation">
  83. <ul class="wy-breadcrumbs">
  84. <li><a href="..">Docs</a> &raquo;</li>
  85. <li>User Types</li>
  86. <li class="wy-breadcrumbs-aside">
  87. <a href="https://github.com/vapourismo/luwra" class="icon icon-github"> Edit on GitHub</a>
  88. </li>
  89. </ul>
  90. <hr/>
  91. </div>
  92. <div role="main">
  93. <div class="section">
  94. <h1 id="user-types">User Types</h1>
  95. <p>A user type is a collection of class members bundled into a metatable. Before user types can be used
  96. in Lua, you must register such metatable in Lua's registry.</p>
  97. <p>The following examples work on this class:</p>
  98. <pre><code class="c++">struct Point {
  99. double x, y;
  100. Point(double x, double y):
  101. x(x), y(y)
  102. {
  103. std::cout &lt;&lt; &quot;Construct Point(&quot; &lt;&lt; x &lt;&lt; &quot;, &quot; &lt;&lt; y &lt;&lt; &quot;)&quot; &lt;&lt; std::endl;
  104. }
  105. ~Point() {
  106. std::cout &lt;&lt; &quot;Destruct Point(&quot; &lt;&lt; x &lt;&lt; &quot;, &quot; &lt;&lt; y &lt;&lt; &quot;)&quot; &lt;&lt; std::endl;
  107. }
  108. void scale(double f) {
  109. x *= f;
  110. y *= f;
  111. }
  112. std::string __tostring() {
  113. return &quot;&lt;Point(&quot; + std::to_string(x) + &quot;, &quot; + std::to_string(y) + &quot;)&gt;&quot;;
  114. }
  115. };
  116. </code></pre>
  117. <h2 id="register-user-type-with-constructor">Register user type with constructor</h2>
  118. <p><a href="../reference/namespaceluwra.html#a683f6075862f8fc5cad0d76445f2f607">registerUserType&lt;S&gt;</a> allows
  119. you to register a metatable and constructor in the global namespace. The template parameter to
  120. <code>registerUserType</code> is a signature in the form of <code>U(A...)</code> where <code>U</code> is your user type and <code>A...</code>
  121. the parameter types to the constructor which you want to register.</p>
  122. <p>By default, the function generates a garbage-collector hook and a string representation function.
  123. If you add a <code>__gc</code> or <code>__tostring</code> meta method to your type, these auto-generated functions will be
  124. overridden.</p>
  125. <p>See this example:</p>
  126. <pre><code class="c++">luwra::registerUserType&lt;Point(double, double)&gt;(
  127. lua,
  128. // Constructor name
  129. &quot;Point&quot;,
  130. // Methods need to be declared here
  131. {
  132. LUWRA_MEMBER(Point, scale),
  133. LUWRA_MEMBER(Point, x),
  134. LUWRA_MEMBER(Point, y)
  135. },
  136. // Meta methods may be registered aswell
  137. {
  138. LUWRA_MEMBER(Point, __tostring)
  139. }
  140. );
  141. </code></pre>
  142. <p>Parameter 3 and 4 are instances of
  143. <a href="../reference/namespaceluwra.html#ac090722c6d5d6b88b31895aad64788c2">FieldVector</a>. The <code>LUWRA_MEMBER</code> macro
  144. generates a <code>std::pair&lt;Pushable, Pushable&gt;</code> expression.</p>
  145. <pre><code class="c++">LUWRA_MEMBER(Point, scale) === {&quot;scale&quot;, LUWRA_WRAP(Point::scale)}
  146. </code></pre>
  147. <p><code>Pushable</code> has an implicit constructor, which makes it convenient to add other types of fields:</p>
  148. <pre><code class="c++">luwra::registerUserType&lt;Point(double, double)&gt;(
  149. lua,
  150. // Constructor name
  151. &quot;Point&quot;,
  152. // Methods need to be declared here
  153. {
  154. {&quot;scale&quot;, LUWRA_WRAP(Point::scale)},
  155. {&quot;x&quot;, LUWRA_WRAP(Point::x)},
  156. {&quot;y&quot;, LUWRA_WRAP(Point::y)},
  157. {&quot;magic&quot;, luwra::FieldVector {
  158. {&quot;number&quot;, 1337},
  159. {&quot;string&quot;, &quot;Hello World&quot;}
  160. }}
  161. },
  162. // Meta methods may be registered aswell
  163. {
  164. {&quot;__tostring&quot;, LUWRA_WRAP(Point::__tostring)}
  165. }
  166. );
  167. </code></pre>
  168. <h2 id="register-user-type-without-constructor">Register user type without constructor</h2>
  169. <p>To register only the metatable associated with a user type, simply omit the constructor parameters
  170. and name from the call to <code>registerUserType</code>.</p>
  171. <pre><code class="c++">luwra::registerUserType&lt;Point&gt;(
  172. lua,
  173. // Methods need to be declared here
  174. {
  175. {&quot;scale&quot;, LUWRA_WRAP(Point::scale)},
  176. {&quot;x&quot;, LUWRA_WRAP(Point::x)},
  177. {&quot;y&quot;, LUWRA_WRAP(Point::y)},
  178. {&quot;magic&quot;, luwra::FieldVector {
  179. {&quot;number&quot;, 1337},
  180. {&quot;string&quot;, &quot;Hello World&quot;}
  181. }}
  182. },
  183. // Meta methods may be registered aswell
  184. {
  185. {&quot;__tostring&quot;, LUWRA_WRAP(Point::__tostring)}
  186. }
  187. );
  188. </code></pre>
  189. <p>It is still possible to provide a constructor using the <code>LUWRA_WRAP_CONSTRUCTOR</code> macro:</p>
  190. <pre><code class="c++">lua_CFunction ctor = LUWRA_WRAP_CONSTRUCTOR(Point, double, double);
  191. luwra::setGlobal(lua, &quot;Point&quot;, ctor);
  192. </code></pre>
  193. <h2 id="usage-in-lua">Usage in Lua</h2>
  194. <p>After you have registered your user type using one of the given methods, you can start using it in
  195. Lua:</p>
  196. <pre><code class="lua">-- Instantiate 'Point'
  197. local point = Point(13, 37)
  198. -- Invoke 'scale' method
  199. point:scale(1.5)
  200. -- Convert to string via '__tostring' meta method
  201. print(point)
  202. -- Read properties 'x' and 'y'
  203. print(point:x(), point:y())
  204. -- Set property 'x'
  205. point:x(point.magic.number)
  206. </code></pre>
  207. <h2 id="manually-constructing-a-user-type">Manually constructing a user type</h2>
  208. <p>Provided you already registered your user type, one can create it from the C++ side aswell.
  209. <a href="../reference/namespaceluwra.html#af079dcca8e67d88e5cfdc7e8872cf5d7">construct&lt;U&gt;</a> provides this
  210. functionality. Given the user type and constructor parameters, it will construct the user type on
  211. top of the stack:</p>
  212. <pre><code class="c++">Point&amp; my_point = luwra::construct&lt;Point&gt;(lua, 13.37, 73.31);
  213. // Changes on C++ side will be visible in Lua
  214. my_point.scale(2);
  215. </code></pre>
  216. <h2 id="registry-names">Registry names</h2>
  217. <p>When registering the metatable for a user type, an automatically generated name will be used to
  218. store it in the registry. When Luwra is used in a single executable or shared library, name
  219. collisions should not happen. If your application consists of multiple seperate compiled units, it
  220. is highly recommended to prevent name collisions by defining the <code>LUWRA_REGISTRY_PREFIX</code> macro
  221. before including the Luwra headers. This macro changes the prefix for auto-generated registry names.</p>
  222. <pre><code class="c++">#define LUWRA_REGISTRY_PREFIX &quot;MyProject#&quot;
  223. #include &lt;luwra.hpp&gt;
  224. </code></pre>
  225. <p>Another way to prevent collisons is to give each user type its individual registry name. This can be
  226. done using the <code>LUWRA_DEF_REGISTRY_NAME</code> macro.</p>
  227. <pre><code class="c++">struct MyUserType {
  228. // ...
  229. };
  230. LUWRA_DEF_REGISTRY_NAME(MyUserType, &quot;MyUserType&quot;)
  231. </code></pre>
  232. <p>Choosing this method will not prefix the registry name with the value of <code>LUWRA_REGISTRY_PREFIX</code>.</p>
  233. </div>
  234. </div>
  235. <footer>
  236. <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
  237. <a href="../wrapping/" class="btn btn-neutral" title="Wrapping"><span class="icon icon-circle-arrow-left"></span> Previous</a>
  238. </div>
  239. <hr/>
  240. <div role="contentinfo">
  241. <!-- Copyright etc -->
  242. </div>
  243. Built with <a href="http://www.mkdocs.org">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
  244. </footer>
  245. </div>
  246. </div>
  247. </section>
  248. </div>
  249. <div class="rst-versions" role="note" style="cursor: pointer">
  250. <span class="rst-current-version" data-toggle="rst-current-version">
  251. <a href="https://github.com/vapourismo/luwra" class="icon icon-github" style="float: left; color: #fcfcfc"> GitHub</a>
  252. <span><a href="../wrapping/" style="color: #fcfcfc;">&laquo; Previous</a></span>
  253. </span>
  254. </div>
  255. </body>
  256. </html>