Sonntag, 22. Juli 2012

Lua C API Tutorial (part 3) Userdata

In previous tutorials we learned how make objects of basic datatypes and functions from C/C++ available in Lua. In this tutorial we will cover one of two userdata types. But first, what is userdata? Userdata is some sort of a generic datatype that represents complex C/C++ objects in Lua. So, to say it more directly: userdata is a way to expose user made C/C++ structs/classes to Lua.

I. Light & Full Userdata
As I already mentioned before there are 2 sorts of userdata in Lua. These sorts are full and light userdata. Unlike in the official Lua book we will start with light userdata first because it's easier to get started with. So, what's so special about it? While full userdata represents the exposed object by itself, light userdata is basically just a pointer to the exposed object in the memory, therefore, being an object inside lua, full userdata objects can be garbage collected by lua while light userdata is stored inside of C and won't be deleted by Lua's garbage collector. You also cannot associate metatables with light userdata, however light userdata is ideal for passing references to values around. E.g if you have a function that creates a window using some multimedia library and a function that draws an image inside the window then you can return a pointer to the created window as light userdata from one function and then pass it to the function that does the drawing stuff.

II. Light Userdata: An Example
Consider following scenario: you are building some sort of an RPG game where items are represented by a type called ItemDefinition. Now, what do you do if you want to get information about the items from within lua?
The goal of this example is to create an instance of ItemDefinition in C++ and then expose it as light userdata to lua. After that previously exposed functions will be used to print out information about the instance. Here is the source:


#include "iostream"
#include "lua5.1/lua.hpp"

struct ItemDefinition
{
    char* name;
    int price;
    bool stackable;
};

int getPrice(lua_State* L)
{
    ItemDefinition* def = (ItemDefinition*)lua_touserdata(L, 1);
    
    lua_pushnumber(L, def->price);
    return 1;
}

int isStackable(lua_State* L)
{
    ItemDefinition* def = (ItemDefinition*)lua_touserdata(L, 1);
    
    lua_pushboolean(L, def->stackable);
    return 1;
}

int getName(lua_State* L)
{
    ItemDefinition* def = (ItemDefinition*)lua_touserdata(L, 1);
    
    lua_pushstring(L, (const char*)def->name);
    return 1;
}

int main(int argc, char** argv)
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    
    ItemDefinition def;
    def.name = "Mana Potion";
    def.price = 120;
    def.stackable = true;
    
    lua_pushlightuserdata(L, (void*)&def);
    lua_setglobal(L, "def");
    
    luaL_Reg module[] = {
                                {"getPrice", &getPrice},
                                {"isStackable", &isStackable},
                                {"getName", &getName},
                                {NULL, NULL}
                        };
    luaL_register(L, "_G", module);
    
    luaL_dostring(L, "print('Type: \t\t'..type(def))");
    
    luaL_dostring(L,    "print('Name: \t\t'..getName(def));"
                        "print('Price: \t\t'..getPrice(def));"
                        "print('Stackable:\t'.. ( (isStackable(def) and 'yes') or 'no') );");
    
    lua_close(L);
    return 0;
}

Most of the code should be self explanatory. First we create an ItemDefinition structure with some properties. Nothing Lua-related so far. After that we define three functions that we will use from within Lua later. The line:

ItemDefinition* def = (ItemDefinition*)lua_touserdata(L, 1);

gets the pointer (our light userdata) from the stack and casts it to ItemDefinition* so we can get needed properties by accessing the instance using the def pointer. The same approach works also for full userdata.

lua_pushlightuserdata(L, (void*)&def);
lua_setglobal(L, "def");

These lines create a global variable in Lua that points to the def object inside the scope of our main function and should be understandable to you if you've read through the first tutorial.

After that we print the type of def along with values of its properties. The output of the program is:


Type:           userdata
Name:           Mana Potion
Price:          120
Stackable:      yes

