mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 13:56:45 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1794 lines
		
	
	
	
		
			52 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			1794 lines
		
	
	
	
		
			52 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!doctype html>
 | |
| <html>
 | |
| <head>
 | |
| <title>LuaBridge 2.0 Reference Manual</title>
 | |
| <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
 | |
| 
 | |
| <!--=========================================================================-->
 | |
| <style TYPE="text/css">
 | |
| 
 | |
| body {
 | |
|   color: #000000 ;
 | |
|   background-color: #FFFFFF ;
 | |
|   font-family: Helvetica, Arial, sans-serif ;
 | |
|   text-align: justify ;
 | |
|   margin-right: 30px ;
 | |
|   margin-left: 30px ;
 | |
| }
 | |
| 
 | |
| h1, h2, h3, h4 {
 | |
|   font-family: Verdana, Geneva, sans-serif ;
 | |
|   font-weight: normal ;
 | |
|   font-style: normal ;
 | |
| }
 | |
| 
 | |
| h1 {
 | |
|   padding-top: 0.4em ;
 | |
|   padding-bottom: 0.4em ;
 | |
|   padding-left: 24px ;
 | |
|   margin-left: -24px ;
 | |
|   background-color: #ffe668 ;
 | |
|   border-radius: 8px ;
 | |
| }
 | |
| 
 | |
| h2 {
 | |
|   padding-top: 0.4em ;
 | |
|   padding-bottom: 0.4em ;
 | |
|   padding-left: 1em ;
 | |
|   padding-right: 1em ;
 | |
|   background-color: #ffe668 ;
 | |
|   border-radius: 8px ;
 | |
| }
 | |
| 
 | |
| h3 {
 | |
|   padding-left: 0.5em ;
 | |
|   border-left: solid #ffe668 1em ;
 | |
| }
 | |
| 
 | |
| a:link {
 | |
|   color: #8d5c00 ;
 | |
|   background-color: inherit ;
 | |
|   text-decoration: none ;
 | |
| }
 | |
| 
 | |
| a:visited {
 | |
|   color: #b17b26;
 | |
|   background-color: inherit ;
 | |
|   text-decoration: none ;
 | |
| }
 | |
| 
 | |
| a:link:hover, a:visited:hover {
 | |
|   color: #8d5c00 ;
 | |
|   background-color: #ffe668 ;
 | |
| }
 | |
| 
 | |
| a:link:active, a:visited:active {
 | |
|   color: inherit;
 | |
| }
 | |
| 
 | |
| hr {
 | |
|   border: 0 ;
 | |
|   height: 1px ;
 | |
|   color: #a0a0a0 ;
 | |
|   background-color: #a0a0a0 ;
 | |
| }
 | |
| 
 | |
| :target {
 | |
|   background-color: #F8F8F8 ;
 | |
|   padding-top: 2px ;
 | |
|   padding-bottom: 2px ;
 | |
|   padding-left: 8px;
 | |
|   padding-right: 8px;
 | |
|   border: solid #a0a0a0 2px ;
 | |
| }
 | |
| 
 | |
| .footer {
 | |
|   color: gray ;
 | |
|   font-size: small ;
 | |
| }
 | |
| 
 | |
| ul {
 | |
|   list-style-type: none ;
 | |
|   list-style-position: outside ;
 | |
| }
 | |
| 
 | |
| ul.bullets {
 | |
|   list-style-type: disc ;
 | |
| } 
 | |
| 
 | |
| img {
 | |
|   border: 0;
 | |
| }
 | |
| 
 | |
| table {
 | |
|   margin-left: 2em;
 | |
| }
 | |
| 
 | |
| pre, code {
 | |
|   font-size: 12pt ;
 | |
| }
 | |
| 
 | |
| pre {
 | |
|   margin-left: 2em;
 | |
| }
 | |
| 
 | |
| pre.split {
 | |
|   padding-left: 2em;
 | |
|   display: table-cell ;
 | |
|   white-space: pre-wrap ;
 | |
|   vertical-align: text-top ;
 | |
|   padding-right: 2em;
 | |
| }
 | |
| 
 | |
| pre.split + pre.split {
 | |
|   border-left: 1px solid #ccc;
 | |
| }
 | |
| 
 | |
| </style>
 | |
| 
 | |
| </head>
 | |
| 
 | |
| <!--=========================================================================-->
 | |
| 
 | |
| <body>
 | |
| 
 | |
| <header>
 | |
| <hr>
 | |
| <h1>LuaBridge 2.0 Reference Manual</h1>
 | |
| <hr>
 | |
| </header>
 | |
| 
 | |
| <small>
 | |
| Official repository is located at
 | |
| <a href="https://github.com/vinniefalco/LuaBridge">https://github.com/vinniefalco/LuaBridge</a>.
 | |
| <br>
 | |
| Copyright © 2012 Vinnie Falco. Freely available under the terms of the
 | |
| <A HREF="http://www.opensource.org/licenses/mit-license.html">MIT License</A>.
 | |
| </small>
 | |
| 
 | |
| <nav>
 | |
| <H2>Contents</H2>
 | |
| <UL id="toc" style="padding: 0">
 | |
| <LI><A href="#s1">1 - Introduction</A>
 | |
| <UL>
 | |
|   <LI><A href="#s1.1">1.1 - Design</A>
 | |
|   <LI><A href="#s1.2">1.2 - Repository</A>
 | |
|   <LI><A href="#s1.3">1.3 - License and Credits</A>
 | |
| </UL>
 | |
| <P>
 | |
| <LI><A href="#s2">2 - Accessing C++ from Lua</A>
 | |
| <UL>
 | |
|   <LI><A href="#s2.1">2.1 - Namespaces</A>
 | |
|   <LI><A href="#s2.2">2.2 - Data, Properties, Functions, and CFunctions</A>
 | |
|   <LI><A href="#s2.3">2.3 - Class Objects</A>
 | |
|   <LI><A href="#s2.4">2.4 - Property Member Proxies</A>
 | |
|   <LI><A href="#s2.5">2.5 - Constructors</A>
 | |
|   <LI><A href="#s2.6">2.6 - Lua Stack</A>
 | |
|   <LI><A href="#s2.7">2.7 - lua_State</A>
 | |
| </UL>
 | |
| <p>
 | |
| <LI><A href="#s3">3 - Passing Objects</A>
 | |
| <UL>
 | |
|   <LI><A href="#s3.1">3.1 - C++ Lifetime</A>
 | |
|   <LI><A href="#s3.2">3.2 - Lua Lifetime</A>
 | |
|   <LI><A href="#s3.3">3.3 - Pointers, References, and Pass by Value</A>
 | |
|   <LI><A href="#s3.4">3.4 - Shared Lifetime</A>
 | |
|   <UL>
 | |
|     <LI><A href="#s3.4.1">3.4.1 - Class RefCountedObjectPtr</A>
 | |
|     <LI><A href="#s3.4.2">3.4.2 - Class RefCountedPtr</A>
 | |
|     <LI><A href="#s3.4.3">3.4.3 - User-defined Containers</A>
 | |
|     <LI><A href="#s3.4.4">3.4.4 - Container Constructors</A>
 | |
|   </UL>
 | |
|   <LI><A href="#s3.5">3.5 - Mixing Lifetimes</A>
 | |
|   <LI><A href="#s3.6">3.6 - Convenience Functions</A>
 | |
| </UL>
 | |
| <P>
 | |
| <LI><A href="#s4">4 - Accessing Lua from C++</A>
 | |
| <UL>
 | |
|   <LI><A href="#s4.1">4.1 - Class LuaRef</A>
 | |
|   <UL>
 | |
|     <LI><A href="#s4.1.1">4.1.1 - Type Conversions</A>
 | |
