2

What I want to do is this:

object.foo = "bar"

print(object.foo)

where "object" is a userdata.

I've been googling for a while (using the keyword __newindex and lua_rawset) but I can't any examples that do what I want it to do.

I want to do this in with the lua api in c++

CapsAdmin
  • 95
  • 2
  • 7
  • Is the string attribute `foo` arbitrary or does it represent an attribute of the userdata object? – gwell Aug 22 '10 at 17:32
  • Note that `lua_rawset()` will skip access to the metatable. That is why it is "raw". You want to use any of the other API functions that manipulate table entries so that the metamethods are used. – RBerteig Aug 23 '10 at 02:30
  • foo is just a variable that I'm using to show that I want to store something in the userdata from within lua. – CapsAdmin Aug 24 '10 at 14:32

3 Answers3

3

Let us write this in Lua code so that we can make quick experiments with the code

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'

If you work with userdata you probably want to do the above using the C API. However the Lua code should make it clear extactly which steps are necessary. (The newproxy(..) function simply creates a dummy userdata from Lua.)

u0b34a0f6ae
  • 48,117
  • 14
  • 92
  • 101
1

I gave up trying to do this in C++ so I did it in lua. I loop through all the metatables (_R) and assign the meta methods.

_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

The problem with this is what I'm supposed to use for index. tostring(self) only works for those objects with an ID returned to tostring. Not all objects have an ID such as Vec3 and Ang3 and all that.

CapsAdmin
  • 95
  • 2
  • 7
0

You could also use a simple table...

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

print(config.tooltype1) --"Tool"   
print(config.tooltype2) --"HopperBin"   
print(config.number) --5
James T
  • 3,292
  • 8
  • 40
  • 70