Now, the only thing that probably also deserves some explanations is the third print command in the second luaL_dostring statement, which is an equivalent of what we would write in C as
printf("%s", (isStackable(def)? "yes" : "no") );

That's it for today. In the next tutorial we will make this example more object oriented by using full userdata and metatables. Bye.

Montag, 16. Juli 2012

Dreams Come True: Learning Haskell

Hm, when one is just starting out as a programming newbie and hears about all those different languages, one is often overwhelmed and fascinated by the diversity of stuff in the IT world. And that's the way things look like until one takes a look at/learns another language and notices that it isn't that different at all. The only differences are in the syntax while the way you think about programming and approach a task does not really change. And then the whole feeling of diversity disappears. I mean, the IT world is currently ruled by C and it's derivatives (Java, C++, PHP, C# etc.) and these languages are quite similar.

Oh, I already see the C++ fans swearing at me because I just said that C and C++ are similar in the way you solve your tasks and though it does not always apply to the way you design your software you still keep the old way of thinking about basic programming concepts like functions, variables, constants, objects, control structures etc. And then there appears a small and perhaps not as well-known language as the ones mentioned above, blows your mind and restores your belief into diversity in the industry.

I had that feeling with Lua because of it's unusual but ingenious, elegant and minimalistic way of looking at things. Of course I mean the concept of tables that can be practically anything.

Now I'd like to try a whole different paradigm, namely the functional programming. So I decided to learn Haskell. I really like that language and hope that it'll change my way of thinking about programming and make me familiar with some new algorithms/patterns/approaches to development. Maybe I'll post a thing or two about the progress of my studies here some time.

Sonntag, 15. Juli 2012

Lua C API Tutorial (part 2) C Functions in Lua

Hi, in this tutorial I'll show how to make C functions available in Lua. We'll start small first and expose a function that does not take any arguments or return any values and then cover step by step things like multiple return values, function arguments, namespaces etc. .

I. Simple 'greet' Function
So,  in this first example we'll create a greet function that will just print "Hello!" to the standard output. Here's the source code:

#include "iostream"
#include "lua5.1/lua.hpp"

int greet(lua_State* L)
{
    std::cout << "Hello!" << std::endl;
    return 0;
}

int main(int argc, char** argv)
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    
    luaL_Reg module[] = {
                                {"greet", &greet},
                                {NULL, NULL}
                        };
    luaL_register(L, "_G", module);
    
    luaL_dostring(L, "greet()");
    
    lua_close(L);
    return 0;
}

Many things should be familiar to you from the previous tutorial however there are (obviously) a few changes. We first define the function greet function that we will expose to Lua. The function expects a lua_State* as argument and returns an integer value. At this point, you may ask yourself how you pass a pointer to lua_State from within Lua, and I know you'll like the answer: you don't have to. Lua does this for you. The passed pointer points to the state that calls the function. The return value of the functions specifies how many values the function returns (0 - in our case).
Note that all functions that you want to expose to Lua have to return an int and expect lua_State* as its only argument (I'll explain it later).

These lines:

luaL_Reg module[] = {
                                {"greet", &greet},
                                {NULL, NULL}
                    };
luaL_register(L, "_G", module);

...create a table of functions that you wish to make available in Lua, terminated by {NULL, NULL} (a value that indicates the end of the table). The first value in a table entry is always the name of the function in Lua. The second one is the pointer to the function itself.
After the creation of the table we finally expose it to our Lua state (first argument). The second argument is the name of the table that will hold the function. I've entered "_G" (Lua's global table) here because I want the function to be accessible globally, like that:

greet()

If we want to put our function into a namespace-table then we have to enter the name of the table. For example:

luaL_register(L, "foo", module);

After that we will have to call our function like that:

foo.greet()

Everything else should be self explanatory. Now let's move on and make a function that returns values and expects arguments.

