From e1cdfd27cad943290a0233119548a8dd8876bd52 Mon Sep 17 00:00:00 2001 From: Andy Belle-Isle Date: Thu, 29 Aug 2019 20:02:35 -0400 Subject: Replaced LuaBridge with sol2 and completely encapsulated scripting within script system --- lib/LuaBridge/Manual.html | 1897 --------------------------------------------- 1 file changed, 1897 deletions(-) delete mode 100644 lib/LuaBridge/Manual.html (limited to 'lib/LuaBridge/Manual.html') diff --git a/lib/LuaBridge/Manual.html b/lib/LuaBridge/Manual.html deleted file mode 100644 index 69f7ba9..0000000 --- a/lib/LuaBridge/Manual.html +++ /dev/null @@ -1,1897 +0,0 @@ - - - -LuaBridge 2.3 Reference Manual - - - - - - - - - - - -
-
-

LuaBridge 2.3 Reference Manual

-
-
- - -Official repository is located at -https://github.com/vinniefalco/LuaBridge. -
-Copyright © 2012 Vinnie Falco. Freely available under the terms of the -MIT License. -
- - - - - -
- -

1 - Introduction

- -

-LuaBridge is a -lightweight and dependency-free library for mapping data, functions, and -classes back and forth between C++ and Lua, -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 LuaJIT. -

- -

-LuaBridge offers the following features: -

- - - -

-LuaBridge is distributed as a a collection of header files. You simply add -one line, #include "LuaBridge/LuaBridge.h" 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. -

- -

-C++ concepts like variables and classes are made available to Lua through a -process called registration. 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. -

- -

-To expose Lua objects to C++, a class called LuaRef 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. -

- - - -
- -

1.1 - Design

- -

-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. -

- -

-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, -OOLua slightly outperforms -LuaBridge in some tests. LuaBridge also does not try to implement every -possible feature, -LuaBind -explores every corner of the C++ language (but it requires Boost). -

- -

-LuaBridge does not support: -

- -
    -
  • Enumerated constants -
  • More than 8 parameters on a function or method (although this can be - increased by adding more TypeListValues specializations). -
  • Overloaded functions, methods, or constructors. -
  • Global variables (variables must be wrapped in a named scope). -
  • Automatic conversion between STL container types and Lua tables - (conversion can be enabled for std::list, std::vector, - std::map or std::unordered_map by including - List.h, Vector.h, Map or - UnorderedMap.h respectively) -
  • Inheriting Lua classes from C++ classes. -
  • Passing nil to a C++ function that expects a pointer or reference. -
  • Standard containers like std::shared_ptr. -
- -
- - - -
- -

1.2 - Repository

- -

-The official repository is located at -https://github.com/vinniefalco/LuaBridge. -The branches are organized as follows: -

- - - - - - - - - - - - - - -
masterTagged, stable release versions.
releaseA temporarily created branch that holds a release candidate for review.
developContains work in progress, possibly unfinished or with bugs.
- -

-These repositories are also available: -

- - - - - - - - - - -
LuaBridgeUnitTestsA stand alone command line application to exercise LuaBridge functionality.
LuaBridgeUnitDemoA stand alone GUI application that provides an interactive console.
- -
- - - -
- -

1.3 - License and Credits

- -

-LuaBridge is published under the terms of the -MIT License: -

- -
-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.
-
- -

-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 LuaRef and -other Lua to C++ binding contributions from Nigel Atkinson. -

- -

-For questions, comments, or bug reports feel free to open a Github issue -or contact Vinnie Falco directly at the email address indicated below. -

- - - -

-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. -

- -
- - - -
- -
- -

2 - Accessing C++ from Lua

- -

-In order to expose C++ data and functions to Lua, each piece of exported -information must be registered. There are five types of objects that -LuaBridge can register: -

- - - - - - - - - - - - - - - - - - - - - - -
Namespaces  A Lua table that contains other registrations.
Data  Global or static variables, data members, and static data members.
Functions  Regular functions, member functions, and static member functions.
CFunctions  A regular function, member function, or static member function that - uses the lua_CFunction calling convention.
Properties  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.
- -

-Both data and properties can be marked as read-only at the time of -registration. This is different from const; 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 -lua_State* L is defined, and that a using namespace luabridge -using-directive is in effect. -

