diff options
| author | Alexander Gavrilov | 2012-04-02 19:10:57 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-04-02 22:02:04 +0400 |
| commit | a8fe0eccb4ab03231da0692f06b9e4bbb27dc5c2 (patch) | |
| tree | 3d094631855436647815c02ca2651bdd2d6f29a1 /library/LuaWrapper.cpp | |
| parent | 467f4108ae9ad52fee6e0e95579be5544d52e4ee (diff) | |
| download | dfhack-a8fe0eccb4ab03231da0692f06b9e4bbb27dc5c2.tar.gz dfhack-a8fe0eccb4ab03231da0692f06b9e4bbb27dc5c2.tar.bz2 dfhack-a8fe0eccb4ab03231da0692f06b9e4bbb27dc5c2.tar.xz | |
Add functions for checking validity of lua wrapper objects.
Diffstat (limited to 'library/LuaWrapper.cpp')
| -rw-r--r-- | library/LuaWrapper.cpp | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp index 1148d3fc..818e6b9e 100644 --- a/library/LuaWrapper.cpp +++ b/library/LuaWrapper.cpp @@ -36,6 +36,7 @@ distribution. #include "DataDefs.h" #include "DataIdentity.h" #include "LuaWrapper.h" +#include "LuaTools.h" #include "MiscUtils.h" @@ -402,6 +403,46 @@ static bool is_valid_metatable(lua_State *state, int objidx, int metaidx) return ok; } +bool Lua::IsDFNull(lua_State *state, int val_index) +{ + if (lua_isnil(state, val_index)) + return true; + if (lua_islightuserdata(state, val_index)) + return lua_touserdata(state, val_index) == NULL; + return false; +} + +Lua::ObjectClass Lua::IsDFObject(lua_State *state, int val_index) +{ + if (lua_isnil(state, val_index)) + return Lua::OBJ_NULL; + if (lua_islightuserdata(state, val_index)) + return lua_touserdata(state, val_index) ? Lua::OBJ_VOIDPTR : OBJ_NULL; + + Lua::ObjectClass cls; + + if (lua_istable(state, val_index)) + { + cls = Lua::OBJ_TYPE; + lua_pushvalue(state, val_index); + LookupInTable(state, &DFHACK_TYPEID_TABLE_TOKEN); + } + else if (lua_isuserdata(state, val_index)) + { + if (!lua_getmetatable(state, val_index)) + return Lua::OBJ_INVALID; + cls = Lua::OBJ_REF; + LookupInTable(state, &DFHACK_TYPETABLE_TOKEN); + } + else + return Lua::OBJ_INVALID; + + bool ok = !lua_isnil(state, -1); + lua_pop(state, 1); + + return ok ? cls : Lua::OBJ_INVALID; +} + /** * Given a DF object reference or type, safely retrieve its identity pointer. */ @@ -865,6 +906,52 @@ static int meta_enum_attr_index(lua_State *state) return 1; } +/** + * Metamethod: df.isvalid(obj[,allow_null]) + */ +static int meta_isvalid(lua_State *state) +{ + luaL_checkany(state, 1); + + switch (Lua::IsDFObject(state, 1)) + { + case Lua::OBJ_NULL: + lua_settop(state, 2); + if (lua_toboolean(state, 2)) + lua_pushvalue(state, lua_upvalueindex(1)); + else + lua_pushnil(state); + return 1; + + case Lua::OBJ_TYPE: + lua_pushvalue(state, lua_upvalueindex(2)); + return 1; + + case Lua::OBJ_VOIDPTR: + lua_pushvalue(state, lua_upvalueindex(3)); + return 1; + + case Lua::OBJ_REF: + lua_pushvalue(state, lua_upvalueindex(4)); + return 1; + + case Lua::OBJ_INVALID: + default: + lua_pushnil(state); + return 1; + } +} + +/** + * Metamethod: df.isnull(obj) + */ +static int meta_isnull(lua_State *state) +{ + luaL_checkany(state, 1); + lua_pushboolean(state, Lua::IsDFNull(state, 1)); + return 1; +} + static int meta_nodata(lua_State *state) { return 0; @@ -1221,9 +1308,15 @@ static void RenderType(lua_State *state, compound_identity *node) break; case IDTYPE_GLOBAL: + lua_pushstring(state, "global"); + lua_setfield(state, ftable, "_kind"); + { RenderTypeChildren(state, node->getScopeChildren()); + lua_pushlightuserdata(state, node); + lua_setfield(state, ftable, "_identity"); + BuildTypeMetatable(state, node); lua_dup(state); @@ -1244,6 +1337,9 @@ static void RenderType(lua_State *state, compound_identity *node) RenderTypeChildren(state, node->getScopeChildren()); + lua_pushlightuserdata(state, node); + lua_setfield(state, ftable, "_identity"); + lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_SIZEOF_NAME); lua_setfield(state, ftable, "sizeof"); @@ -1341,6 +1437,16 @@ static int DoAttach(lua_State *state) lua_pushlightuserdata(state, NULL); lua_setglobal(state, "NULL"); + lua_pushstring(state, "null"); + lua_pushstring(state, "type"); + lua_pushstring(state, "voidptr"); + lua_pushstring(state, "ref"); + lua_pushcclosure(state, meta_isvalid, 4); + lua_setfield(state, -2, "isvalid"); + + lua_pushcfunction(state, meta_isnull); + lua_setfield(state, -2, "isnull"); + freeze_table(state, false, "df"); } |