|     <LI><A href="#s4.1.2">4.1.2 - Visual Studio 2010, 2012</A>
 | |
|   </UL>
 | |
|   <LI><A href="#s4.2">4.2 - Table Proxies</A>
 | |
|   <LI><A href="#s4.3">4.3 - Calling Lua</A>
 | |
|   <UL>
 | |
|     <LI><A href="#s4.3.1">4.3.1 - Class LuaException</A>
 | |
|   </UL>
 | |
| </uL>
 | |
| <P>
 | |
| <LI><A href="#s5">5 - Security</A>
 | |
| </UL>
 | |
| </nav>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h1>1 - <span id="s1">Introduction</span></h1>
 | |
| 
 | |
| <p>
 | |
| <a href="https://github.com/vinniefalco/LuaBridge">LuaBridge</a> is a
 | |
| lightweight and dependency-free library for mapping data, functions, and
 | |
| classes back and forth between C++ and <a href="http://wwww.lua.org">Lua</a>,
 | |
| a powerful, fast, lightweight, embeddable scripting language. LuaBridge has
 | |
| been tested and works with Lua revisions starting from 5.1.5, although it
 | |
| should work in any version of Lua from 5.1.0 and later. It also works
 | |
| transparently with <a href="http://luajit.org/">LuaJIT</a>.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| LuaBridge offers the following features:
 | |
| </p>
 | |
| 
 | |
| <ul class="bullets" title="Features">
 | |
| <li><a href="http://www.opensource.org/licenses/mit-license.html">MIT Licensed</a>, no usage restrictions!</li>
 | |
| <li>Headers-only: No Makefile, no .cpp files, just one <code>#include</code>!</li>
 | |
| <li>Simple, light, and nothing else needed (like Boost).</li>
 | |
| <li>No macros, settings, or configuration scripts needed.</li>
 | |
| <li>Supports different object lifetime management models.</li>
 | |
| <li>Convenient, type-safe access to the Lua stack.</li>
 | |
| <li>Automatic function parameter type binding.</li>
 | |
| <li>Easy access to Lua objects like tables and functions.</li>
 | |
| <li>Written in a clear and easy to debug style.</li>
 | |
| <li>Does not require C++11.</li>
 | |
| </ul>
 | |
| 
 | |
| <p>
 | |
| LuaBridge is distributed as a a collection of header files. You simply add
 | |
| one line, <code>#include "LuaBridge/LuaBridge.h"</code> where you want to
 | |
| pass functions, classes, and variables back and forth between C++ and Lua.
 | |
| There are no additional source files, no compilation settings, and no
 | |
| Makefiles or IDE-specific project files. LuaBridge is easy to integrate.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| C++ concepts like variables and classes are made available to Lua through a
 | |
| process called <em>registration</em>. Because Lua is weakly typed, the resulting
 | |
| structure is not rigid. The API is based on C++ template metaprogramming. It
 | |
| contains template code to automatically generate at compile-time the various
 | |
| Lua C API calls necessary to export your program's classes and functions to
 | |
| the Lua environment.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| To expose Lua objects to C++, a class called <code>LuaRef</code> is provided.
 | |
| The implementation allows C++ code to access Lua objects such as numbers
 | |
| or strings, but more importantly to access things like tables and their
 | |
| values. Using this class makes idioms like calling Lua functions simple
 | |
| and clean.
 | |
| </p>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>1.1 - <span id="s1.1">Design</span></h2>
 | |
| 
 | |
| <p>
 | |
| LuaBridge tries to be efficient as possible when creating the "glue" that
 | |
| exposes C++ data and functions to Lua. At the same time, the code was
 | |
| written with the intention that it is all as simple and clear as possible,
 | |
| without resorting to obscure C++ idioms, ugly preprocessor macros, or
 | |
| configuration settings. Furthermore, it is designed to be "header-only",
 | |
| making it very easy to integrate into your projects.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Because LuaBridge was written with simplicity in mind there are some features
 | |
| that are not available. Although it comes close to the highest possible
 | |
| performance, LuaBridge is not quite the fastest,
 | |
| <a href="http://code.google.com/p/oolua/">OOLua</a> slightly outperforms
 | |
| LuaBridge in some tests. LuaBridge also does not try to implement every
 | |
| possible feature,
 | |
| <a href="http://www.rasterbar.com/products/luabind.html">LuaBind</a>
 | |
| explores every corner of the C++ language (but it requires Boost).
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| LuaBridge does not support:
 | |
| </p>
 | |
| 
 | |
| <ul class="bullets">
 | |
| <li>Enumerated constants
 | |
| <li>More than 8 parameters on a function or method (although this can be
 | |
|     increased by adding more <code>TypeListValues</code> specializations).
 | |
| <li>Overloaded functions, methods, or constructors.
 | |
| <li>Global variables (variables must be wrapped in a named scope).
 | |
| <li>Automatic conversion between STL container types and Lua tables.
 | |
| <li>Inheriting Lua classes from C++ classes.
 | |
| <li>Passing nil to a C++ function that expects a pointer or reference.
 | |
| <li>Standard containers like <code>std::shared_ptr</code>.
 | |
| </ul>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>1.2 - <span id="s1.2">Repository</span></h2>
 | |
| 
 | |
| <p>
 | |
| The official repository is located at
 | |
| <a href="https://github.com/vinniefalco/LuaBridge">https://github.com/vinniefalco/LuaBridge</a>.
 | |
| The branches are organized as follows:
 | |
| </p>
 | |
| 
 | |
| <table>
 | |
| <tr>
 | |
|   <td><b>master</b></td>
 | |
|   <td>Tagged, stable release versions.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b>release</b></td>
 | |
|   <td>A temporarily created branch that holds a release candidate for review.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b>develop</b></td>
 | |
|   <td>Contains work in progress, possibly unfinished or with bugs.</td>
 | |
| </tr>
 | |
| </table>
 | |
| 
 | |
| <p>
 | |
| These repositories are also available:
 | |
| </p>
 | |
| 
 | |
| <table>
 | |
| <tr>
 | |
|   <td><b><a href="https://github.com/vinniefalco/LuaBridgeUnitTests">LuaBridgeUnitTests</a></b></td>
 | |
|   <td>A stand alone command line application to exercise LuaBridge functionality.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b><a href="https://github.com/vinniefalco/LuaBridgeDemo">LuaBridgeUnitDemo</a></b></td>
 | |
|   <td>A stand alone GUI application that provides an interactive console.</td>
 | |
| </tr>
 | |
| </table>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>1.3 - <span id="s1.3">License and Credits</span></h2>
 | |
| 
 | |
| <p>
 | |
| LuaBridge is published under the terms of the
 | |
| <a href="http://www.opensource.org/licenses/mit-license.html">MIT License</a>:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| Permission is hereby granted, free of charge, to any person obtaining a copy
 | |
| of this software and associated documentation files (the "Software"), to deal
 | |
| in the Software without restriction, including without limitation the rights
 | |
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | |
| copies of the Software, and to permit persons to whom the Software is
 | |
| furnished to do so, subject to the following conditions:
 | |
| 
 | |
| The above copyright notice and this permission notice shall be included in
 | |
| all copies or substantial portions of the Software.
 | |
| 
 | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | |
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | |
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | |
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | |
| SOFTWARE.
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| The original version of LuaBridge was written by Nathan Reed. The project
 | |
| has been taken over by Vinnie Falco, who added new functionality and wrote
 | |
| the new documentation. Vinnie also incorporated <code>LuaRef</code> and
 | |
| other Lua to C++ binding contributions from Nigel Atkinson.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| For questions, comments, or bug reports feel free to open a Github issue
 | |
| or contact Vinnie Falco directly at the email address indicated below.
 | |
| </p>
 | |