II. Return Values and Arguments
In this example we will write and expose a function that calculates the average of arguments and returns the result then. The implementation will require us to do some stack trickery and here's what it looks like:


#include "lua5.1/lua.hpp"

int average(lua_State* L)
{
    double sum = 0;
    int i = 0;
    for(;lua_gettop(L) > 0; ++i)
    {
        sum += luaL_checknumber(L, -1);
        lua_remove(L, -1);
    }
    
    lua_pushnumber(L, sum/i);
    return 1;
}

int main(int argc, char** argv)
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    
    luaL_Reg module[] = {
                                {"average", &average},
                                {NULL, NULL}
                        };
    luaL_register(L, "_G", module);
    
    luaL_dostring(L, "print(average(5, 4, 5))");
    
    lua_close(L);
    return 0;
}

While you should understand what's going on in the main function, the average function deserves a closer look. So what we do there is defining two variables first: sum to store the sum of the arguments passed to the function and the counter variable i that will contain the number of valid arguments in the end.
In order to understand what happens after that, one has to understand the lua stack. So we already know that the exchange of values between Lua and C/C++ works through the stack. That means that the arguments we pass to the average function will land on our Lua stack, and now we need to get them out of there. How that works? We can access values using indices (just like when we use arrays). Indices are integer values that can be positive as well as negative (opposed to C arrays that accept only positive values). Please note that in the case of a stack the indices start with 1 and not with 0.
Positive indices specify an absolute position within the stack (1 - is the element at the bottom, 2 - element above 1 etc.) while negative indices are relative to the top of the stack (-1 is the very top of a stack, -2 - the value below -1 etc.).
So that means that when we call the average function with 2, 5 and 9 (in exactly that order) as arguments then our stack will look like that:


Value Absolute Index Relative Index Comment
9 3 -1 It was the last argument so it's on the top of the stack now.
5 2 -2
2 1 -3 Is on the bottom of the stack

What we have to do now, to get all the values is to make a loop and let it run until the stack is empty. Inside of the loop we will check whether the element on the top is a number and add it to the sum variable. After that we will have to remove the element from the top, so the element below it becomes the 'top'. We will empty the stack step by step until the loop terminates. Then we finally calculate the average, push it onto the stack and return 1 so Lua knows that there is one result to be fetched from the stack. To cut it short, here are the functions we call with their descriptions:


for(;lua_gettop(L) > 0; ++i)

We let the loop iterate for as long as the index of the top is greater then zero. Because a stack is empty when it's greatest absolute index is zero.


sum += luaL_checknumber(L, -1);

We check whether the argument on the top of the stack is a number, extract it and finally add it to the sum variable.


lua_remove(L, -1);

This call removes the value we just got, from the stack, so we can process the value below it on the next iteration.


lua_pushnumber(L, sum/i);

All done! We finally push our result onto the stack.

So there's one more thing that I should mention before I go to bed:

III. Multiple Return Values
There isn't really much to explain here. Just take a look at this piece of code:


#include "lua5.1/lua.hpp"

int get_info(lua_State* L)
{
    lua_pushstring(L, "John Doe"); // push name (first return value)
    lua_pushnumber(L, 40); // push age (second return value)
    return 2; // return 2 values from the top of the stack
}

int main(int argc, char** argv)
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    
    luaL_Reg module[] = {
                                {"get_info", &get_info},
                                {NULL, NULL}
                        };
    luaL_register(L, "_G", module);
    
    luaL_dostring(L, "name, age = get_info(); print(name .. '(' .. age .. ')' )");
    
    lua_close(L);
    return 0;
}


Output:
John Doe(40)


I hope you're still brave and ready for the next tutorial where I will show you how to create userdata. Good night!

Donnerstag, 12. Juli 2012

Lua C API Tutorial (part 1) Installation and First Program

So, I've decided to make a series of tutorials for the (IMO quite eccentric) Lua 5.1 c api. I plan to cover things like exposing C/C++ functions/values to Lua, creation of userdata and metatables as well as the installation of the api on a linux system. However some things must be mentioned first:

