Рассматривать userdate как таблицу в Lua - PullRequest
8 голосов
/ 26 июля 2010

У меня есть несколько классов в C ++, которые я хотел бы представить Lua. Я могу позвонить Widget:New(), чтобы получить возвращенные данные пользователя с метатабельным набором для таблицы WidgetMeta. WidgetMeta содержит все функции C ++, и он __index настроен на себя, поэтому я могу сделать это:

w = Widget:New()
w:Foo() -- Foo is defined in C code

Это все довольно просто.

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

w1 = Widget:New()
w2 = Widget:New()

function w1:Bar() print "Hello!" end -- Both functions unique
function w1:Baz() print "World!" end -- to their own userdata

Мой текущий план атаки состоит в том, чтобы у metatable была специальная таблица, которая сопоставляет пользовательские данные и таблицу, в которой я могу хранить функции и переменные для пользовательских данных. Проблема в том, что я не уверен, что это лучший способ сделать, или есть лучшее решение. поэтому мой вопрос состоит из двух частей: когда я настраиваю свои метаметоды __index и __newindex, пишу ли я их в коде Lua в текстовом файле и запускаю его перед тем, как запускать остальные компоненты, или я помещаю код Lua непосредственно из C строка в моей программе через luaL_loadstring, или я делаю это с интерфейсом C и имею дело со всеми манипуляциями со стеком? и во-вторых, как мне написать эту функцию ... но я разберусь с этим, как только решу, какой путь лучше выбрать.

Ответы [ 2 ]

9 голосов
/ 26 июля 2010

Добавить функциональную среду к данным пользователя и перенаправить доступ через них.

Вот мой старый код, описывающий процесс.

static int l_irc_index( lua_State* L )
{
    /* object, key */
    /* first check the environment */ 
    lua_getfenv( L, -2 );
    lua_pushvalue( L, -2 );
    lua_rawget( L, -2 );
    if( lua_isnoneornil( L, -1 ) == 0 )
    {
        return 1;
    }

    lua_pop( L, 2 );

    /* second check the metatable */    
    lua_getmetatable( L, -2 );
    lua_pushvalue( L, -2 );
    lua_rawget( L, -2 );

    /* nil or otherwise, we return here */
    return 1;
}

static int l_irc_newindex( lua_State* L )
{
    /* object, key, value */

    lua_getfenv( L, -3 );
    lua_pushvalue( L, -3 );
    lua_pushvalue( L, -3 );
    lua_rawset( L, -3 );

    return 0;
}
0 голосов
/ 28 июля 2010

Вы действительно должны взглянуть на tolua ++, который имеет очень похожую концепцию. У всех объектов пользовательских данных, созданных из lua, есть скрытая таблица для хранения их свойств.

Этот раздел руководства описывает это: http://www.codenix.com/~tolua/tolua++.html#additional

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...