| 
 | |
| <ul>
 | |
| <li>Copyright 2012, Vinnie Falco <a href="mailto:vinnie.falco@gmail.com"><vinnie.falco@gmail.com></a>
 | |
| <li>Copyright 2008, Nigel Atkinson <a href="mailto:suprapilot+LuaCode@gmail.com"><suprapilot+LuaCode@gmail.com></a>
 | |
| <li>Copyright 2007, Nathan Reed
 | |
| <li>Portions from The Loki Library: Copyright 2001 by Andrei Alexandrescu
 | |
| </ul>
 | |
| 
 | |
| <p>
 | |
| Older versions of LuaBridge up to and including 0.2 (available separately) are
 | |
| distributed under the BSD 3-Clause License. See the corresponding license file
 | |
| in those versions (distributed separately) for more details.
 | |
| </p>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h1>2 - <span id="s2">Accessing C++ from Lua</span></h1>
 | |
| 
 | |
| <p>
 | |
| In order to expose C++ data and functions to Lua, each piece of exported
 | |
| information must be <em>registered</em>. There are five types of objects that
 | |
| LuaBridge can register:
 | |
| </p>
 | |
| 
 | |
| <table>
 | |
| <tr>
 | |
|   <td><b>Namespaces</b>  </td>
 | |
|   <td>A Lua table that contains other registrations.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b>Data</b>  </td>
 | |
|   <td>Global or static variables, data members, and static data members.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b>Functions  </b></td>
 | |
|   <td>Regular functions, member functions, and static member functions.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b>CFunctions  </b></td>
 | |
|   <td>A regular function, member function, or static member function that
 | |
|       uses the <code>lua_CFunction</code> calling convention.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b>Properties  </b></td>
 | |
|   <td>Global properties, property members, and static property members.
 | |
|       These appear like data to Lua, but are implemented in C++ using
 | |
|       functions to get and set the values.</td>
 | |
|   </tr>
 | |
| </table>
 | |
| 
 | |
| <p>
 | |
| Both data and properties can be marked as <em>read-only</em> at the time of
 | |
| registration. This is different from <code>const</code>; the values of these
 | |
| objects can be modified on the C++ side, but Lua scripts cannot change them.
 | |
| Code samples that follow are in C++ or Lua, depending on context. For brevity
 | |
| of exposition code samples in C++ assume the traditional variable
 | |
| <code>lua_State* L</code> is defined, and that a <code>using namespace luabridge</code>
 | |
| using-directive is in effect.
 | |
| </p>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>2.1 - <span id="s2.1">Namespaces</span></h2>
 | |
| 
 | |
| <p>
 | |
| All LuaBridge registrations take place in a <em>namespace</em>. When we refer
 | |
| to a <em>namespace</em> we are always talking about a namespace in the Lua
 | |
| sense, which is implemented using tables. The namespace need not correspond
 | |
| to a C++ namespace; in fact no C++ namespaces need to exist at all unless you
 | |
| want them to. LuaBridge namespaces are visible only to Lua scripts; they are
 | |
| used as a logical grouping tool. To obtain access to the global namespace
 | |
| we write:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| getGlobalNamespace (L);
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| This returns an object on which further registrations can be performed. The
 | |
| subsequent registrations will go into the global namespace, a practice which
 | |
| is not recommended. Instead, we can add our own namespace by writing:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| getGlobalNamespace (L)
 | |
|   .beginNamespace ("test");
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| This creates a table in <code>_G</code> called "test". Since we have not
 | |
| performed any registrations, this table will be empty except for some
 | |
| bookkeeping key/value pairs. LuaBridge reserves all identifiers that start
 | |
| with a double underscore. So <code>__test</code> would be an invalid name
 | |
| (although LuaBridge will silently accept it). Functions like
 | |
| <code>beginNamespace</code> return the corresponding object on which we can
 | |
| make more registrations. Given:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| getGlobalNamespace (L)
 | |
|   .beginNamespace ("test")
 | |
|     .beginNamespace ("detail")
 | |
|     .endNamespace ()
 | |
|     .beginNamespace ("utility")
 | |
|     .endNamespace ()
 | |
|   .endNamespace ();
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| The results are accessible to Lua as <code>test</code>, <code>test.detail</code>,
 | |
| and <code>test.utility</code>. Here we introduce the <code>endNamespace</code>
 | |
| function; it returns an object representing the original enclosing namespace.
 | |
| All LuaBridge functions which  create registrations return an object upon which
 | |
| subsequent registrations can be made, allowing for an unlimited number of
 | |
| registrations to be chained together using the dot operator. Adding two objects
 | |
| with the same name, in the same namespace, results in undefined behavior
 | |
| (although LuaBridge will silently accept it).
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| A namespace can be re-opened later to add more functions. This lets you split
 | |
| up the registration between different source files. These are equivalent:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| getGlobalNamespace (L)
 | |
|   .beginNamespace ("test")
 | |
|     .addFunction ("foo", foo)
 | |
|   .endNamespace ();
 | |
| 
 | |
| getGlobalNamespace (L)
 | |
|   .beginNamespace ("test")
 | |
|     .addFunction ("bar", bar)
 | |
|   .endNamespace ();
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| and
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| getGlobalNamespace (L)
 | |
|   .beginNamespace ("test")
 | |
|     .addFunction ("foo", foo)
 | |
|     .addFunction ("bar", bar)
 | |
|   .endNamespace ();
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>2.2 - <span id="s2.2">Data, Properties, Functions, and CFunctions</span></h2>
 | |
| 
 | |
| <p>
 | |
| These are registered into a namespace using <code>addVariable</code>,
 | |
| <code>addProperty</code>, <code>addFunction</code>, and <code>addCFunction</code>.
 | |
| When registered functions are called by scripts, LuaBridge automatically takes
 | |
| care of the conversion of arguments into the appropriate data type when doing
 | |
| so is possible. This automated system works for the function's return value,
 | |
| and up to 8 parameters although more can be added by extending the templates.
 | |
| Pointers, references, and objects of class type as parameters are treated
 | |
| specially, and explained later. If we have:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| int globalVar;
 | |
| static float staticVar;
 | |
| 
 | |
| std::string stringProperty;
 | |
| std::string getString () { return stringProperty; }
 | |
| void setString (std::string s) { stringProperty = s; }
 | |
| 
 | |
| int foo () { return 42; }
 | |
| void bar (char const*) { }
 | |
| int cFunc (lua_State* L) { return 0; }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| These are registered with:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| getGlobalNamespace (L)
 | |
|   .beginNamespace ("test")
 | |
|     .addVariable ("var1", &globalVar)
 | |
|     .addVariable ("var2", &staticVar, false)     // read-only
 | |
|     .addProperty ("prop1", getString, setString)
 | |
|     .addProperty ("prop2", getString)            // read only
 | |
|     .addFunction ("foo", foo)
 | |
|     .addFunction ("bar", bar)
 | |
|     .addCFunction ("cfunc", cFunc)
 | |
|   .endNamespace ();
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Variables can be marked <em>read-only</em> by passing <code>false</code> in
 | |
| the second optional parameter. If the parameter is omitted, <em>true</em> is
 | |
| used making the variable read/write. Properties are marked read-only by
 | |
| omitting the set function. After the registrations above, the following Lua
 | |
| identifiers are valid:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| test        -- a namespace
 | |
| test.var1   -- a lua_Number variable
 | |
| test.var2   -- a read-only lua_Number variable
 | |
| test.prop1  -- a lua_String property
 | |
| test.prop2  -- a read-only lua_String property
 | |
| test.foo    -- a function returning a lua_Number
 | |
| test.bar    -- a function taking a lua_String as a parameter
 | |