I don't claim to be a professional in using lua c api. These tutorials should be considered as an introduction to it and not as an in-depth guide.


I. Installation
To install lua api on a Debian derivative type following line into the terminal (tested on Ubuntu 12.04):
$ sudo apt-get install liblua5.1-0-dev
(don't enter the '$' symbol)


If you're using another distro then consult its package management system. If lua development files are not in the repositories then you can still download and build lua.

To do so, download the sources from here. (Note that this tutorial covers only the installation of lua 5.1)
Extract the archive, open up the terminal and cd to the directory that has been extracted from the archive. After that you can simply type:
$ make linux


The build process could take some time, depending on your machine. To install the libraries and headers to a public directory (either /usr/local/lib/ + /usr/local/include/ or /usr/include/ + /usr/lib/) enter:
$ sudo make install
This step makes many things simpler since you don't have to specify the library/header search directories explicitly.

II. Hello, Lua
In this part of the tutorial we will expose a C string that contains "Hello, Lua" to Lua and pass it to Lua's print function. So, here's the complete source code first:


// main.cpp
#include "lua5.1/lua.hpp"

int main()
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    
    lua_pushstring(L, "Hello, Lua");
    lua_setglobal(L, "hello");
    
    luaL_dostring(L, "print(hello)");
    
    lua_close(L);
    return 0;
}

You can build the source by calling:
$ g++ main.cpp -llua5.1 -o lua_app

So, the first line of code includes lua headers (for C++). Note: you may want to use '<' and '>' instead of the double quotes, and that would probably be the right thing to do. The only reason why I picked double quotes in the include statement is because they seem to make less problems with the syntax highlighter.

The following line creates a new lua state.

lua_State* L = luaL_newstate();

Lua states are instances of the lua interpreter. An application can have multiple unrelated states. They don't share anything, so if you execute a script that defines a variable 'a' in one state then other states still won't know anything about it. Most functions of the lua api require a pointer to a lua state as their first argument.

We make the lua standard library available to our state using the following call.

luaL_openlibs(L);


