summaryrefslogtreecommitdiff
path: root/library/LuaWrapper.cpp
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-06-13 22:26:54 +0400
committerAlexander Gavrilov2012-06-13 22:26:54 +0400
commitc50b605dfc2024bf5bca7d6dfb18fc266b358978 (patch)
treee291e605812c0c82d0349dac8b074177afd9e2bb /library/LuaWrapper.cpp
parent8d7cf092fd6f3f1cf68e6b48b8f3dc42ef40dcfa (diff)
downloaddfhack-c50b605dfc2024bf5bca7d6dfb18fc266b358978.tar.gz
dfhack-c50b605dfc2024bf5bca7d6dfb18fc266b358978.tar.bz2
dfhack-c50b605dfc2024bf5bca7d6dfb18fc266b358978.tar.xz
Support casting references and allocating arrays of numbers in lua wrapper.
Diffstat (limited to 'library/LuaWrapper.cpp')
-rw-r--r--library/LuaWrapper.cpp89
1 files changed, 84 insertions, 5 deletions
diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp
index 471dba64..7c15a27a 100644
--- a/library/LuaWrapper.cpp
+++ b/library/LuaWrapper.cpp
@@ -447,10 +447,21 @@ Lua::ObjectClass Lua::IsDFObject(lua_State *state, int val_index)
}
static const char *const primitive_types[] = {
- "string", NULL
+ "string",
+ "int8_t", "uint8_t", "int16_t", "uint16_t",
+ "int32_t", "uint32_t", "int64_t", "uint64_t",
+ "bool", "float", "double",
+ NULL
};
static type_identity *const primitive_identities[] = {
- df::identity_traits<std::string>::get(), NULL
+ df::identity_traits<std::string>::get(),
+ df::identity_traits<int8_t>::get(), df::identity_traits<uint8_t>::get(),
+ df::identity_traits<int16_t>::get(), df::identity_traits<uint16_t>::get(),
+ df::identity_traits<int32_t>::get(), df::identity_traits<uint32_t>::get(),
+ df::identity_traits<int64_t>::get(), df::identity_traits<uint64_t>::get(),
+ df::identity_traits<bool>::get(),
+ df::identity_traits<float>::get(), df::identity_traits<double>::get(),
+ NULL
};
/**
@@ -644,12 +655,32 @@ static int meta_new(lua_State *state)
{
int argc = lua_gettop(state);
- if (argc != 1)
- luaL_error(state, "Usage: object:new() or df.new(object)");
+ if (argc != 1 && argc != 2)
+ luaL_error(state, "Usage: object:new() or df.new(object) or df.new(ptype,count)");
type_identity *id = get_object_identity(state, 1, "df.new()", true);
- void *ptr = id->allocate();
+ void *ptr;
+
+ // Support arrays of primitive types
+ if (argc == 2)
+ {
+ int cnt = luaL_checkint(state, 2);
+ if (cnt <= 0)
+ luaL_error(state, "Invalid array size in df.new()");
+ if (id->type() != IDTYPE_PRIMITIVE)
+ luaL_error(state, "Cannot allocate arrays of non-primitive types.");
+
+ size_t sz = id->byte_size() * cnt;
+ ptr = malloc(sz);
+ if (ptr)
+ memset(ptr, 0, sz);
+ }
+ else
+ {
+ ptr = id->allocate();
+ }
+
if (!ptr)
luaL_error(state, "Cannot allocate %s", id->getFullName().c_str());
@@ -666,6 +697,48 @@ static int meta_new(lua_State *state)
return 1;
}
+/**
+ * Method: type casting of pointers.
+ */
+static int meta_reinterpret_cast(lua_State *state)
+{
+ int argc = lua_gettop(state);
+
+ if (argc != 2)
+ luaL_error(state, "Usage: df.reinterpret_cast(type,ptr)");
+
+ type_identity *id = get_object_identity(state, 1, "df.reinterpret_cast()", true);
+
+ // Find the raw pointer value
+ void *ptr;
+
+ if (lua_isnil(state, 2))
+ ptr = NULL;
+ else if (lua_isnumber(state, 2))
+ ptr = (void*)lua_tointeger(state, 2);
+ else
+ {
+ ptr = get_object_internal(state, NULL, 2, false, true);
+ if (!ptr)
+ luaL_error(state, "Invalid pointer argument in df.reinterpret_cast.\n");
+ }
+
+ // Convert it to the appropriate representation
+ if (ptr == NULL)
+ {
+ lua_pushnil(state);
+ }
+ else if (lua_isuserdata(state, 1))
+ {
+ lua_getmetatable(state, 1);
+ push_object_ref(state, ptr);
+ }
+ else
+ push_object_internal(state, id, ptr);
+
+ return 1;
+}
+
static void invoke_resize(lua_State *state, int table, lua_Integer size)
{
lua_getfield(state, table, "resize");
@@ -1433,6 +1506,10 @@ static int DoAttach(lua_State *state)
lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_NEW_NAME);
lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN);
+ lua_pushcclosure(state, meta_reinterpret_cast, 1);
+ lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_CAST_NAME);
+
+ lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN);
lua_pushcclosure(state, meta_assign, 1);
lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_ASSIGN_NAME);
@@ -1463,6 +1540,8 @@ static int DoAttach(lua_State *state)
lua_setfield(state, -2, "assign");
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_IS_INSTANCE_NAME);
lua_setfield(state, -2, "is_instance");
+ lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_CAST_NAME);
+ lua_setfield(state, -2, "reinterpret_cast");
lua_pushlightuserdata(state, NULL);
lua_setfield(state, -2, "NULL");