Как бы я обменивался переменными в классе C ++ с Lua? - PullRequest
4 голосов
/ 20 апреля 2010

Я довольно новичок в Lua, я пытался реализовать скрипты Lua для логики в игровом движке, который я собираю.До сих пор у меня не было никаких проблем с настройкой Lua и его работой через движок, и я могу вызывать функции Lua из функций C и C из Lua.

Способ работы движка теперь, каждый класс Objectсодержит набор переменных, которые движок может быстро перебрать, чтобы нарисовать или обработать для физики.Хотя всем игровым объектам необходим доступ к этим переменным и манипулирование ими, чтобы сам игровой движок мог видеть любые изменения, они могут создавать свои собственные переменные, Lua чрезвычайно гибок в этом отношении, поэтому я не вижу никаких проблем.

Во всяком случае, в настоящее время сторона игрового движка находится на земле C, и я действительно хочу, чтобы они остались там по соображениям производительности.Таким образом, в идеальном мире при создании нового игрового объекта мне нужно было бы предоставить Lua доступ на чтение / запись к этому стандартному набору переменных как часть базового класса объекта Lua, к которому затем могла бы перейти его игровая логика.схожу с ума.

Пока что я держу две отдельные таблицы объектов на месте - Lua создает новый игровой объект, который добавляет себя в глобально индексированную глобальную таблицу объектов и затем вызываетФункция C ++, которая создает новый класс GameObject и регистрирует индекс Lua (int) с классом.Пока все хорошо, функции C ++ теперь могут видеть объект Lua и легко выполнять операции или вызывать функции в Lua land, используя dostring.

Теперь мне нужно взять переменные C ++, часть класса GameObject,и выставить их Луа, и именно здесь Google подводит меня.Я столкнулся с очень хорошим методом здесь , который детализирует процесс с использованием тегов, но я читал, что этот метод устарел в пользу метатаблиц.

Какой идеальный способ достиженияэтот?Стоит ли учиться тому, как передавать определения классов, используя libBind или какой-либо эквивалентный метод, или есть простой способ, которым я могу просто зарегистрировать каждую переменную (один раз, во время появления) в глобальном объекте lua?Каков «текущий» лучший способ сделать это, начиная с Lua 5.1.4?

1 Ответ

5 голосов
/ 21 апреля 2010

Один подход заключается в использовании

  • lightuserdata, указывающая на переменную C ++
  • функция C для доступа к переменной C ++ с использованием lightuserdata
  • сохранить lightuserdata как значение функции C, так что для всех переменных достаточно одной функции
  • использовать количество аргументов функции для выбора между получением и установкой переменной

Например:

int game_state_var_accessor (lua_State *L)
{
    int *p = lua_topointer(L, lua_upvalueindex(1));
    if (lua_gettop(L) == 0)
    {   // stack empty, so get
        lua_pushinteger(L, *p);
        return 1;
    }
    else
    {   // arg provided, so set
        *p = lua_tointeger(L,1);
        return 0;
    }
}

Когда вы создаете новое игровое состояние, вы можете создавать методы доступа для каждой переменной, используя:

lua_pushlightuserdata(L, (int *)p); // where p points to your variable
lua_pushcclosure(L, game_state_var_accessor, 1);

Метод доступа теперь находится в стеке и может быть связан с глобальным именем или с именем метода в классе Lua. Если ваша таблица классов Lua находится в стеке с индексом t, это будет:

lua_setfield(L, t, "name_of_accessor");
...