O'Reilly logo

Programming Game AI by Example by Mat Buckland

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Ü
NOTE Unlike C++, Lua handles memory management automatically. It uses
something called a garbage collector to periodically delete all the dead objects.
The performance of the garbage collector can be customized to your taste,
ranging from immediate deletion of dead objects to no deletion. See the Lua
documentation for further details.
Exposing a C/C++ Class to Lua
This is where things start to get tricky! Exposing a C++ class to a Lua
script can be pretty gnarly. You basically have to create a Lua table that has
as its elements the class data and methods you require to expose. You may
also have to create a metatable that defines how your class behaves with
any appropriate operators such as == or *. As you have seen, simply expos
-
ing a C-like function to Lua can get longwinded, so you can imagine the
amount of work required to expose a C++ class. Fortunately, someone has
already done the hard work for us and created an API allowing for
pain-free class (and function) registration. It’s called Luabind, and just like
Lua it’s free, open-source, and easy to use and understand.
Luabind to the Rescue!
Luabind is a library for creating bindings between Lua and C++. It is
implemented using the magic of template meta-programming so the source
code is not for the faint hearted, but it makes exposing your C/C++ classes
and functions a cinch. It handles inheritance and templated classes and you
can even use it to create classes in Lua. It’s still in the early days of devel-
opment, so it is not without its problems, but these are few and the
developers, Daniel Wallin and Arvid Norberg, have put in a lot of time to
iron out the bugs and to provide fast and helpful support should you need
it.
Setting Up Luabind
Before you can use Luabind you must set up your compiler correctly.
Luabind (6.0) requires you to have the Boost library 1.30.0 or later headers
installed. You can download Boost from www.boost.org. Unzip and add the
boost header folder to your compilers include paths.
The required files for Luabind are in the folder common/luabind. You
must set this path in your compiler for the Luabind headers, and the path
common/luabind/src for the source files. Although you can build the
Luabind libraries, it’s much easier (unless you are using UNIX) to just
include all the files found in common/luabind/src in your project.
z
TIP For those of you who use .NET, there is a Lua and Luabind .NET wrapper
called LuaDotNet available from codeproject. You can grab it from:
http://www.codeproject.com/managedcpp/luanetwrapper.asp.
276 | Chapter 6
Scripting in Lua
To use Luabind you must include the Luabind header along with the Lua
files, and then call the function
luabind::open(lua_State*). This registers
all the functions Luabind uses to expose your classes and functions.
You eventually end up with code that flows like this:
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include <luabind/luabind.hpp>
int main()
{
//create a lua state
lua_State* pLua = lua_open();
//open luabind
luabind::open(pLua);
/* Register functions and classes with luabind here */
/* load and run the script here */
//tidy up
lua_close(pLua);
return 0;
}
Now let me show you how easy Luabind is to use.
Scopes
Any function or class you register using Luabind must be registered in a
scope. This can be either a namespace of your choice or in the global
scope, which Luabind calls
module. To create a scope you use
luabind::module. It is used like this:
luabind::module(pL)
[
//register stuff here
];
This will register functions and classes in the global scope. To place your
functions or classes in a namespace, you call
luabind::module using the
desired name like so:
luabind::module(pL, "MyNamespace")
[
//register stuff here
];
To Script, or Not to Script, That Is the Question
| 277
Scripting in Lua
Luabind represents namespaces using a table, so in this example, all the
functions and classes registered will be put into the table
MyNameSpace.
Exposing C/C++ Functions Using Luabind
To expose a C/C++ function to Lua use the luabind::def function. As an
example, let’s take two simple functions,
add and HelloWorld, and bind
them to Lua. Here are the functions:
void HelloWorld()
{
cout << "\n[C++]: Hello World!" << endl;
}
int add(int a, int b)
{
returna+b;
}
And here’s how you bind them:
module(pL)
[
def("HelloWorld", &HelloWorld),
def("add", &add)
];
How easy is that! Following is a Lua script file that calls the exposed
functions.
--lua script to demonstrate exposing C++ functions to Lua using luabind
print("[lua]: About to call the C++ HelloWorld() function")
HelloWorld()
print("\n[lua]: About to call the C++ add() function")
a=10
b=5
print ("\n[lua]: "..a.." + "..b.." = "..add(a, b))
Running this script gives the output:
[lua]: About to call the C++ HelloWorld() function
[C++]: HelloWorld!
[lua]: About to call the C++ add() function
[lua]: 10+5=15
The project file containing this script is called ExposingCPPFunctions
-
ToLua.
278 | Chapter 6
Scripting in Lua

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required