вторник, 15 апреля 2008 г.

Экспортирование C++ классов в luabind

Привязка классов C++ к lua не на много сложнее, чем функции. Она реализована с помощью шаблона class_ и метода def, который регистриует конструкторы, методы, переменные и деструкторы. class_::def возвращает this указатель на редактируемую цепочку.

Класс животного:

class Animal
{
private:

int m_iNumLegs;

std::string m_NoiseEmitted;

public:

Animal(std::string NoiseEmitted,
int NumLegs):m_iNumLegs(NumLegs),
m_NoiseEmitted(NoiseEmitted)
{}

virtual ~Animal(){}

virtual void Speak()const
{std::cout << "\n[C++]: " << m_NoiseEmitted << std::endl;}

int NumLegs()const{return m_iNumLegs;}
};


экспорт класса с помощью luabind:

module(pLua)
[
class_<Animal>("Animal")
.def(constructor<string, int>())
.def("Speak", &Animal::Speak)
.def("NumLegs", &Animal::NumLegs)
];


Теперь можно применять этот класс в lua скрипте:


--создание объекта животное и вызов его методов

cat = Animal("Мяу", 4);

print ("\n[Lua]: У кота "..cat:NumLegs().. " ног.");

cat:Speak();


Заметьте, что в скрипте используется оператор : для вызовов методов. Другой путь вызова метода: cat.Speak(cat). Методы можно вызывать любым из указанных способов. Классы в lua представлены в виде таблиц, каждый элемент таблицы представляет собой метод или переменную класса.

Классы-наследники тоже легко экспортировать с помощью luabind. Пример класса, полученного от класса Animal:


class Pet : public Animal
{
private:

std::string m_Name;

public:

Pet(std::string name,
std::string noise,
int NumLegs):Animal(noise, NumLegs),
m_Name(name)
{}

std::string GetName()const{return m_Name;}
};


Используя luabind, класс Pet легко привязывать к lua. Это делается с помощью параметра шаблона bases<base class>, который определяет родительский класс:


module(pLua)
[
class_<Pet, bases<Animal> >("Pet")
.def(constructor<string, string, int>())
.def("GetName", &Pet::GetName)
];


Если ваш класс был создан при помощи множественного наследования, то каждый родительский класс должен быть прописан в bases<> и разделен запятыми:


class_<Derived, bases<Base1, Base2, Base3> >("Derived")

Экспортирование C/C++ функций в luabind

Чтобы привязать C/C++ функцию к lua используйте luabind::def фунцию. Например, давайте создадим простые функции: сложения двух чисел и вывода сообщения Hello World и привяжем их к lua:


using namespace std;
using namespace luabind;

void HelloWorld()
{
cout << "\n[C++]: Hello World!" << endl;
}

int add(int a, int b)
{
return a+b;
}

module(pL)
[
def("HelloWorld", &HelloWorld),
def("add", &add)
];


Теперь в скриптах lua можно вызывать эти функции:


print("[lua]: Вызов функции C++ HelloWorld()")

HelloWorld()


print("\n[lua]: Вызов функции C++ add()")

a=10
b=5

print ("\n[lua]: "..a.." + "..b.." = "..add(a, b))


После выполнения скрипта получим:


[lua]: [lua]: Вызов функции C++ HelloWorld()
[C++]: HelloWorld!
[lua]: [lua]: Вызов функции C++ add()
[lua]: 10+5=15


Если у вас есть перегруженные функции, например:


int MyFunc(int a);
void MyFunc(double a);


то def будет иметь следующий вид:


module(pLua)
[
def("MyFunc", (int (*)(int)) &MyFunc),
def("MyFunc", (void (*)(double)) &MyFunc),
];

понедельник, 14 апреля 2008 г.

Интересный блог о разработке казульного проекта Bloom 2

Под вечер нашел еще очень неплохие блоги автора elmortem. В своем новом блоге он рассказывает о создании проекта Bloom 2 (я играл в bloom, игра сделана очень качественно для первой казулки, надеюсь новая часть будет еще лучше предыдущей). Так же на его другом блоге можно найти кучу полезных расширений для HGE, особенно полезна разработка HGE с с полной поддержкой Unicode (сам когда-то хотел сделать такое, но потом решил работать с дефолтными возможностями по локализации).

воскресенье, 13 апреля 2008 г.

Экспорт С++ классов и функций с помощью luabind (общая информация)

Экспорт функций в lua очень прост даже без библиотеки luabind, но классы - это совсем другое дело! Чтобы экспортировать простой класс и его методы из lua в c++, вам придется создать lua-таблицу, которая будет содержать как данные класса, так и методы, которые вам потребуются. Вам придется создать метатаблицу, которая будет определять, как ваш класс ведет себя с операторами == или *. Чтобы экспортировать lua-функцию в c-функцию требуется много времени и сил, а чтобы сделать тоже самое с классом придется потратить гораздо больше ресурсов. К счастью за нас уже сделали тяжелую работу и создали API, который позволяет экспортировать функции и классы без каких-либо трудностей. Этот API называется luabind, и точно так же как и lua является open-source решением, которое можно легко использовать для своей работы.

Luabind - это библиотека, которая позволяет соединять данные между lua и C ++. Это реализовано благодаря использованию мета-программирования. Вы можете можете создавать классы в lua и использовать их в своих c++ программах, а также наоборот.

Чтобы начать использовать luabind, нужно включить заголовочные файлы библиотеки и lua в ваш проект, и затем вызывать функцию luabind::open(lua_State*) для инициализации luabind:


extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

#include "luabind/luabind.hpp"

int main()
{
//создание lua state
lua_State* pLua = lua_open();

//инициализация luabind
luabind::open(pLua);

/* регистрация функций и классов в luabind */

/* загрузка и выполение скриптов */

// освобождение ресурсов
lua_close(pLua);

return 0;
}


Для добавление своей функции нужно зарегистрировать ее в окружении luabind, для этого используется luabind::module(pL):


luabind::module(pL)
[
// регистрация классов и функций
];


Этот вызов регистрирует вашу функцию или класс в глобальном пространстве имен. Чтобы указать какое-то другое пространство имен сделайте:


luabind::module(pL, "MyNamespace")
[
// регистрация классов и функций
];


Luabind представляет пространство имен, как таблицу. В данном примере, все функции и классы будут находится в таблице с именем MyNameSpace.

Изучение luabind.

Сегодня решил начать изучение различных библиотек для связывания lua и c++. Начну рассмотрение с luabind.

Документацию на русском языке можно прочесть здесь (по-умолчанию выставляется неправильная кодировка, выберите в настройках браузера UTF8, чтобы убрать кракозяблы).

Для того, чтобы начать работать с luabind, её необходимо скачать с офцициального сайта. Так же для работы потребуется библиотека boost.