[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: What will be the future of Lua-5.2 or even Lua-6.0
- From: Shannon Stewman <stew@...>
- Date: Sun, 25 Dec 2005 01:16:46 -0600
On Sat, Dec 24, 2005 at 09:35:17PM +0200, askok@dnainternet.net wrote:
> The only thing I'd really want of Lua itself, is enumerated types, so that C API
> constants can be used as type-aware parameters, and catch any "false" usage
> (color enum where font enums should be, and such). This is a major issue for
> coding larger programs with SDL, Gtk+ etc. and currently, just placing those
> enums as integers is a Lowsy Solution. I shall look into this, if it could be
> achieved by the extended metatable handling there now is, or some other "stock
> Lua" technique.
I've found a very easy way to do this in Lua 5.0 with light userdata.
The following example, not fully tested, is similar to the code I use in
my research:
// typedef to hold the enums
typedef struct { const char* name; int val; } luaL_enum;
// registers the enums in the table given at index 'tbl'
void luaL_register_enums( lua_State* L, int tbl, const luaL_enum* enumList );
{
int i;
for (i=0; enumList[i].name != NULL; ++i) {
lua_pushstring(L, enumList[i].name);
lua_pushlightuserdata(L, (void*) enumList+i);
lua_rawset(L, tbl);
}
lua_pushlightuserdata(L, enumList);
lua_pushnumber(L, i);
lua_rawset(L, LUA_REGISTRYINDEX);
}
int luaL_toenum( lua_State* L, int enumIdx, const luaL_enum* enumList )
{
const luaL_enum* ep;
int ei, maxent;
lua_pushlightuserdata(L, enumList);
lua_rawget(L, LUA_REGISTRYINDEX);
if (!lua_isnumber(L,-1)) {
lua_pop(L,1); return 0;
}
maxent = lua_tonumber(L,-1);
lua_pop(L,1);
if (!lua_islightuserdata(L,enumIdx)) return 0;
ep = (luaL_enum*) lua_touserdata(L,enumIdx);
ei = enumList - ep;
if (ei < 0 || ei >= maxent) return 0;
return enumList[ei].val;
}
int luaL_isenum( lua_State* L, int enumIdx, const luaL_enum* enumList )
{
const luaL_enum* ep;
int ei, maxent;
lua_pushlightuserdata(L, enumList);
lua_rawget(L, LUA_REGISTRYINDEX);
if (!lua_isnumber(L,-1)) {
lua_pop(L,1); return 0;
}
maxent = lua_tonumber(L,-1);
lua_pop(L,1);
if (!lua_islightuserdata(L,enumIdx)) return 0;
ep = (luaL_enum*) lua_touserdata(L,enumIdx);
ei = enumList - ep;
return (ei >= 0 && ei < maxent);
}
//
//// EXAMPLE OF ABOVE
//
// example enums
enum LibEnum { LIB_FOO = 1, LIB_BAR };
// enums for our library
static const luaL_enum library_enums[] = {
{ "FOO", (int) LIB_FOO },
{ "BAR", (int) LIB_BAR },
{ 0 },
};
int lib_enumToString( lua_State* L )
{
int v;
LibEnum e;
v = luaL_toenum(L,1);
if (v==0 && !luaL_isenum(L,1)) luaL_typerror(L,1,"LibEnum");
e = (LibEnum) v;
switch(e) {
case LIB_FOO: lua_pushstring(L, "FOO"); break;
case LIB_BAR: lua_pushstring(L, "BAR"); break;
default: lua_pushstring(L, "UNKNOWN"); break;
}
return 1;
}
static const struct luaL_reg lib_fxns[] = {
{ "enumToString", lib_enumToString },
{ 0 },
};
int luaopen_lib(lua_State* L)
{
luaL_openlib(L, "lib", lib_fxns);
luaL_register_enums(L, lua_gettop(L), library_enums);
return 0;
}
Cheers!
--
Shannon Stewman | Let us walk through the waning night,
Caught in a whirlpool, | As dawn-rays tickle our toes, the dew soothes
A quartering act: | Our blistered soles, and damp bones stir
Solitude or society? | As crimson cracks under the blue-grey sky.
--
Shannon Stewman | Let us walk through the waning night,
Caught in a whirlpool, | As dawn-rays tickle our toes, the dew soothes
A quartering act: | Our blistered soles, and damp bones stir
Solitude or society? | As crimson cracks under the blue-grey sky.