Sign in to follow this  
Matthew Shockley

Unique ID

Recommended Posts

In my program, users make an unknown amount of userdata values with my function. I make a new Triangle object for each userdata they create and somehow I need to link each Triangle to each userdata for later use. I was thinking about using lua_topointer() but some people think I should use the lua registry. What would be the best way to do this with an unknown amount of userdatas created.

Share this post


Link to post
Share on other sites
ddn3    1610
If the userdata is 1:1 for the Lua object the user data itself can be the key for the data in the registry. However there might be issues with down casting from a ptr to a signed int. The registry within Lua itself is just a globally accessible table.

I believe its possible to push the user data as an up value onto a c-functor, thus allowing you to give each instance of the Lua Triangle in your case a unique functor. I see your setting the __index explicitly in C perhaps you can bind the userdata/Triangle there? Look into up values they might help.

see..

http://www.lua.org/pil/27.3.3.html

Good Luck!

-ddn

Share this post


Link to post
Share on other sites
Here is my code so far:

static int index(lua_State* L) {
lua_pushstring(L, "Please work!");
return 1;
}

static int Object(lua_State* L) {
const char *val = lua_tostring(L, -1);
lua_newuserdata(L, 0);
int uTop = lua_gettop(L);
lua_newtable(L);
lua_setmetatable(L, -2);
lua_getmetatable(L, -1);
int Top = lua_gettop(L);
lua_pushliteral(L, "__index");
lua_pushcfunction(L, index);
lua_settable(L, Top);
lua_pushvalue(L, uTop);
return 1;
}

Share this post


Link to post
Share on other sites
ddn3    1610
I think it will be clear if you look at the implementation of

#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)

when you use lua_pushcfunction to push the function (static int index(lua_State* L) onto the Lua stack, your pushing a closure onto the stack. Upvalues are used to associate state specific data with C closures. So on the lines..

..
int Top = lua_gettop(L);
lua_pushliteral(L, "__index"); <------ push upvalue around here somewhere
lua_pushcfunction(L, index); <------ push upvalue around here somewhere
lua_settable(L, Top);

the upvalue would just be the user data associated with this triangle object you just created.

After that is done when the function (static int index) is called it can pull the user data from the upvalue associated with the c-closure, and that tells you which real C object Triangle to operate upon. This is a common technique used by most binding libraries.

Good Luck!

-ddn

Share this post


Link to post
Share on other sites
I think I see what you mean? Make a closure for the index function and then use it to find the userdata? But when I get the userdata value in the index function, how will I check to see if has the same "ID" of a userdata?

Share this post


Link to post
Share on other sites
ddn3    1610
What are u putting in the user data? Is it the C side triangle object? Which you want to recover to operate upon when __index is called? Thats the normal use case of userdata (application specific ptr data).

I assumed your creating a new triangle object every time (static int Object(lua_State* L)) is called. This creates a Lua table with the associated metatable __index function which pipes to your own index function. Once this userdata to object connection is made it can't be broken, unless you reassign the __index metatable function directly in Lua between objects.

If that's the case, inside your index function, you can recover the userdata then cast it to your real triangle type and operate upon it as so. That's if i'm reading what you want to do right.

Good Luck!

-ddn

Share this post


Link to post
Share on other sites
I have a Triangle class and every time the Object function is called it makes a userdata and a Triangle. I need to link them like:

Triangle.Userdata = luauserdata;

Or something like that in the index function I can do this:

if (luauserdata == Triangle.Userdata) {
// Do stuff
}

Share this post


Link to post
Share on other sites
ddn3    1610
I'm not sure what your doing but if you want to associate the user data with the triangle and that with the Lua object who holds the same user data you can still use the up values.

Try something like this when you create the C-closure index.

..
lua_pushliteral(L, "__index");
lua_pushlightuserdata(L, (void*)data); <-----push ur user data here this will be upvalue #1
lua_pushcfunction(L, index);
...

now inside

static int index(lua_State* L) {

void* userData = (void*)lua_touserdata(L, lua_upvalueindex(1)); <--- this is how u can grab the upvalue from the closure

Now that you have that userData you can do whatever you want with it. It should be the exact same userdata which u pushed in with the line lua_pushlightuserdata..

Good Luck!

-ddn

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this