| test.cfunc  -- a function with a variable argument list and multi-return
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Note that <code>test.prop1</code> and `test.prop2` both refer to the
 | |
| same value. However, since <code>test.prop2</code> is read-only, assignment
 | |
| attempts will generate a run-time error. These Lua statements have the stated effects:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| test.var1 = 5         -- okay
 | |
| test.var2 = 6         -- error: var2 is not writable
 | |
| test.prop1 = "Hello"  -- okay
 | |
| test.prop1 = 68       -- okay, Lua converts the number to a string.
 | |
| test.prop2 = "bar"    -- error: prop2 is not writable
 | |
| 
 | |
| test.foo ()           -- calls foo and discards the return value
 | |
| test.var1 = foo ()    -- calls foo and stores the result in var1
 | |
| test.bar ("Employee") -- calls bar with a string
 | |
| test.bar (test)       -- error: bar expects a string not a table
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| LuaBridge does not support overloaded functions nor is it likely to in the
 | |
| future. Since Lua is dynamically typed, any system that tries to resolve a set
 | |
| of parameters passed from a script will face considerable ambiguity when
 | |
| trying to choose an appropriately matching C++ function signature.
 | |
| </p>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>2.3 - <span id="s2.3">Class Objects</span></h2>
 | |
| 
 | |
| <p>
 | |
| A class registration is opened using either <code>beginClass</code> or
 | |
| <code>deriveClass</code> and ended using <code>endClass</code>. Once
 | |
| registered, a class can later be re-opened for more registrations using
 | |
| <code>beginClass</code>. However, <code>deriveClass</code> should only be
 | |
| used once. To add more registrations to an already registered derived class,
 | |
| use <code>beginClass</code> on it. These declarations:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| struct A {
 | |
|   static int staticData;
 | |
|   static float staticProperty;
 | |
|     
 | |
|   static float getStaticProperty () { return staticProperty; }
 | |
|   static void setStaticProperty (float f) { staticProperty = f; }
 | |
|   static void staticFunc () { }
 | |
| 
 | |
|   static int staticCFunc () { return 0; }
 | |
| 
 | |
|   std::string dataMember;
 | |
| 
 | |
|   char dataProperty;
 | |
|   char getProperty () const { return dataProperty; }
 | |
|   void setProperty (char v) { dataProperty = v; }
 | |
| 
 | |
|   void func1 () { }
 | |
|   virtual void virtualFunc () { }
 | |
| 
 | |
|   int cfunc (lua_State* L) { return 0; }
 | |
| };
 | |
| 
 | |
| struct B : public A {
 | |
|   double dataMember2;
 | |
| 
 | |
|   void func1 () { }
 | |
|   void func2 () { }
 | |
|   void virtualFunc () { }
 | |
| };
 | |
| 
 | |
| int A::staticData;
 | |
| float A::staticProperty;
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| are registered using:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| getGlobalNamespace (L)
 | |
|   .beginNamespace ("test")
 | |
|     .beginClass <A> ("A")
 | |
|       .addStaticData ("staticData", &A::staticData)
 | |
|       .addStaticProperty ("staticProperty", &A::staticProperty)
 | |
|       .addStaticFunction ("staticFunc", &A::staticFunc)
 | |
|       .addStaticCFunction ("staticCFunc", &A::staticCFunc)
 | |
|       .addData ("data", &A::dataMember)
 | |
|       .addProperty ("prop", &A::getProperty, &A::setProperty)
 | |
|       .addFunction ("func1", &A::func1)
 | |
|       .addFunction ("virtualFunc", &A::virtualFunc)
 | |
|       .addCFunction ("cfunc", &A::cfunc)
 | |
|     .endClass ()
 | |
|     .deriveClass <B, A> ("B")
 | |
|       .addData ("data", &B::dataMember2)
 | |
|       .addFunction ("func1", &B::func1)
 | |
|       .addFunction ("func2", &B::func2)
 | |
|     .endClass ()
 | |
|   .endNameSpace ();
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Method registration works just like function registration.  Virtual methods
 | |
| work normally; no special syntax is needed. const methods are detected and
 | |
| const-correctness is enforced, so if a function returns a const object (or
 | |
| a container holding to a const object) to Lua, that reference to the object
 | |
| will be considered const and only const methods can be called on it.
 | |
| Destructors are registered automatically for each class.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| As with regular variables and properties, class data and properties can be
 | |
| marked read-only by passing false in the second parameter, or omitting the set
 | |
| set function respectively. The `deriveClass` takes two template arguments: the
 | |
| class to be registered, and its base class.  Inherited methods do not have to
 | |
| be re-declared and will function normally in Lua. If a class has a base class
 | |
| that is **not** registered with Lua, there is no need to declare it as a
 | |
| subclass.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Remember that in Lua, the colon operator '<code>:</code>' is used for
 | |
| method call syntax:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| local a = A ()
 | |
| 
 | |
| a.func1 () -- Does nothing
 | |
| a:func1 () -- Works
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>2.4 - <span id="s2.4">Property Member Proxies</span></h2>
 | |
| 
 | |
| <p>
 | |
| Sometimes when registering a class which comes from a third party library, the
 | |
| data is not exposed in a way that can be expressed as a pointer to member,
 | |
| there are no get or set functions, or the get and set functons do not have the
 | |
| right function signature. Since the class declaration is closed for changes,
 | |
| LuaBridge allows for a <em>property member proxy</em>. This is a pair of get
 | |
| and set flat functions which take as their first parameter a pointer to
 | |
| the object. This is easily understood with the following example:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| // Third party declaration, can't be changed
 | |
| struct Vec 
 | |
| {
 | |
|   float coord [3];
 | |
| };
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Taking the address of an array element, e.g. <code>&Vec::coord [0]</code>
 | |
| results in an error instead of a pointer-to-member. The class is closed for
 | |
| modifications, but we want to export Vec objects to Lua using the familiar
 | |
| object notation. To do this, first we add a "helper" class:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| struct VecHelper
 | |
| {
 | |
|   template <unsigned index>
 | |
|   static float get (Vec const* vec)
 | |
|   {
 | |
|     return vec->coord [index];
 | |
|   }
 | |
| 
 | |
|   template <unsigned index>
 | |
|   static void set (Vec* vec, float value)
 | |
|   {
 | |
|     vec->coord [index] = value;
 | |
|   }
 | |
| };
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| This helper class is only used to provide property member proxies.
 | |
| <code>Vec</code> continues to be used in the C++ code as it was before.
 | |
| Now we can register the <code>Vec</code> class with property member proxies for
 | |
| <code>x</code>, <code>y</code>, and <code>z</code>:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| getGlobalNamespace (L)
 | |
|   .beginNamespace ("test")
 | |
|     .beginClass <Vec> ("Vec")
 | |
|       .addProperty ("x", &VecHelper::get <0>, &VecHelper::set <0>)
 | |
|       .addProperty ("y", &VecHelper::get <1>, &VecHelper::set <1>)
 | |
|       .addProperty ("z", &VecHelper::get <2>, &VecHelper::set <2>)
 | |
|     .endClass ()
 | |
|   .endNamespace ();
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>2.5 - <span id="s2.5">Constructors</span></h2>
 | |
| 
 | |
| <p>
 | |
| A single constructor may be added for a class using <code>addConstructor</code>.
 | |
| LuaBridge cannot automatically determine the number and types of constructor
 | |
| parameters like it can for functions and methods, so you must provide them.
 | |
| This is done by specifying the signature of the desired constructor function
 | |
| as the first template parameter to <code>addConstructor</code>. The parameter
 | |
| types will be extracted from this (the return type is ignored).  For example,
 | |
| these statements register constructors for the given classes:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| struct A {
 | |
|   A ();
 | |
| };
 | |
| 
 | |