- - - -
- -

2.1 - Namespaces

- -

-All LuaBridge registrations take place in a namespace. When we refer -to a namespace 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: -

- -
-getGlobalNamespace (L);
-
- -

-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: -

- -
-getGlobalNamespace (L)
-  .beginNamespace ("test");
-
- -

-This creates a table in _G 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 __test would be an invalid name -(although LuaBridge will silently accept it). Functions like -beginNamespace return the corresponding object on which we can -make more registrations. Given: -

- -
-getGlobalNamespace (L)
-  .beginNamespace ("test")
-    .beginNamespace ("detail")
-    .endNamespace ()
-    .beginNamespace ("utility")
-    .endNamespace ()
-  .endNamespace ();
-
- -

-The results are accessible to Lua as test, test.detail, -and test.utility. Here we introduce the endNamespace -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). -

- -

-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: -

- -
-getGlobalNamespace (L)
-  .beginNamespace ("test")
-    .addFunction ("foo", foo)
-  .endNamespace ();
-
-getGlobalNamespace (L)
-  .beginNamespace ("test")
-    .addFunction ("bar", bar)
-  .endNamespace ();
-
- -

-and -

- -
-getGlobalNamespace (L)
-  .beginNamespace ("test")
-    .addFunction ("foo", foo)
-    .addFunction ("bar", bar)
-  .endNamespace ();
-
- -
- - - -
- -

2.2 - Properties and Functions

- -

-These are registered into a namespace using addProperty -and addFunction. -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: -

- -
-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; }
-
- -

-These are registered with: -

- -
-getGlobalNamespace (L)
-  .beginNamespace ("test")
-    .addProperty ("var1", &globalVar)
-    .addProperty ("var2", &staticVar, false) // read-only
-    .addProperty ("prop1", getString, setString)
-    .addProperty ("prop2", getString)            // read only
-    .addFunction ("foo", foo)
-    .addFunction ("bar", bar)
-    .addFunction ("cfunc", cFunc)
-  .endNamespace ();
-
- -

-Variables can be marked read-only by passing false in -the second optional parameter. If the parameter is omitted, true 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: -

- -
-test        -- a namespace
-test.var1   -- a lua_Number property
-test.var2   -- a read-only lua_Number property
-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
-
- -

-Note that test.prop1 and test.prop2 both refer to the -same value. However, since test.prop2 is read-only, assignment -attempts will generate a run-time error. These Lua statements have the stated effects: -

- -
-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
-
- -

-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. -

- -
- - - -
- -

2.3 - Class Objects

- -

-A class registration is opened using either beginClass or -deriveClass and ended using endClass. Once -registered, a class can later be re-opened for more registrations using -beginClass. However, deriveClass should only be -used once. To add more registrations to an already registered derived class, -use beginClass on it. -

-

-These declarations: -

- -
-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 (lua_State *L) { return 0; }
-
-  std::string dataMember;
-
-  char dataProperty;
-  char getProperty () const { return dataProperty; }
-  void setProperty (char v) { dataProperty = v; }
-  std::string toString () const { return dataMember; }
-
-  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;
-
- -

-are registered using: -

- -
-getGlobalNamespace (L)
-  .beginNamespace ("test")
-    .beginClass <A> ("A")
-      .addStaticProperty ("staticData", &A::staticData)
-      .addStaticProperty ("staticProperty", &A::getStaticProperty, &A::setStaticProperty)
-      .addStaticFunction ("staticFunc", &A::staticFunc)
-      .addStaticFunction ("staticCFunc", &A::staticCFunc)
-      .addProperty ("data", &A::dataMember)
-      .addProperty ("prop", &A::getProperty, &A::setProperty)
-      .addFunction ("func1", &A::func1)
-      .addFunction ("virtualFunc", &A::virtualFunc)
-      .addFunction ("__tostring", &A::toString)     // Metamethod
-      .addFunction ("cfunc", &A::cfunc)
-    .endClass ()
-    .deriveClass <B, A> ("B")
-      .addProperty ("data", &B::dataMember2)
-      .addFunction ("func1", &B::func1)
-      .addFunction ("func2", &B::func2)
-    .endClass ()
-  .endNameSpace ();
-
- -

-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. -It is possible to register Lua metamethods (except __gc). -Destructors are registered automatically for each class. -