Now we come to the part where we create our variable. Be careful, this part could be a little bit tricky. So, to exchange values between lua and c/c++ we use the so called stack (that has nothing to do with the normal stack of a c/c++ program). It works like that: if we want to make a value available in lua then we put it onto the stack and then it can be used from within lua and if lua calls a C function and passes some arguments to it, then they also land on the stack and then you have to "extract" them from there in order to be able to use them in your C code. (You'll see how it works in the next tutorial when we bind a C++ function to Lua
So in our case we want to "export" a string value to lua so we call lua_pushstring function and give it the pointer to our state (so it knows which lua instance will get the string) and the string itself ("Hello, Lua" in this case). We'll that's good, now we've got a string in lua, but how do we access it? The question is answered in the next line: we call the lua_setglobal function. This function creates a global variable (called "hello" in this case) and assigns a value from the stack to it. So these two lines of C++ code...

lua_pushstring(L, "Hello, Lua");
lua_setglobal(L, "hello");

...are the same as this line in lua:

hello = "Hello, Lua"
However, how does the function know which value to assign to the variable if there are multiple values on the stack? Well, the lua_setglobal function assumes that the value we want to assign is on the top of the stack (and our string is on the top since we haven't pushed anything else). After assigning the value to the global variable the string is removed from stack, so it's perfectly clear again.

The call to luaL_dostring in the next line expects a string with some lua code and the state that will execute it. At this point we also could have used luaL_dofile, if we had a lua script. (creating a separate script for one line of code is however a bit overkill, if you ask me).
The lua code in the string calls lua's print-function (which wouldn't be available if we hadn't called luaL_openlibs, because it's a part of lua's standard library) and lets it print the string we created in c++.

The call to lua_close, closes the specified lua state and frees all resources associated with it.

As you may have noticed the API functions have 2 kinds of prefixes: "lua_" and "luaL_". What's the difference? Well, "lua_"-functions are functions of the "naked" lua API, while "luaL_"-functions are handy functions provided by the lua auxiliary library that is there to make our life easier by providing out-of-the-box functionality for common stuff that we would otherwise have to implement by ourselves.

So, that was the first lua c api tutorial and also a brief demonstration of it. In the next tutorial we will extend lua with functions from C/C++.
I hope you could follow me and good night!

Sonntag, 8. Juli 2012

Back to the Roots

Hm, I guess I'm just a spoiled C++ programmer, that got used to using original libraries and expected their bindings to be as well documented as the original ones are. Yes that means that I'm returning to C/C++ with Qt or Gtk+.

Meet Python

Today I'm going to start preparing myself for the development of the level editor for Lacewing. For this task I needed an easy to use language (I don't want to get stuck for years with C++) that also has fairly complete set of bindings for a number of libraries and I was able to narrow my search down to 2 languages: Python and C#. Both languages have lots of bindings, are relatively simple to use and have a lots of people using them so that I know that I'm not alone if there's a problem that I can't solve on my own. However I'm not going to make another review or comparison of the languages or try to find a better one and as the title of the post already shows, I've decided to go with Python.

Well, whatever, today I'm going to start working with PyGTK and bindings to various other libraries (especially opengl). For the PyGTK part, I'll probably take a look at the PyGTK tutorial on zetcode.com .
zetcode.com is an awesome site, that deserves some credit and if you've never been there before and have some interest in working with various GUI toolkits and databases then make sure to check out the site. The author of the tutorials offers brief introductions to a variety of nice libraries.

Freitag, 6. Juli 2012

Project Announcement

I've been working for quite some time on a project called Lacewing. (one of the reasons why this blog is called Unicorns & Lacewings)
Lacewing is/will be an open source game engine or to be more precise, a game development concept, since it doesn't introduce any game engine specific stuff by itself and builds upon another frameworks.
So, what does it exactly do? Well, it creates a Component Base Entity System (just google it for more on this topic).

In my case a CBE System introduces one entity type and you can attach various components to it. The entity does nothing but calling callback functions of its components when needed, and components do the actual job, so if you wan't to have a flying, ice-breathing fire-dragon with a laser eye (maybe a bit overkill though) in your game, then just pick an entity, write appropriate components (e.g. the laser eye component) and attach them all to the entity, and voila! you've now got a that strange creature in your game. Needless to say, this is much easier and faster then implementing a separate dragon class. This brings much flexibility and reusability to your projects.

My version of this system is implemented in Lua and is also somehow inspired by unity3d (which is an awesome 3d game engine). I currently plan to make a level editor that makes use of the system and generates lua code for levels.

To show how easy everything works, consider following situation: There is a ball entity with a rigid body component attached to it. We want the entity to print out "collision!" when the ball hits something in the game world.

Well, the naive approach would be, to modify the rigid body component, to complete this task, however the results will be probably kind of annoying because each owner of the rigid body component will print "collision!" and not just the ball. So, the better approach would be the creation of a custom component. To do so, we create a .lua file. Lets call it "debug_collision.lua". Now, all we have to do is to put following code into the file:
function onCollisionEnter()
    print "collision!"
end


And that's it, more code isn't required. Then we just drop the component onto the ball entity in the editor to attach it to the entity and if we start the game we will see "collision!" - in the console window, each time the ball hits some other object.

Mittwoch, 4. Juli 2012

Intro

Hm, many things have changed since I was here the last time, now everything seems to be so "Web 2.0"ish, well never mind. Hi my name is Alex Rovner, I am a hobbyist software developer from Germany and in this blog I'll be posting stuff on various software development related topics (mostly lua and game development), but I'll also post some random thoughts here.