lua-users home
lua-l archive

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


2009/7/23 b's spam <spam@inlandstudios.com>:
> I'm not too sure how to use the index/newindex metamethods for what I'm
> trying to do.  Are there examples of this somewhere?

Here is an (untested) example of what you can do (I used the prototype
of the classes you used in your example) :

template <typename T>
int index(lua_State* L);

template <>
int index<bool>(lua_State* L);
{
	bool* ptr = (bool*)lua_touserdata(L, 1);
	lua_pushboolean(L, *ptr ? 1 : 0);
	return 1;
}

template <>
int index<float>(lua_State* L);
{
	float* ptr = (float*)lua_touserdata(L, 1);
	lua_pushnumber(L, *ptr);
	return 1;
}

template <typename T>
int newindex(lua_State* L);

template <>
int newindex<bool>(lua_State* L);
{
	bool* ptr = (bool*)lua_touserdata(L, 1);
	*ptr = lua_toboolean(L, 3)!=0;
	return 0;
}

template <>
int newindex<float>(lua_State* L);
{
	float* ptr = (float*)lua_touserdata(L, 1);
	if (!lua_isnumber(L, 3))
		return luaL_error(L, "new value must be a number");
	*ptr = (float)lua_tonumber(L, 3);
	return 1;
}

template <typename T>
struct LuaValue
{
	lua_State* L;
	std::string name;
	T* ptr;
	LuaValue(lua_State* _L, std::string _name)
	: L(_L)
	, name(_name)
	, ptr(0)
	{
		ptr = lua_newuserdata(L, sizeof(T))
		*ptr = T();
		lua_createtable(L, 0, 2);
		lua_pushcfunction(L, index<T>);
		lua_setfield(L, -2, "__index");
		lua_pushcfunction(L, newindex<T>);
		lua_setfield(L, -2, "__newindex");
		lua_setmetatable(L, -2);
		lua_setglobal(L, name.c_str());
	}
	~LuaValue()
	{
		lua_pushnil(L);
		lua_setglobal(L, name.c_str());
		ptr = 0;
		L = 0;
	}
	LuaValue<T>& operator=(const T& value) { *ptr = value; return *this; }
	operator T() { return *ptr; }
}

typedef LuaValue<float> LuaFloat;
typedef LuaValue<bool> LuaBool;

LuaBool myBool ( lua_state, "boolvar_in_script" );
LuaFloat myValue ( lua_state, "floatvar_in_script" );

for loop()
{
   myBool = false; // write to variable
   myValue= 1.25f;

   // faster access:
   bool* pBool = myBool.ptr;
   float* pValue = myValue.ptr;
   *pBool = false; // write to variable
   *pValue= 1.25f;


   bool tmpBoolean = myBool; // read from variable
}

And from the Lua side, you can do:

if boolvar_in_script.value then
    floatvar_in_script.value = 42
end