[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Lightweight Lua Enumerations
- From: Rici Lake <lua@...>
- Date: Wed, 27 Jun 2007 19:06:58 -0500
On 27-Jun-07, at 6:09 PM, Gavin Kistner wrote:
What do _you_ do when you need a simple, lightweight way to create some
unique values?
I use simple lower case strings, unless a better solution
occurs to me. In your example, I would might use "good", "sin",
"cos" and "sin".
Having said that, I might well choose to use math.sin and math.cos
for the operation, if those were appropriate. For example,
rather than using an enumeration of "BlendType"'s, I would be
tempted to use the actual blending functions.
Do you worry about cross-enumeration comparisons?
No. I figure that it's about the same as using the same name
for two completely unrelated methods in unrelated classes.
(Shape:draw() versus Sheriff:draw() would be the classic example).
Although you didn't ask about C, here's how I bridge with
C enumerations.The validity of the string is checked
by looking up the C enumeration in a table attached as an
upvalue to the C closure, which is reasonably simple and fast:
static int foo_set_op (lua_State *L) {
lua_Integer op = 0;
Foo *self = check_self(L);
if (lua_type(L, 2) == LUA_TSTRING) {
lua_rawget(L, lua_upvalueindex(1));
op = lua_tointeger(L, -1);
if (op != 0 || lua_type(L, -1) == LUA_TNUMBER) {
self->op = op;
return 0;
}
}
luaL_typerror(L, 2, "Operation");
return 0;
}
static int foo_get_op (lua_State *L) {
Foo *self = check_self(L);
lua_rawgeti(L, lua_upvalueindex(1), self->op);
return 1;
}
The same table is used for both functions; it has integer keys
which map to strings, and string keys which map to integers.
check_self, by the way, is implemented by setting the environment
table of the closures to the metatable for the object type, so it
can be quite general:
void *check_self (lua_State *L) {
if (lua_getmetatable(L, 1) && lua_rawequal(L, -1, LUA_ENVIRONINDEX)) {
lua_pop(L, 1);
return lua_touserdata(L, 1);
}
else {
lua_getfield(L, LUA_ENVIRONINDEX, "__typename");
luaL_typerror(L, 1, lua_tostring(L, -1));
return 0;
}
}
The enumeration checking code above can be refactored for convenience
as well.