2010-08-22 2 views
2

То, что я хочу сделать это:Сохранение значений в пользовательских данных объекта из Lua

object.foo = "bar" 

print(object.foo) 

где «объект» является UserData.

Я искал какое-то время (используя ключевое слово __newindex и lua_rawset), но я не могу никаких примеров делать то, что я хочу.

Я хочу сделать это в с Lua API в C++

+0

Является ли атрибут string 'foo' произвольным или представляет собой атрибут объекта userdata? – gwell

+0

Обратите внимание, что 'lua_rawset()' пропускает доступ к метатебельному. Вот почему он «сырой». Вы хотите использовать любую из других функций API, которые управляют записями таблицы, чтобы использовать метаметоды. – RBerteig

+0

foo - это просто переменная, которую я использую, чтобы показать, что я хочу что-то хранить в пользовательских данных из lua. – CapsAdmin

ответ

3

Запишем это в Lua коде, так что мы можем сделать быстрые эксперименты с кодом

function create_object() 
    -- ## Create new userdatum with a metatable 
    local obj = newproxy(true) 
    local store = {} 
    getmetatable(obj).__index = store 
    getmetatable(obj).__newindex = store 
    return obj 
end 

ud = create_object() 
ud.a = 10 
print(ud.a) 
-- prints '10' 

Если вы работаете с UserData вы вероятно, захотите сделать это, используя API C. Однако код Lua должен четко указывать, какие шаги необходимы. (The newproxy(..) функция просто создает фиктивную UserData из Lua.)

+0

Я забыл добавить, что хочу сделать это в C++, и я не уверен, как бы я это сделал. – CapsAdmin

+0

О, я понимаю, что вы имеете в виду. Я мог бы попробовать это сделать. – CapsAdmin

+0

Функция newproxy не поддерживается в Lua 5.2 или выше. –

0

Вы также можете использовать простую таблицу ...

config = { tooltype1 = "Tool", 
     tooltype2 = "HopperBin", 
     number = 5, 
     } 

print(config.tooltype1) --"Tool" 
print(config.tooltype2) --"HopperBin" 
print(config.number) --5 
1

я отказался от попыток сделать это в C++, так что я сделал это в Lua. Я просматриваю все метатеги (_R) и назначаю мета-методы.

_R.METAVALUES = {} 

for key, meta in pairs(_R) do 
    meta.__oldindex = meta.__oldindex or meta.__index 

    function meta.__index(self, key) 
     _R.METAVALUES[tostring(self)] = _R.METAVALUES[tostring(self)] or {} 
     if _R.METAVALUES[tostring(self)][key] then 
      return _R.METAVALUES[tostring(self)][key] 
     end 
     return meta.__oldindex(self, key) 
    end 

    function meta.__newindex(self, key, value) 

     _R.METAVALUES[tostring(self)] = _R.METAVALUES[tostring(self)] or {} 

     _R.METAVALUES[tostring(self)][key] = value 
    end 

    function meta:__gc() 
     _R.METAVALUES[tostring(self)] = nil 
    end 
end 

Проблема в том, что я должен использовать для индекса. tostring (self) работает только для тех объектов с идентификатором, возвращаемым tostring. Не все объекты имеют ID, такие как Vec3 и Ang3, и все такое.

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