| struct B {
 | |
|   explicit B (char const* s, int nChars);
 | |
| };
 | |
| 
 | |
| getGlobalNamespace (L)
 | |
|   .beginNamespace ("test")
 | |
|     .beginClass <A> ("A")
 | |
|       .addConstructor <void (*) (void)> ()
 | |
|     .endClass ()
 | |
|     .beginClass <B> ("B")
 | |
|       .addConstructor <void (*) (char const*, int)> ()
 | |
|     .endClass ()
 | |
|   .endNamespace ();
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Constructors added in this fashion are called from Lua using the fully
 | |
| qualified name of the class. This Lua code will create instances of
 | |
| <code>A</code> and <code>B</code>.
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| a = test.A ()           -- Create a new A.
 | |
| b = test.B ("hello", 5) -- Create a new B.
 | |
| b = test.B ()           -- Error: expected string in argument 1
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>2.6 - <span id="s2.6">Lua Stack</span></h2>
 | |
| 
 | |
| <p>
 | |
| In the Lua C API, all operations on the <code>lua_State</code> are performed
 | |
| through the Lua stack. In order to pass values back and forth between C++
 | |
| and Lua, LuaBridge uses specializations of this template class concept:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| template <class T>
 | |
| struct Stack
 | |
| {
 | |
|   static void push (lua_State* L, T t);
 | |
|   static T get (lua_State* L, int index);
 | |
| };
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| When a specialization of <code>Stack</code> exists for a given type
 | |
| <code>T</code> we say that the <code>T</code> is <em>convertible</em>.
 | |
| Throughout this document and the LuaBridge API, these types can be used
 | |
| anywhere a convertible type is expected.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| The Stack template class specializations are used automatically for variables,
 | |
| properties, data members, property members, function arguments and return
 | |
| values. These basic types are supported:
 | |
| </p>
 | |
| 
 | |
| <ul class="bullets">
 | |
| <li><code>bool</code>
 | |
| <li><code>char</code>, converted to a string of length one.
 | |
| <li><code>char const*</code> and <code>std::string</code> strings.
 | |
| <li>Integers, <code>float</code>, and <code>double</code>,
 | |
|     converted to <code>Lua_number</code>.
 | |
| </ul>
 | |
| 
 | |
| <p>
 | |
| User-defined types which are convertible to one of the basic types are
 | |
| possible, simply provide a <code>Stack<></code> specialization in the
 | |
| <code>luabridge</code> namespace for your user-defined type, modeled after
 | |
| the existing types. For example, here is a specialization for a
 | |
| <code>juce::String</code>:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| template <>
 | |
| struct Stack <juce::String>
 | |
| {
 | |
|   static void push (lua_State* L, juce::String s)
 | |
|   {
 | |
|     lua_pushstring (L, s.toUTF8 ());
 | |
|   }
 | |
| 
 | |
|   static juce::String get (lua_State* L, int index)
 | |
|   {
 | |
|     return juce::String (luaL_checkstring (L, index));
 | |
|   }
 | |
| };
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>2.7 - <span id="s2.7">lua_State</span></h2>
 | |
| 
 | |
| <p>
 | |
| Sometimes it is convenient from within a bound function or member function
 | |
| to gain access to the `lua_State*` normally available to a `lua_CFunction`.
 | |
| With LuaBridge, all you need to do is add a `lua_State*` as the last
 | |
| parameter of your bound function:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| void useState (lua_State* L);
 | |
| 
 | |
| getGlobalNamespace (L).addFunction ("useState", &useState);
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| You can still include regular arguments while receiving the state:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| void useStateAndArgs (int i, std::string s, lua_State* L);
 | |
| 
 | |
| getGlobalNamespace (L).addFunction ("useStateAndArgs", &useStateAndArgs);
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| When the script calls <code>useStateAndArgs</code>, it passes only the integer
 | |
| and string parameters. LuaBridge takes care of inserting the <code>lua_State*</code>
 | |
| into the argument list for the corresponding C++ function. This will work
 | |
| correctly even for the state created by coroutines. Undefined behavior results
 | |
| if the <code>lua_State*</code> is not the last parameter.
 | |
| </p>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h1>3 - <span id="s3">Passing Objects</span></h1>
 | |
| 
 | |
| <p>
 | |
| An object of a registered class <code>T</code> may be passed to Lua as:
 | |
| </p>
 | |
| 
 | |
| <table>
 | |
| <tr>
 | |
|   <td><b><code>T</code></b></td>
 | |
|   <td>Passed by value (a copy), with <em>Lua lifetime</em>.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b><code>T const</code></b></td>
 | |
|   <td>Passed by value (a copy), with <em>Lua lifetime</em>.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b><code>T*</code></b></td>
 | |
|   <td>Passed by reference, with <em>C++ lifetime</em>.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b><code>T&</code></b></td>
 | |
|   <td>Passed by reference, with <em>C++ lifetime</em>.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b><code>T const*</code></b></td>
 | |
|   <td>Passed by const reference, with <em>C++ lifetime</em>.</td>
 | |
| </tr>
 | |
| <tr>
 | |
|   <td><b><code>T const&</code></b></td>
 | |
|   <td>Passed by const reference, with <em>C++ lifetime</em>.</td>
 | |
| </tr>
 | |
| </table>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>3.1 - <span id="s3.1">C++ Lifetime</span></h2>
 | |
| 
 | |
| <p>
 | |
| The creation and deletion of objects with <em>C++ lifetime</em> is controlled by
 | |
| the C++ code. Lua does nothing when it garbage collects a reference to such an
 | |
| object. Specifically, the object's destructor is not called (since C++ owns
 | |
| it). Care must be taken to ensure that objects with C++ lifetime are not
 | |
| deleted while still being referenced by a <code>lua_State*</code>, or else
 | |
| undefined behavior results. In the previous examples, an instance of <code>A</code>
 | |
| can be passed to Lua with C++ lifetime, like this:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| A a;
 | |
| 
 | |
| push (L, &a);             // pointer to 'a', C++ lifetime
 | |
| lua_setglobal (L, "a");
 | |
| 
 | |
| push (L, (A const*)&a);   // pointer to 'a const', C++ lifetime
 | |
| lua_setglobal (L, "ac");
 | |
| 
 | |
| push <A const*> (L, &a);  // equivalent to push (L, (A const*)&a)
 | |
| lua_setglobal (L, "ac2");
 | |
| 
 | |
| push (L, new A);          // compiles, but will leak memory
 | |
| lua_setglobal (L, "ap");
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>3.2 - <span id="s3.2">Lua Lifetime</span></h2>
 | |
| 
 | |
| <p>
 | |
| When an object of a registered class is passed by value to Lua, it will have
 | |
| <em>Lua lifetime</em>. A copy of the passed object is constructed inside the
 | |
| userdata. When Lua has no more references to the object, it becomes eligible
 | |
| for garbage collection. When the userdata is collected, the destructor for
 | |
| the class will be called on the object. Care must be taken to ensure that
 | |
| objects with Lua lifetime are not accessed by C++ after they are garbage
 | |
| collected, or else undefined behavior results. An instance of <code>B</code>
 | |
| can be passed to Lua with Lua lifetime this way:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| B b;
 | |
| 
 | |
| push (L, b);                    // Copy of b passed, Lua lifetime.
 | |
| lua_setglobal (L, "b");
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Given the previous code segments, these Lua statements are applicable:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| print (test.A.staticData)       -- Prints the static data member.
 | |
| print (test.A.staticProperty)   -- Prints the static property member.
 | |
| test.A.staticFunc ()            -- Calls the static method.
 | |
| 
 | |
| print (a.data)                  -- Prints the data member.
 | |
| print (a.prop)                  -- Prints the property member.
 | |
