summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--depends/lua/CMakeLists.txt7
-rw-r--r--depends/lua/include/luaconf.h15
-rw-r--r--library/CMakeLists.txt3
-rw-r--r--library/DataStaticsFields.cpp21
-rw-r--r--library/LuaWrapper.cpp218
-rw-r--r--library/include/DataDefs.h6
-rw-r--r--library/include/DataIdentity.h3
8 files changed, 267 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d39d940e..1c538e24 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -103,6 +103,7 @@ ENDIF()
# use shared libraries for protobuf
ADD_DEFINITIONS(-DPROTOBUF_USE_DLLS)
+ADD_DEFINITIONS(-DLUA_BUILD_AS_DLL)
if(UNIX)
add_definitions(-D_LINUX)
diff --git a/depends/lua/CMakeLists.txt b/depends/lua/CMakeLists.txt
index b135f221..6a97bd43 100644
--- a/depends/lua/CMakeLists.txt
+++ b/depends/lua/CMakeLists.txt
@@ -76,8 +76,13 @@ src/lzio.c
)
LIST(APPEND SRC_LIBLUA ${HDR_LIBLUA})
-ADD_LIBRARY ( lua STATIC EXCLUDE_FROM_ALL ${SRC_LIBLUA} )
+ADD_LIBRARY ( lua SHARED EXCLUDE_FROM_ALL ${SRC_LIBLUA} )
TARGET_LINK_LIBRARIES ( lua ${LIBS})
+
+install(TARGETS lua
+ LIBRARY DESTINATION ${DFHACK_LIBRARY_DESTINATION}
+ RUNTIME DESTINATION ${DFHACK_LIBRARY_DESTINATION})
+
IDE_FOLDER(lua "Depends")
#SET ( SRC_LUA src/lua.c )
diff --git a/depends/lua/include/luaconf.h b/depends/lua/include/luaconf.h
index 66079335..b202967b 100644
--- a/depends/lua/include/luaconf.h
+++ b/depends/lua/include/luaconf.h
@@ -151,11 +151,20 @@
** the libraries, you may want to use the following definition (define
** LUA_BUILD_AS_DLL to get it).
*/
+#ifdef __cplusplus
+ #define LUA_API_EXTERN extern "C"
+#else
+ #define LUA_API_EXTERN extern
+#endif
#if defined(LUA_BUILD_AS_DLL)
- #if defined(LUA_CORE) || defined(LUA_LIB)
- #define LUA_API __declspec(dllexport)
+ #if defined(_MSC_VER)
+ #if defined(LUA_CORE) || defined(LUA_LIB)
+ #define LUA_API __declspec(dllexport) LUA_API_EXTERN
+ #else
+ #define LUA_API __declspec(dllimport) LUA_API_EXTERN
+ #endif
#else
- #define LUA_API __declspec(dllimport)
+ #define LUA_API LUA_API_EXTERN __attribute__ ((visibility("default")))
#endif
#else
#ifdef __cplusplus
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 7d3c4d6b..3b1c6e7b 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -55,6 +55,7 @@ SET(MAIN_SOURCES
Core.cpp
ColorText.cpp
DataDefs.cpp
+LuaWrapper.cpp
DataStatics.cpp
DataStaticsCtor.cpp
DataStaticsFields.cpp
@@ -251,7 +252,7 @@ ENDIF()
#effectively disables debug builds...
SET_TARGET_PROPERTIES(dfhack PROPERTIES DEBUG_POSTFIX "-debug" )
-TARGET_LINK_LIBRARIES(dfhack protobuf-lite clsocket ${PROJECT_LIBS})
+TARGET_LINK_LIBRARIES(dfhack protobuf-lite clsocket lua ${PROJECT_LIBS})
SET_TARGET_PROPERTIES(dfhack PROPERTIES LINK_INTERFACE_LIBRARIES "")
TARGET_LINK_LIBRARIES(dfhack-client protobuf-lite clsocket)
diff --git a/library/DataStaticsFields.cpp b/library/DataStaticsFields.cpp
index 0e6e9957..a9d2f312 100644
--- a/library/DataStaticsFields.cpp
+++ b/library/DataStaticsFields.cpp
@@ -13,6 +13,27 @@
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
+namespace df {
+#define ATOM_IDENTITY_TRAITS(type) \
+ primitive_identity identity_traits<type>::identity(sizeof(type));
+
+ ATOM_IDENTITY_TRAITS(char);
+ ATOM_IDENTITY_TRAITS(int8_t);
+ ATOM_IDENTITY_TRAITS(uint8_t);
+ ATOM_IDENTITY_TRAITS(int16_t);
+ ATOM_IDENTITY_TRAITS(uint16_t);
+ ATOM_IDENTITY_TRAITS(int32_t);
+ ATOM_IDENTITY_TRAITS(uint32_t);
+ ATOM_IDENTITY_TRAITS(int64_t);
+ ATOM_IDENTITY_TRAITS(uint64_t);
+ ATOM_IDENTITY_TRAITS(bool);
+ ATOM_IDENTITY_TRAITS(float);
+ ATOM_IDENTITY_TRAITS(std::string);
+ ATOM_IDENTITY_TRAITS(void*);
+
+#undef ATOM_IDENTITY_TRAITS
+}
+
#define TID(type) (&identity_traits< type >::identity)
#define FLD(mode, name) struct_field_info::mode, #name, offsetof(CUR_STRUCT, name)
diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp
new file mode 100644
index 00000000..3ed4a35c
--- /dev/null
+++ b/library/LuaWrapper.cpp
@@ -0,0 +1,218 @@
+/*
+https://github.com/peterix/dfhack
+Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include "Internal.h"
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "MemAccess.h"
+#include "Core.h"
+#include "VersionInfo.h"
+#include "tinythread.h"
+// must be last due to MS stupidity
+#include "DataDefs.h"
+#include "DataIdentity.h"
+
+#include "MiscUtils.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+using namespace DFHack;
+
+static luaL_Reg no_functions[] = { { NULL, NULL } };
+
+inline void lua_dup(lua_State *state) { lua_pushvalue(state, -1); }
+inline void lua_swap(lua_State *state) { lua_insert(state, -2); }
+
+static int change_error(lua_State *state)
+{
+ luaL_error(state, "Attempt to change a read-only table.\n");
+}
+
+static void freeze_table(lua_State *state, bool leave_metatable = false, const char *name = NULL)
+{
+ // rv = {}; setmetatable(rv, { __index = in, __newindex = change_error, __metatable = name })
+ int base = lua_gettop(state);
+ lua_newtable(state);
+ lua_swap(state);
+ lua_setfield(state, base, "__index");
+ lua_getfield(state, LUA_REGISTRYINDEX, "DFHack.ChangeError");
+ lua_setfield(state, base, "__newindex");
+ lua_newtable(state);
+ lua_swap(state);
+ lua_dup(state);
+ lua_setmetatable(state, base);
+ if (name)
+ {
+ lua_pushstring(state, name);
+ lua_setfield(state, -2, "__metatable");
+ }
+ // result: [frozen table] [metatable]
+ if (!leave_metatable)
+ lua_pop(state, 1);
+}
+
+static void SaveTypeInfo(lua_State *state, void *node)
+{
+ lua_getfield(state, LUA_REGISTRYINDEX, "DFHack.DFTypes");
+ lua_pushlightuserdata(state, node);
+ lua_pushvalue(state, -3);
+ lua_settable(state, -3);
+ lua_pop(state, 1);
+}
+
+static bool RegisterTypeInfo(lua_State *state, void *node)
+{
+ lua_getfield(state, LUA_REGISTRYINDEX, "DFHack.DFTypes");
+ int base = lua_gettop(state);
+
+ lua_pushlightuserdata(state, node);
+ lua_rawget(state, base);
+
+ bool added = false;
+
+ if (lua_isnil(state, -1))
+ {
+ lua_pop(state, 1);
+
+ lua_newtable(state);
+ lua_pushlightuserdata(state, node);
+ lua_pushvalue(state, -2);
+ lua_rawset(state, base);
+
+ added = true;
+ }
+
+ lua_remove(state, -2);
+ return added;
+}
+
+static void RenderTypeChildren(lua_State *state, const std::vector<compound_identity*> &children);
+
+static void RenderType(lua_State *state, compound_identity *node)
+{
+ assert(node->getName());
+
+ lua_newtable(state);
+ if (!lua_checkstack(state, 20))
+ return;
+
+ int base = lua_gettop(state);
+
+ lua_pushlightuserdata(state, node);
+ lua_setfield(state, base, "_identity");
+
+ switch (node->type())
+ {
+ case IDTYPE_ENUM:
+ {
+ enum_identity *eid = (enum_identity*)node;
+ const char *const *keys = eid->getKeys();
+
+ // For enums, set mapping between keys and values
+ for (int64_t i = eid->getFirstItem(), j = 0; i <= eid->getLastItem(); i++, j++)
+ {
+ if (!keys[j])
+ continue;
+
+ lua_pushinteger(state, i);
+ lua_pushstring(state, keys[j]);
+ lua_dup(state);
+ lua_pushinteger(state, i);
+
+ lua_settable(state, base);
+ lua_settable(state, base);
+ }
+
+ if (eid->getFirstItem() <= eid->getLastItem())
+ {
+ lua_pushstring(state, "_first_item");
+ lua_pushinteger(state, eid->getFirstItem());
+ lua_settable(state, base);
+
+ lua_pushstring(state, "_last_item");
+ lua_pushinteger(state, eid->getLastItem());
+ lua_settable(state, base);
+ }
+
+ SaveTypeInfo(state, node);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ RenderTypeChildren(state, node->getScopeChildren());
+
+ assert(base == lua_gettop(state));
+
+ freeze_table(state, false, node->getName());
+}
+
+static void RenderTypeChildren(lua_State *state, const std::vector<compound_identity*> &children)
+{
+ for (size_t i = 0; i < children.size(); i++)
+ {
+ RenderType(state, children[i]);
+ lua_pushstring(state, children[i]->getName());
+ lua_swap(state);
+ lua_settable(state, -3);
+ }
+}
+
+static void DoAttach(lua_State *state)
+{
+ int base = lua_gettop(state);
+
+ lua_pushcfunction(state, change_error);
+ lua_setfield(state, LUA_REGISTRYINDEX, "DFHack.ChangeError");
+
+ luaL_register(state, "df", no_functions);
+
+ {
+ // Assign df a metatable with read-only contents
+ lua_newtable(state);
+
+ // Render the type structure
+ RenderTypeChildren(state, compound_identity::getTopScope());
+
+ freeze_table(state, true, "df");
+ lua_remove(state, -2);
+ lua_setmetatable(state, -2);
+ }
+
+ lua_pop(state, 1);
+}
+
+void DFHack::AttachDFGlobals(lua_State *state)
+{
+ if (luaL_newmetatable(state, "DFHack.DFTypes"))
+ DoAttach(state);
+
+ lua_pop(state, 1);
+}
diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h
index 2a956718..3a7679b6 100644
--- a/library/include/DataDefs.h
+++ b/library/include/DataDefs.h
@@ -37,6 +37,8 @@ distribution.
#undef interface
#endif
+typedef struct lua_State lua_State;
+
/*
* Definitions of DFHack namespace structs used by generated headers.
*/
@@ -155,6 +157,8 @@ namespace DFHack
virtual identity_type type() { return IDTYPE_ENUM; }
+ int64_t getFirstItem() { return first_item_value; }
+ int64_t getLastItem() { return last_item_value; }
int getCount() { return int(last_item_value-first_item_value+1); }
const char *const *getKeys() { return keys; }
};
@@ -280,6 +284,8 @@ namespace DFHack
void InitDataDefGlobals(Core *core);
+ DFHACK_EXPORT void AttachDFGlobals(lua_State *state);
+
template<class T>
T *ifnull(T *a, T *b) { return a ? a : b; }
diff --git a/library/include/DataIdentity.h b/library/include/DataIdentity.h
index 679023fc..d354beb0 100644
--- a/library/include/DataIdentity.h
+++ b/library/include/DataIdentity.h
@@ -65,8 +65,7 @@ namespace df
template<> struct identity_traits<type> { \
static primitive_identity identity; \
static primitive_identity *get() { return &identity; } \
- }; \
- primitive_identity identity_traits<type>::identity(sizeof(type));
+ };
ATOM_IDENTITY_TRAITS(char);
ATOM_IDENTITY_TRAITS(int8_t);