[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: How to know calling convention inside __index function
- From: "Jerome Vuarand" <jerome.vuarand@...>
- Date: Wed, 30 May 2007 16:40:00 -0400
John Labenski wrote:
> print(udata.GetStuff)
> print(udata.GetStuff())
> print(udata:GetStuff())
>
> udata.SetStuff(5)
> udata.SetStuff = 5
> udata:SetStuff(5)
>
> [...]
>
> I am most interested in knowing the difference between udata.GetStuff
> <==> udata:GetStuff() udata.SetStuff = 5 <==> udata:SetStuff(5)
You are mixing syntatic sugars, metamethods and a confused idea of how
userdata setters/getters work. Here is equivalent code, without the
syntax sugar and with explicit metamethod access:
udata.GetStuff
getmetatable(udata).__index(udata, "GetStuff")
-- __index always get two params
udata.GetStuff()
getmetatable(udata).__index(udata, "GetStuff")()
-- here you just add an extra () pair
udata:GetStuff()
getmetatable(udata).__index(udata, "GetStuff")(udata)
-- here with an additionnal param inside the last () pair
udata.SetStuff(5)
getmetatable(udata).__index(udata, "SetStuff")(5)
-- here you pass 5 to the function returned by __index
udata.SetStuff = 5
getmetatable(udata).__newindex(udata, "SetStuff", 5)
-- __newindew always get three params
udata:SetStuff(5)
getmetatable(udata).__index(udata, "SetStuff")(udata, 5)
-- using : you insert an additionnal param in the setter call
Now to fix this mess you have to decide if you want explicit
getters/setters in Lua or not.
Without getter/setter, you need to overide both __index and __newindex.
Example:
-- In Lua you write:
udata.Stuff = 5
print(udata.Stuff)
/* In C you write */
int my_index(lua_State* L)
{
somestruct_t* data = (somestruct_t*)lua_touserdata(L, 1);
const char* field = lua_tostring(L, 2);
if (!strcmp(field, "Stuff"))
{
lua_pushnumber(L, data->Stuff);
return 1;
}
return 0;
}
int my_newindex(lua_State* L)
{
somestruct_t* data = (somestruct_t*)lua_touserdata(L, 1);
const char* field = lua_tostring(L, 2);
if (!strcmp(field, "Stuff"))
{
data->Stuff = lua_tonumber(L, 3);
}
return 0;
}
With getter/setter, you only need to override __index, but you have to
create two additionnal functions. Example:
-- In Lua you write:
udata:SetStuff(5)
print(udata:GetStuff())
/* In C you write */
int my_GetStuff(lua_State* L)
{
somestruct_t* data = (somestruct_t*)lua_touserdata(L, 1);
lua_pushnumber(L, data->Stuff);
return 1;
}
int my_SetStuff(lua_State* L)
{
somestruct_t* data = (somestruct_t*)lua_touserdata(L, 1);
data->Stuff = lua_tonumber(L, 2);
return 0;
}
int my_index(lua_State* L)
{
somestruct_t* data = (somestruct_t*)lua_touserdata(L, 1);
const char* field = lua_tostring(L, 2);
if (!strcmp(field, "GetStuff"))
{
lua_pushcfunction(L, my_GetStuff);
return 1;
}
else if (!strcmp(field, "SetStuff"))
{
lua_pushcfunction(L, my_SetStuff);
return 1;
}
return 0;
}
If something is still not clear, fell free to ask for more details :-)