| a:func1 ()                      -- Calls A::func1 ().
 | |
| test.A.func1 (a)                -- Equivalent to a:func1 ().
 | |
| test.A.func1 ("hello")          -- Error: "hello" is not a class A.
 | |
| a:virtualFunc ()                -- Calls A::virtualFunc ().
 | |
| 
 | |
| print (b.data)                  -- Prints B::dataMember.
 | |
| print (b.prop)                  -- Prints inherited property member.
 | |
| b:func1 ()                      -- Calls B::func1 ().
 | |
| b:func2 ()                      -- Calls B::func2 ().
 | |
| test.B.func2 (a)                -- Error: a is not a class B.
 | |
| test.A.func1 (b)                -- Calls A::func1 ().
 | |
| b:virtualFunc ()                -- Calls B::virtualFunc ().
 | |
| test.B.virtualFunc (b)          -- Calls B::virtualFunc ().
 | |
| test.A.virtualFunc (b)          -- Calls B::virtualFunc ().
 | |
| test.B.virtualFunc (a)          -- Error: a is not a class B.
 | |
| 
 | |
| a = nil; collectgarbage ()      -- 'a' still exists in C++.
 | |
| b = nil; collectgarbage ()      -- Lua calls ~B() on the copy of b.
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| When Lua script creates an object of class type using a registered
 | |
| constructor, the resulting value will have Lua lifetime. After Lua no longer
 | |
| references the object, it becomes eligible for garbage collection. You can
 | |
| still pass these to C++, either by reference or by value. If passed by
 | |
| reference, the usual warnings apply about accessing the reference later,
 | |
| after it has been garbage collected.
 | |
| </p>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>3.3 - <span id="s3.3">Pointers, References, and Pass by Value</span></h2>
 | |
| 
 | |
| <p>
 | |
| When C++ objects are passed from Lua back to C++ as arguments to functions,
 | |
| or set as data members, LuaBridge does its best to automate the conversion.
 | |
| Using the previous definitions, the following functions may be registered
 | |
| to Lua:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| void func0 (A a);
 | |
| void func1 (A* a);
 | |
| void func2 (A const* a);
 | |
| void func3 (A& a);
 | |
| void func4 (A const& a);
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Executing this Lua code will have the prescribed effect:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| func0 (a)   -- Passes a copy of a, using A's copy constructor.
 | |
| func1 (a)   -- Passes a pointer to a.
 | |
| func2 (a)   -- Passes a pointer to a const a.
 | |
| func3 (a)   -- Passes a reference to a.
 | |
| func4 (a)   -- Passes a reference to a const a.
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| In the example above, all functions can read the data members and property
 | |
| members of <code>a</code>, or call const member functions of <code>a</code>.
 | |
| Only <code>func0</code>, <code>func1</code>, and <code>func3</code> can
 | |
| modify the data members and data properties, or call non-const member
 | |
| functions of <code>a</code>.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| The usual C++ inheritance and pointer assignment rules apply. Given:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| void func5 (B b);
 | |
| void func6 (B* b);
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| These Lua statements hold:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| func5 (b)   - Passes a copy of b, using B's copy constructor.
 | |
| func6 (b)   - Passes a pointer to b.
 | |
| func6 (a)   - Error: Pointer to B expected.
 | |
| func1 (b)   - Okay, b is a subclass of a.
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| When a pointer or pointer to const is passed to Lua and the pointer is null
 | |
| (zero), LuaBridge will pass Lua a `nil` instead. When Lua passes a
 | |
| <code>nil</code> to C++ where a pointer is expected, a null (zero) is passed
 | |
| instead. Attempting to pass a null pointer to a C++ function expecting a
 | |
| reference results in <code>lua_error</code> being called.
 | |
| </p>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>3.4 - <span id="s3.4">Shared Lifetime</span></h2>
 | |
| 
 | |
| <p>
 | |
| LuaBridge supports a <em>shared lifetime</em> model: dynamically allocated
 | |
| and reference counted objects whose ownership is shared by both Lua and C++.
 | |
| The object remains in existence until there are no remaining C++ or Lua
 | |
| references, and Lua performs its usual garbage collection cycle. A container
 | |
| is recognized by a specialization of the <code>ContainerTraits</code>
 | |
| template class. LuaBridge will automatically recognize when a data type is
 | |
| a container when the correspoding specialization is present. Two styles of
 | |
| containers come with LuaBridge, including the necessary specializations.
 | |
| </p>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h3>3.4.1 - <span id="s3.4.1">Class RefCountedObjectPtr</span></h3>
 | |
| 
 | |
| <p>
 | |
| This is an intrusive style container. Your existing class declaration must be
 | |
| changed to be also derived from <code>RefCountedObject</code>. Given
 | |
| <code>class T</code>, derived from <code>RefCountedObject</code>, the container
 | |