- -

-As with regular variables and properties, class properties can be -marked read-only by passing false in the second parameter, or omitting the set -set function. 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. -

- -

-Remember that in Lua, the colon operator ':' is used for -method call syntax: -

- -
-local a = A ()
-
-a.func1 ()  -- error: func1 expects an object of a registered class
-a.func1 (a) -- okay, verbose, this how OOP works in Lua
-a:func1 ()  -- okay, less verbose, equvalent to the previous
-
- -
- - - -
- -

2.4 - Property Member Proxies

- -

-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 property member proxy. 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: -

- -
-// Third party declaration, can't be changed
-struct Vec
-{
-  float coord [3];
-};
-
- -

-Taking the address of an array element, e.g. &Vec::coord [0] -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: -

- -
-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;
-  }
-};
-
- -

-This helper class is only used to provide property member proxies. -Vec continues to be used in the C++ code as it was before. -Now we can register the Vec class with property member proxies for -x, y, and z: -

- -
-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 ();
-
- -

-With a C++11 compilant compiler it is possible to use std::function -instances as proxies: -

- -
-getGlobalNamespace (L)
-  .beginNamespace ("test")
-    .beginClass <Vec> ("Vec")
-      .addProperty ("x",
-        std::function <float (const Vec*)> (
-          [] (const Vec* vec) {return vec->coord [0];}),
-        std::function <void (Vec*, float)> (
-          [] (Vec* vec, float v) {vec->coord [0] = v;}))
-      // ... same for "y" and "z"
-    .endClass ()
-  .endNamespace ();
-
- -
- - - -
- -

2.5 - Function Member Proxies

- -

-Where it is not possible or inconvenient to add a member to be registered, -LuaBridge also allows for a function member proxy. This is a flat -function which take as its first parameter a pointer to the object: -

- -
-// Third party declaration, can't be changed
-struct Vec
-{
-  float coord [3];
-};
-
- -

-The class is closed for modifications, but we want to extend Vec objects -with our member function. To do this, first we add a "helper" function: -

- -
-void scale (float value)
-{
-  value->coord [0] *= value;
-  value->coord [1] *= value;
-  value->coord [2] *= value;
-};
-
- -

-Now we can register the Vec class with a member function -scale: -

- -
-getGlobalNamespace (L)
-  .beginNamespace ("test")
-    .beginClass <Vec> ("Vec")
-      .addFunction ("scale", &scale)
-    .endClass ()
-  .endNamespace ();
-
- -

-With a C++11 compilant compiler it is possible to use std::function -instances as proxies: -

- -
-getGlobalNamespace (L)
-  .beginClass <Vec> ("Vec")
-    .addFunction ("scaleX",
-      std::function <void (Vec*, float)> (
-        [] (Vec* vec, float v) {vec->coord [0] *= v;}))
-  .endClass ()
-
- -
- - - -
- -

2.6 - Constructors

- -

-A single constructor may be added for a class using addConstructor. -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 addConstructor. The parameter -types will be extracted from this (the return type is ignored). For example, -these statements register constructors for the given classes: -

- -
-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 ();
-
- -

-Constructors added in this fashion are called from Lua using the fully -qualified name of the class. This Lua code will create instances of -A and B. -

- -
-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
-
- -
- - - -
- -

2.7 - Lua Stack

- -

-In the Lua C API, all operations on the lua_State 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: -

- -
-template <class T>
-struct Stack
-{
-  static void push (lua_State* L, T t);
-  static T get (lua_State* L, int index);
-};
-
- -

-When a specialization of Stack exists for a given type -T we say that the T is convertible. -Throughout this document and the LuaBridge API, these types can be used -anywhere a convertible type is expected. -

- -

-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: -

- -
    -
  • bool -
  • char, converted to a string of length one. -
  • char const* and std::string strings. -
  • Integers, float, and double, - converted to Lua_number. -
- -

-User-defined types which are convertible to one of the basic types are -possible, simply provide a Stack<> specialization in the -luabridge namespace for your user-defined type, modeled after -the existing types. For example, here is a specialization for a -juce::String: -

- -
-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));
-  }
-};
-
- -
- - - -
- -

2.8 - lua_State

- -

-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: -

- -
-void useState (lua_State* L);
-
-getGlobalNamespace (L).addFunction ("useState", &useState);
-
- -

