2015-01-11 5 views
4

У меня есть система сценариев, хорошо работающая с использованием объектов userdata. Тем не менее, теперь я хочу иметь свойство в своих пользовательских данных, которые могут принимать обычную таблицу.Добавление метаданных userdata в таблицу lua

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

Мой существующий код выглядит следующим образом:

void 
LuaContext::push(lua_State* state, boost::shared_ptr<LuaWrapped> wrapped) { 
    static struct luaL_Reg methods[] = { 
     { "__index", LuaWrapped::static_get }, 
     { "__newindex", LuaWrapped::static_set }, 
     { "__len", LuaWrapped::static_len }, 
     { "__ipairs", LuaWrapped::static_ipairs }, 
     { "__pairs", LuaWrapped::static_pairs }, 
     { "__gc", LuaWrapped::static_gc }, 
     { "__eq", LuaWrapped::static_eq }, 
     { NULL, NULL } 
    }; 

    LuaWrapped::Ptr **ptr = (LuaWrapped::Ptr **)lua_newuserdata(state, sizeof(LuaWrapped::Ptr *)); 
    *ptr = new LuaWrapped::Ptr(wrapped); 

    if (luaL_newmetatable(state, "LuaWrapped")) { 
     lua_pushstring(state, "__index"); 
     lua_pushvalue(state, -2); 
     lua_settable(state, -3); 
     luaL_openlib(state, NULL, methods, 0); 
    } 
    lua_setmetatable(state, -2); 
} 

__gc Метаметод находится там, чтобы удалить LuaWrapped::Ptr класс (который является оболочкой для boost::shared_ptr). Наверное, я оставлю это и сохраню указатель в поле lightuserdata на обычной таблице.


Experimental обычай метатаблица против нормального выпуска таблицы (на обсуждение в комментариях):

void 
LuaContext::push(lua_State* state, boost::shared_ptr<LuaWrapped> wrapped) { 
    static struct luaL_Reg methods[] = { 
     { "__index", LuaWrapped::static_get }, 
     { "__newindex", LuaWrapped::static_set }, 
     { "__len", LuaWrapped::static_len }, 
     { "__ipairs", LuaWrapped::static_ipairs }, 
     { "__pairs", LuaWrapped::static_pairs }, 
     { "__gc", LuaWrapped::static_gc }, 
     { "__eq", LuaWrapped::static_eq }, 
     { NULL, NULL } 
    }; 

    lua_newtable(state); 
    LuaContext::push(state, "pointer"); 
    lua_pushlightuserdata(state, new LuaWrapped::Ptr(wrapped)); 
    lua_settable(state, -3); 

    lua_newtable(state); 
    luaL_openlib(state, NULL, methods, 0); 
    lua_setmetatable(state, -2); 
} 

int 
LuaWrapped::static_get(lua_State* state) { 
    int argc = lua_gettop(state); 
    for (int i = 1; i <= argc; i++) { 
     const char *type = lua_typename(state, i); 
     std::cout << type << std::endl; 
    } 
    .... 

Ожидаемые результаты на ПОЛУЧАЕТЕ:

таблицы, строка

Actual выход на выходе (Lua 5.2, Ubuntu 14.04):

булево, пользовательские данные

+0

Вы хотите сохранить таблицу как свойство своих пользовательских данных или хотите, чтобы таблица могла функционировать * как * userdata/object? –

+0

@etanreisner Я хочу, чтобы таблица была как свойство. Идея использования обычной таблицы с метатабелем userdata кажется способ реализации этого (но я был бы очень рад использовать другое решение). –

+0

Я пытаюсь понять, почему вообще пытаются повесить стол. Если точка состоит в том, чтобы сохранить таблицу в пользовательских данных, тогда это не так, а затем сохранит любое другое значение в пользовательских данных (вам просто нужно связать таблицу с пользовательскими данными и сохранить в ней ссылки), не возиться с метатегами или чем-то другим. Как вы в настоящее время сохраняете свойства в пользовательских данных. –

ответ

3

Хранение произвольных данных вместе с UserData является то, что USERDATA сред/uservalues ​​для.

Метод lua 5.2 для этого заключается в использовании функций lua_setuservalue и lua_getuservalue для сопоставления таблицы с пользовательскими данными. Затем эту таблицу можно использовать для хранения и получения произвольных значений, связанных с пользовательскими данными.

В lua 5.1 более общая концепция среды была использована для этой цели через lua_setfenv и lua_getfenv, но идея такая же.

 Смежные вопросы

  • Нет связанных вопросов^_^