| <code>RefCountedObjectPtr <T></code>` may be used. In order for
 | |
| reference counts to be maintained properly, all C++ code must store a
 | |
| container instead of the pointer. This is similar in style to
 | |
| <code>std::shared_ptr</code> although there are slight differences. For
 | |
| example:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| // A is reference counted.
 | |
| struct A : public RefCountedObject
 | |
| {
 | |
|   void foo () { }
 | |
| };
 | |
| 
 | |
| struct B
 | |
| {
 | |
|   RefCountedObjectPtr <A> a; // holds a reference to A
 | |
| };
 | |
| 
 | |
| void bar (RefCountedObjectPtr <A> a)
 | |
| {
 | |
|   a->foo ();
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h3>3.4.2 - <span id="s3.4.2">Class RefCountedPtr</span></h3>
 | |
| 
 | |
| <p>
 | |
| This is a non intrusive reference counted pointer. The reference counts are
 | |
| kept in a global hash table, which does incur a small performance penalty.
 | |
| However, it does not require changing any already existing class declarations.
 | |
| This is especially useful when the classes to be registered come from a third
 | |
| party library and cannot be modified. To use it, simply wrap all pointers
 | |
| to class objects with the container instead:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| struct A
 | |
| {
 | |
|   void foo () { }
 | |
| };
 | |
| 
 | |
| struct B
 | |
| {
 | |
|   RefCountedPtr <A> a;
 | |
| };
 | |
| 
 | |
| RefCountedPtr <A> createA ()
 | |
| {
 | |
|   return new A;
 | |
| }
 | |
| 
 | |
| void bar (RefCountedPtr <A> a)
 | |
| {
 | |
|   a->foo ();
 | |
| }
 | |
| 
 | |
| void callFoo ()
 | |
| {
 | |
|   bar (createA ());
 | |
| 
 | |
|   // The created A will be destroyed
 | |
|   // when we leave this scope
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h3>3.4.3 - <span id="s3.4.3">User-defined Containers</span></h3>
 | |
| 
 | |
| <p>
 | |
| If you have your own container, you must provide a specialization of
 | |
| <code>ContainerTraits</code> in the <code>luabridge</code> namespace for your
 | |
| type before it will be recognized by LuaBridge (or else the code will not
 | |
| compile):
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| template <class T>
 | |
| struct ContainerTraits <CustomContainer <T> >
 | |
| {
 | |
|   typedef typename T Type;
 | |
| 
 | |
|   static T* get (CustomContainer <T> const& c)
 | |
|   {
 | |
|     return c.getPointerToObject ();
 | |
|   }
 | |
| };
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Standard containers like <code>std::shared_ptr</code> or
 | |
| <code>boost::shared_ptr</code> <b>will not work</b>. This is because of type
 | |
| erasure; when the object goes from C++ to Lua and back to C++, there is no
 | |
| way to associate the object with the original container. The new container is
 | |
| constructed from a pointer to the object instead of an existing container.
 | |
| The result is undefined behavior since there are now two sets of reference
 | |
| counts.
 | |
| </p>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h3>3.4.4 - <span id="s3.4.4">Container Constructors</span></h3>
 | |
| 
 | |
| <p>
 | |
| When a constructor is registered for a class, there is an additional
 | |
| optional second template parameter describing the type of container to use.
 | |
| If this parameter is specified, calls to the constructor will create the
 | |
| object dynamically, via operator new, and place it a container of that
 | |
| type. The container must have been previously specialized in
 | |
| <code>ContainerTraits</code>, or else a compile error will result. This code
 | |
| will register two objects, each using a constructor that creates an object
 | |
| with Lua lifetime using the specified container:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| class C : public RefCountedObject
 | |
| {
 | |
|   C () { }
 | |
| };
 | |
| 
 | |
| class D
 | |
| {
 | |
|   D () { }
 | |
| };
 | |
| 
 | |
| getGlobalNamespace (L)
 | |
|   .beginNamespace ("test")
 | |
|     .beginClass <C> ("C")
 | |
|       .addConstructor <void (*) (void), RefCountedObjectPtr <C> > ()
 | |
|     .endClass ()
 | |
|     .beginClass <D> ("D")
 | |
|       .addConstructor <void (*) (void), RefCountedPtr <D> > ()
 | |
|     .endClass ();
 | |
|   .endNamespace ()
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>3.5 - <span id="s3.5">Mixing Lifetimes</span></h2>
 | |
| 
 | |
| <p>
 | |
| Mixing object lifetime models is entirely possible, subject to the usual
 | |
| caveats of holding references to objects which could get deleted. For
 | |
| example, C++ can be called from Lua with a pointer to an object of class
 | |
| type; the function can modify the object or call non-const data members.
 | |
| These modifications are visible to Lua (since they both refer to the same
 | |
| object). An object store in a container can be passed to a function expecting
 | |
| a pointer. These conversion work seamlessly.
 | |
| <p>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>3.6 - <span id="s3.6">Convenience Functions</span></h2>
 | |
| 
 | |
| <p>
 | |
| The <code>setGlobal</code> function can be used to assign any convertible
 | |
| value into a global variable. 
 | |
| </p>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h1>4 - <span id="s4">Accessing Lua from C++</span></h1>
 | |
| 
 | |
| <p>
 | |
| Because Lua is a <em>dynamically typed language</em>, special consideration
 | |
| is required to map values in Lua to C++. The following sections describe the
 | |
| classes and functions used for representing Lua types. Only the essential
 | |
| operations are explained; To gain understanding of all available functions,
 | |
| please refer to the documentation comments in the corresponding source files.
 | |
| </p>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>4.1 - <span id="s4.1">Class LuaRef</span></h2>
 | |
| 
 | |
| <p>
 | |
| The <code>LuaRef</code> class is a container which references any Lua type.
 | |
| It can hold anything which a Lua variable can hold: <strong>nil</strong>,
 | |
| number, boolean, string, table, function, thread, userdata, and
 | |
| lightuserdata. Because <code>LuaRef</code> uses the <code>Stack</code>
 | |
| template specializations to do its work, classes, functions, and data
 | |
| exported to Lua through namespace registrations can also be stored (these
 | |
| are instances of userdata). In general, a <code>LuaRef</code> can represent
 | |
| any <em>convertible</em> C++ type as well as all Lua types.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| A <code>LuaRef</code> variable constructed with no parameters produces a
 | |
| reference to <strong>nil</strong>:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| LuaRef v (L); // References nil
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| To construct a <code>LuaRef</code> to a specific value, the two parameter
 | |
| constructor is used:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| LuaRef v1 (L, 1);                   // A LUA_TNUMBER
 | |
| LuaRef v2 (L, 1.1);                 // Also a LUA_TNUMBER
 | |
| LuaRef v3 (L, true);                // A LUA_TBOOLEAN
 | |
| LuaRef v4 (L, "string");            // A LUA_TSTRING
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| The functions <code>newTable</code> and <code>getGlobal</code> create
 | |
| references to new empty table and an existing value in the global table
 | |
| respectively:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| LuaRef v1 = newTable (L);           // Create a new table
 | |
| LuaRef v2 = getGlobal (L, "print")  // Reference to _G ["print"]
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| A <code>LuaRef</code> can hold classes <em>registered</em> using LuaBridge:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| class A;
 | |
| //...
 | |
| LuaRef v (L, new A); // A LuaBridge userdata holding a pointer to A
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Any convertible type may be assigned to an already-existing <code>LuaRef</code>:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| LuaRef v (L);         // Nil
 | |
| v = newTable (L);     // An empty table
 | |
| v = "string"          // A string. The prevous value becomes
 | |
|                       // eligible for garbage collection.
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| A <code>LuaRef</code> is itself a convertible type, and the convertible
 | |
| type <code>Nil</code> can be used to represent a Lua <strong>nil</strong>.
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| LuaRef v1 (L, "x");   // assign "x"
 | |
| LuaRef v2 (L, "y");   // assign "y"
 | |
| v2 = v1;              // v2 becomes "x"
 | |
| v1 = "z";             // v1 becomes "z", v2 is unchanged
 | |
| v1 = newTable (L);    // An empty table
 | |
| v2 = v1;              // v2 references the same table as v1
 | |
| v1 = Nil ();          // v1 becomes nil, table is still
 | |
|                       // referenced by v2.
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Values stored in a <code>LuaRef</code> object obey the same rules as
 | |
| variables in Lua: tables, functions, threads, and full userdata values are
 | |
| <em>objects</em>. The <code>LuaRef</code> does not actually <em>contain</em>
 | |
| these values, only <em>references</em> to them. Assignment, parameter
 | |
| passing, and function returns always manipulate references to such values;
 | |
| these operations do not imply any kind of copy.
 | |
| </p>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h3>4.1.1 - <span id="s4.1.1">Type Conversions</span></h3>
 | |
| 
 | |
| <p>
 | |
| A universal C++ conversion operator is provided for implicit conversions
 | |
| which allow a <code>LuaRef</code> to be used where any convertible type is
 | |
| expected. These operations will all compile:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| void passInt (int);
 | |
| void passBool (bool);
 | |
| void passString (std::string);
 | |
| void passObject (A*);
 | |
| 
 | |
| LuaRef v (L);
 | |
| //...
 | |
| passInt (v);        // implicit conversion to int
 | |
| passBool (v);       // implicit conversion to bool
 | |
| passString (v);     // implicit conversion to string
 | |
| passObject (v);     // must hold a registered LuaBridge class or a
 | |
|                     // lua_error() will be called.
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Since Lua types are dynamic, the conversion is performed at run time using
 | |
| traditional functions like <code>lua_toboolean</code> or
 | |
| <code>lua_tostring</code>. In some cases, the type information may be
 | |
| incorrect especially when passing objects of registered class types.
 | |
| When performing these conversions, LuaBridge may raise a Lua error by
 | |
| directly or indirectly calling <code>lua_error</code> To be bullet-proof,
 | |
| such code must either be wrapped in a <code>lua_pcall</code>, or you must
 | |
| install a Lua <em>panic function</em> that throws an exception which you
 | |
| can catch.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| When an explicit conversion is required (such as when writing templates),
 | |
| use the <code>cast</code> template function or an explicit C++ style cast.
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| void passString (std::string);
 | |
| 
 | |
| LuaRef v (L);
 | |
| 
 | |
| // The following are all equivalent:
 | |
| 
 | |
| passString (std::string (v));
 | |
| passString ((std::string)v);
 | |
| passString (static_cast <std::string> (v));
 | |
| passString (v.cast <std::string> ());
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h3>4.1.2 - <span id="s4.1.2">Visual Studio 2010, 2012</span></h3>
 | |
| 
 | |
| <p>
 | |
| There is a defect with all versions of Visual Studio up to and including
 | |
| Visual Studio 2012 which prevents the implicit conversion operator from
 | |
| being applied when it is used as an operand in a boolean operator:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| LuaRef v1 (L);
 | |
| LuaRef v2 (L);
 | |
| 
 | |
| if (v1 || v2) { } // Compile error in Visual Studio
 | |
| 
 | |
| // Work-arounds:
 | |
| if (v1.cast <bool> () || v2.cast <bool> ()) { }
 | |
| if (bool (v1) || bool (v2)) { }
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>4.2 - <span id="s4.2">Table Proxies</span></h2>
 | |
| 
 | |
| <p>
 | |
| As tables are the sole data structuring mechanism in Lua, the
 | |
| <code>LuaRef</code> class provides robust facilities for accessing and
 | |
| manipulating table elements using a simple, precise syntax. Any convertible
 | |
| type may be used as a key or value. Applying the array indexing operator
 | |
| <code>[]</code> to a <code>LuaRef</code> returns a special temporary object
 | |
| called a <em>table proxy</em> which supports all the operations which can
 | |
| be performed on a <code>LuaRef</code>. In addition, assignments made to
 | |
| table proxies change the underlying table. Because table proxies are
 | |
| compiler-created temporary objects, you don't work with them directly. A
 | |
| LuaBridge table proxy should not be confused with the Lua proxy table
 | |
| technique described in the book "Programming in Lua"; the LuaBridge table
 | |
| proxy is simply an intermediate C++ class object that works behind the
 | |
| scenes to make table manipulation syntax conform to C++ idioms. These
 | |
| operations all invoke table proxies:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| LuaRef v (L);
 | |
| v = newTable (L);
 | |
| 
 | |
| v ["name"] = "John Doe";      // string key, string value
 | |
| v [1] = 200;                  // integer key, integer value
 | |
| v [2] = newTable (L);         // integer key, LuaRef value
 | |
| v [3] = v [1];                // assign 200 to integer index 3
 | |
| v [1] = 100;                  // v[1] is 100, v[3] is still 200
 | |
| v [3] = v [2];                // v[2] and v[3] reference the same table
 | |
| v [2] = Nil ();               // Removes the value with key = 2. The table
 | |
|                               //   is still referenced by v[3].
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h2>4.3 - <span id="s4.3">Calling Lua</span></h2>
 | |
| 
 | |
| <p>
 | |
| Table proxies and <code>LuaRef</code> objects provide a convenient syntax
 | |
| for invoking <code>lua_pcall</code> on suitable referenced object. This
 | |
| includes C functions, Lua functions, or Lua objects with an appropriate
 | |
| <code>__call</code> metamethod set. The provided implementation supports
 | |
| up to eight parameters (although more can be supported by adding new
 | |
| functions). Any convertible C++ type can be passed as a parameter in its
 | |
| native format. The return value of the function call is provided as a
 | |
| <code>LuaRef</code>, which may be <strong>nil</strong>.
 | |
| </p>
 | |
| 
 | |
| <pre class="split">
 | |
| LuaRef same = getGlobal (L, "same");
 | |
| 
 | |
| // These all evaluate to true
 | |
| same (1,1);
 | |
| !same (1,2);
 | |
| same ("text", "text");
 | |
| !same (1, "text");
 | |
| same (1, 1, 2); // third param ignored
 | |
| </pre>
 | |
| 
 | |
| <pre class="split">
 | |
| function same (arg1, arg)
 | |
|   return arg1 == arg2
 | |
| end
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Table proxies support all of the Lua call notation that <code>LuaRef</code>
 | |
| supports, making these statements possible:
 | |
| </p>
 | |
| 
 | |
| <pre class="split">
 | |
| LuaRef v = getGlobal (L, "t");
 | |
| 
 | |
| t[1]();
 | |
| t[2]("a", "b");
 | |
| t[2](t[1]); // Call t[3] with the value in t[2]
 | |
| t[4]=t[3]();   // Call t[3] and store the result in t[4].
 | |
| 
 | |
| t [t[5]()] = "wow"; // Store "wow" at the key returned by
 | |
|                     //   the call to t[5]
 | |
| </pre>
 | |
| 
 | |
| <pre class="split">
 | |
| t = {}
 | |
| t[1] = function () print ("hello") end
 | |
| t[2] = function (u, v) print (u, v) end
 | |
| t[3] = "foo"
 | |
| </pre>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| <h3>4.3.1 - <span id="s4.3.1">Class LuaException</span></h3>
 | |
| 
 | |
| <section >
 | |
| 
 | |
| <p>
 | |
| When <code>LuaRef</code> is used to call into Lua using the <code>()</code>
 | |
| operator it issues a protected call using <code>lua_pcall</code>. LuaBridge
 | |
| uses the C++ exception handling mechanism, throwing a <code>LuaException</code>
 | |
| object:
 | |
| </p>
 | |
| 
 | |
| <pre class="split">
 | |
| LuaRef f (L) = getGlobal (L, "fail");
 | |
| 
 | |
| try {
 | |
|   f ();
 | |
| }
 | |
| catch (LuaException const& e) {
 | |
|   std::cerr && e.what ();
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <pre class="split">
 | |
| function fail ()
 | |
|   error ("A problem occurred")
 | |
| end
 | |
| </pre>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <section>
 | |
| 
 | |
| <h1>5 - <span id="s5">Security</span></h1>
 | |
| 
 | |
| <p>
 | |
| The metatables and userdata that LuaBridge creates in the `lua_State*` are
 | |
| protected using a security system, to eliminate the possibility of undefined
 | |
| behavior resulting from scripted manipulation of the environment. The
 | |
| security system has these components:
 | |
| </p>
 | |
| 
 | |
| <ul class="bullets">
 | |
| <li>
 | |
| Class and const class tables use the <em>table proxy</em> technique. The
 | |
| corresponding metatables have <code>__index</code> and <code>__newindex</code>
 | |
| metamethods, so these class tables are immutable from Lua.
 | |
| <li>
 | |
| Metatables have <code>__metatable</code> set to a boolean value. Scripts
 | |
| cannot obtain the metatable from a LuaBridge object.
 | |
| <li>
 | |
| Classes are mapped to metatables through the registry, which Lua scripts
 | |
| cannot access. The global environment does not expose metatables
 | |
| <li>
 | |
| Metatables created by LuaBridge are tagged with a lightuserdata key which
 | |
| is unique in the process. Other libraries cannot forge a LuaBridge
 | |
| metatable.
 | |
| </ul>
 | |
| 
 | |
| <p>
 | |
| This security system can be easily bypassed if scripts are given access to
 | |
| the debug library (or functionality similar to it, i.e. a raw `getmetatable`).
 | |
| The security system can also be defeated by C code in the host, either by
 | |
| revealing the unique lightuserdata key to another module or by putting a
 | |
| LuaBridge metatable in a place that can be accessed by scripts.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| When a class member function is called, or class property member accessed,
 | |
| the `this` pointer is type-checked. This is because member functions exposed
 | |
| to Lua are just plain functions that usually get called with the Lua colon
 | |
| notation, which passes the object in question as the first parameter. Lua's
 | |
| dynamic typing makes this type-checking mandatory to prevent undefined
 | |
| behavior resulting from improper use.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| If a type check error occurs, LuaBridge uses the <code>lua_error</code>
 | |
| mechanism to trigger a failure. A host program can always recover from
 | |
| an error through the use of <code>lua_pcall</code>; proper usage of
 | |
| LuaBridge will never result in undefined behavior.
 | |
| </p>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <!--========================================================================-->
 | |
| 
 | |
| </body>
 | |
| </html>
 | |
| 
 |