-You can still include regular arguments while receiving the state: -

- -
-void useStateAndArgs (int i, std::string s, lua_State* L);
-
-getGlobalNamespace (L).addFunction ("useStateAndArgs", &useStateAndArgs);
-
- -

-When the script calls useStateAndArgs, it passes only the integer -and string parameters. LuaBridge takes care of inserting the lua_State* -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 lua_State* is not the last parameter. -

- -

-The same is applicable for properies. -

- -
- - - -
- -
- -

3 - Passing Objects

- -

-An object of a registered class T may be passed to Lua as: -

- - - - - - - - - - - - - - - - - - - - - - - - - - -
TPassed by value (a copy), with Lua lifetime.
T constPassed by value (a copy), with Lua lifetime.
T*Passed by reference, with C++ lifetime.
T&Passed by reference, with C++ lifetime.
T const*Passed by const reference, with C++ lifetime.
T const&Passed by const reference, with C++ lifetime.
- - - -
- -

3.1 - C++ Lifetime

- -

-The creation and deletion of objects with C++ lifetime 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 lua_State*, or else -undefined behavior results. In the previous examples, an instance of A -can be passed to Lua with C++ lifetime, like this: -

- -
-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");
-
- -
- - - -
- -

3.2 - Lua Lifetime

- -

-When an object of a registered class is passed by value to Lua, it will have -Lua lifetime. 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 B -can be passed to Lua with Lua lifetime this way: -

- -
-B b;
-
-push (L, b);                    // Copy of b passed, Lua lifetime.
-lua_setglobal (L, "b");
-
- -

-Given the previous code segments, these Lua statements are applicable: -

- -
-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.
-
- -

-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. -

- -
- - - -
- -

3.3 - Pointers, References, and Pass by Value

- -

-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: -

- -
-void func0 (A a);
-void func1 (A* a);
-void func2 (A const* a);
-void func3 (A& a);
-void func4 (A const& a);
-
- -

-Executing this Lua code will have the prescribed effect: -

- -
-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.
-
- -

-In the example above, all functions can read the data members and property -members of a, or call const member functions of a. -Only func0, func1, and func3 can -modify the data members and data properties, or call non-const member -functions of a. -

- -

-The usual C++ inheritance and pointer assignment rules apply. Given: -

- -
-void func5 (B b);
-void func6 (B* b);
-
- -

-These Lua statements hold: -

- -
-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.
-
- -

-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 -nil 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 lua_error being called. -

- -
- - - -
- -

3.4 - Shared Lifetime

- -

-LuaBridge supports a shared lifetime 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 ContainerTraits -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. -

- - - -
- -

3.4.1 - Class RefCountedObjectPtr

- -

-This is an intrusive style container. Your existing class declaration must be -changed to be also derived from RefCountedObject. Given -class T, derived from RefCountedObject, the container -RefCountedObjectPtr <T> 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 -std::shared_ptr although there are slight differences. For -example: -

- -
-// 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 ();
-}
-
- -
- - - -
- -

3.4.2 - Class RefCountedPtr

- -

-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: -

- -
-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
-}
-
- -
- - - -
- -

3.4.3 - User-defined Containers

- -

-If you have your own container, you must provide a specialization of -ContainerTraits in the luabridge namespace for your -type before it will be recognized by LuaBridge (or else the code will not -compile): -

- -
-template <class T>
-struct ContainerTraits <CustomContainer <T> >
-{
-  typedef typename T Type;
-
-  static T* get (CustomContainer <T> const& c)
-  {
-    return c.getPointerToObject ();
-  }
-};
-
- -

-Standard containers like std::shared_ptr or -boost::shared_ptr will not work. 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. -

- -
- - - -
- -

3.4.4 - Container Constructors

- -

-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 -ContainerTraits, 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: -

- -
-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 ()
-
- -
- - - -
- -
- -

3.5 - Mixing Lifetimes

- -

-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. -

- -

- - - -
- -

3.6 - Convenience Functions

- -

-The setGlobal function can be used to assign any convertible -value into a global variable. -

- -
- - - -
- -
- -

4 - Accessing Lua from C++

- -

-Because Lua is a dynamically typed language, 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. -

- - - -
- -

4.1 - Class LuaRef

