lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Charles Melice once stated:
> > Sorry, I see now that I have not asked the right question.
> > 
> > I wonder "How to index a userdata, and together define methods in the
> > userdata virtual table".
> 
> I just found that this method works, but it seems very complicated.
> 
> 	static int index(lua_State *L)
> 	{
> 		Vect4 *v=Vget(L,1);  // Get my user data pointer
> 		int ch;
> 		if (lua_type(L,2)==LUA_TSTRING)
> 		{
> 			const char *szIndex = luaL_checkstring(L,2);
> 			if (!strcmp(szIndex, "normalize"))
> 			{
> 				lua_pushcfunction(L, Lnormalize);
> 				return 1;
> 			}
> 			if (strlen(szIndex)!=1) 
> 				LuaError(L, "Bad method");
> 			ch = *szIndex;
> 		}
> 		else if (lua_type(L,2)==LUA_TNUMBER)
> 		{
> 			ch = luaL_checkint(L,2);
> 		}
> 		else
> 			LuaError(L, "Bad index type");
> 
> 		switch (*luaL_checkstring(L,2))
> 		{
> 		case 1: case 'x': lua_pushnumber(L,v->x); break;
> 		case 2: case 'y': lua_pushnumber(L,v->y); break;
> 		case 3: case 'z': lua_pushnumber(L,v->z); break;
> 		case 4: case 'w': lua_pushnumber(L,v->w); break;
> 		default:
> 			LuaError(L, "Bad index");
> 		}
> 		return 1;
> 	}
> 

  Okay.  To have this behavior, just change the previous code I sent thusly:

	static const luaL_Reg vec4meta[] =
	{
	  { "__index"		, vec4meta___index	} ,
	  { "__newindex"	, vec4meta___newindex	} ,
	  { "normalize"		, vec4meta_normalize	} ,
	  { NULL		, NULL			}
	};
	
  and make the following changes to vec4meta___index():
  
  	static int vec4meta___index(lua_State *L)
  	{
  	  Vec4 *vec = luaL_checkudata(L,1,MY_VEC4_TYPE);
  	  int   idx;
  	  
  	  if (lua_type(L,2) == LUA_TSTRING)
  	  {
  	    const char *name = lua_tostring(L,2);
  	    
	    /*--------------------------------------------------------------
	    ; check to see if the given name exists in the metatable; if so,
	    ; we return it.
            ;---------------------------------------------------------------*/

  	    if (luaL_getmetatable(L,1,name))
  	      return 1;
  	    
  	    /* rest of code goes here, as is */
  	}
  	
  I'll leave the changes to vec4meta___newindex() as an extercise to the
reader.

  -spc