- -

-The LuaRef class is a container which references any Lua type. -It can hold anything which a Lua variable can hold: nil, -number, boolean, string, table, function, thread, userdata, and -lightuserdata. Because LuaRef uses the Stack -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 LuaRef can represent -any convertible C++ type as well as all Lua types. -

- -

-A LuaRef variable constructed with no parameters produces a -reference to nil: -

- -
-LuaRef v (L); // References nil
-
- -

-To construct a LuaRef to a specific value, the two parameter -constructor is used: -

- -
-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
-
- -

-The functions newTable and getGlobal create -references to new empty table and an existing value in the global table -respectively: -

- -
-LuaRef v1 = newTable (L);           // Create a new table
-LuaRef v2 = getGlobal (L, "print")  // Reference to _G ["print"]
-
- -

-A LuaRef can hold classes registered using LuaBridge: -

- -
-class A;
-//...
-LuaRef v (L, new A); // A LuaBridge userdata holding a pointer to A
-
- -

-Any convertible type may be assigned to an already-existing LuaRef: -

- -
-LuaRef v (L);         // Nil
-v = newTable (L);     // An empty table
-v = "string"          // A string. The prevous value becomes
-                      // eligible for garbage collection.
-
- -

-A LuaRef is itself a convertible type, and the convertible -type Nil can be used to represent a Lua nil. -

- -
-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.
-
- -

-Values stored in a LuaRef object obey the same rules as -variables in Lua: tables, functions, threads, and full userdata values are -objects. The LuaRef does not actually contain -these values, only references to them. Assignment, parameter -passing, and function returns always manipulate references to such values; -these operations do not imply any kind of copy. -

- - - -
- -

4.1.1 - Type Conversions

- -

-A universal C++ conversion operator is provided for implicit conversions -which allow a LuaRef to be used where any convertible type is -expected. These operations will all compile: -

- -
-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.
-
- -

-Since Lua types are dynamic, the conversion is performed at run time using -traditional functions like lua_toboolean or -lua_tostring. 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 lua_error To be bullet-proof, -such code must either be wrapped in a lua_pcall, or you must -install a Lua panic function that throws an exception which you -can catch. -

- -

-When an explicit conversion is required (such as when writing templates), -use the cast template function or an explicit C++ style cast. -

- -
-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> ());
-
- -
- - - -
- -

4.1.2 - Visual Studio 2010, 2012

- -

-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: -

- -
-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)) { }
-
- -
- - - -
- -
- -

4.2 - Table Proxies

- -

-As tables are the sole data structuring mechanism in Lua, the -LuaRef 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 -[] to a LuaRef returns a special temporary object -called a table proxy which supports all the operations which can -be performed on a LuaRef. 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: -

- -
-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].
-
- -
- - - -
- -

4.3 - Calling Lua

- -

-Table proxies and LuaRef objects provide a convenient syntax -for invoking lua_pcall on suitable referenced object. This -includes C functions, Lua functions, or Lua objects with an appropriate -__call 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 -LuaRef, which may be nil. -

- -
-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
-
- -
-function same (arg1, arg)
-  return arg1 == arg2
-end
-
- -

-Table proxies support all of the Lua call notation that LuaRef -supports, making these statements possible: -

- -
-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]
-
- -
-t = {}
-t[1] = function () print ("hello") end
-t[2] = function (u, v) print (u, v) end
-t[3] = "foo"
-
- - - -

4.3.1 - Class LuaException

- -
- -

-When LuaRef is used to call into Lua using the () -operator it issues a protected call using lua_pcall. LuaBridge -uses the C++ exception handling mechanism, throwing a LuaException -object: -

- -
-LuaRef f (L) = getGlobal (L, "fail");
-
-try {
-  f ();
-}
-catch (LuaException const& e) {
-  std::cerr && e.what ();
-}
-
- -
-function fail ()
-  error ("A problem occurred")
-end
-
- -
- - - -
- - - -
- -
- -

5 - Security

- -

-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: -

- - - -

-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. -

- -

-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. -

- -

-If a type check error occurs, LuaBridge uses the lua_error -mechanism to trigger a failure. A host program can always recover from -an error through the use of lua_pcall; proper usage of -LuaBridge will never result in undefined behavior. -

- -
- - - - - - -- cgit v1.2.3