Experimental: try wrapping a dfhack api function.

develop
Alexander Gavrilov 2012-04-05 11:59:39 +04:00
parent d1b27418a6
commit 3afed43cdb
5 changed files with 43 additions and 6 deletions

@ -35,14 +35,18 @@ distribution.
// must be last due to MS stupidity // must be last due to MS stupidity
#include "DataDefs.h" #include "DataDefs.h"
#include "DataIdentity.h" #include "DataIdentity.h"
#include "DataFuncs.h"
#include "modules/World.h" #include "modules/World.h"
#include "modules/Gui.h"
#include "LuaWrapper.h" #include "LuaWrapper.h"
#include "LuaTools.h" #include "LuaTools.h"
#include "MiscUtils.h" #include "MiscUtils.h"
#include "df/job.h"
#include <lua.h> #include <lua.h>
#include <lauxlib.h> #include <lauxlib.h>
#include <lualib.h> #include <lualib.h>
@ -868,6 +872,8 @@ lua_State *DFHack::Lua::Open(color_ostream &out, lua_State *state)
OpenPersistent(state); OpenPersistent(state);
LuaWrapper::AddMethodWrapper(state, 0, -1, "getSelectedJob", df::wrap_function(&Gui::getSelectedJob));
lua_setglobal(state, "dfhack"); lua_setglobal(state, "dfhack");
// load dfhack.lua // load dfhack.lua

@ -1029,11 +1029,16 @@ static int meta_call_function(lua_State *state)
/** /**
* Create a closure invoking the given function, and add it to the field table. * Create a closure invoking the given function, and add it to the field table.
*/ */
static void AddMethodWrapper(lua_State *state, int meta_idx, int field_idx, void LuaWrapper::AddMethodWrapper(lua_State *state, int meta_idx, int field_idx,
const char *name, function_identity_base *fun) const char *name, function_identity_base *fun)
{ {
field_idx = lua_absindex(state, field_idx);
lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN);
if (meta_idx)
lua_pushvalue(state, meta_idx); lua_pushvalue(state, meta_idx);
else
lua_pushlightuserdata(state, NULL); // can't be a metatable
lua_pushfstring(state, "%s()", name); lua_pushfstring(state, "%s()", name);
lua_pushlightuserdata(state, fun); lua_pushlightuserdata(state, fun);
lua_pushcclosure(state, meta_call_function, 4); lua_pushcclosure(state, meta_call_function, 4);

@ -53,6 +53,9 @@ static luaL_Reg no_functions[] = { { NULL, NULL } };
*/ */
void LuaWrapper::field_error(lua_State *state, int index, const char *err, const char *mode) void LuaWrapper::field_error(lua_State *state, int index, const char *err, const char *mode)
{ {
if (lua_islightuserdata(state, UPVAL_METATABLE))
lua_pushstring(state, "(global)");
else
lua_getfield(state, UPVAL_METATABLE, "__metatable"); lua_getfield(state, UPVAL_METATABLE, "__metatable");
const char *cname = lua_tostring(state, -1); const char *cname = lua_tostring(state, -1);
const char *fname = index ? lua_tostring(state, index) : "*"; const char *fname = index ? lua_tostring(state, index) : "*";

@ -67,10 +67,15 @@ namespace df {
CT *self = (CT*)DFHack::LuaWrapper::get_object_addr(state, base++, UPVAL_METHOD_NAME, "invoke"); CT *self = (CT*)DFHack::LuaWrapper::get_object_addr(state, base++, UPVAL_METHOD_NAME, "invoke");
#define LOAD_ARG(type) \ #define LOAD_ARG(type) \
type v##type; df::identity_traits<type>::get()->lua_write(state, UPVAL_METHOD_NAME, &v##type, base++); type v##type; df::identity_traits<type>::get()->lua_write(state, UPVAL_METHOD_NAME, &v##type, base++);
#define OSTREAM_ARG DFHack::color_ostream&
#define LOAD_OSTREAM(name) \
DFHack::color_ostream_proxy name(DFHack::Core::getInstance().getConsole());
#define INSTANTIATE_WRAPPERS(Count, FArgs, Args, Loads) \ #define INSTANTIATE_RETURN_TYPE(FArgs) \
template<FW_TARGSC class RT> struct return_type<RT (*) FArgs> { typedef RT type; }; \ template<FW_TARGSC class RT> struct return_type<RT (*) FArgs> { typedef RT type; }; \
template<FW_TARGSC class RT, class CT> struct return_type<RT (CT::*) FArgs> { typedef RT type; }; \ template<FW_TARGSC class RT, class CT> struct return_type<RT (CT::*) FArgs> { typedef RT type; };
#define INSTANTIATE_WRAPPERS(Count, FArgs, Args, Loads) \
template<FW_TARGS> struct function_wrapper<void (*) FArgs, true> { \ template<FW_TARGS> struct function_wrapper<void (*) FArgs, true> { \
static const bool is_method = false; \ static const bool is_method = false; \
static const int num_args = Count; \ static const int num_args = Count; \
@ -96,24 +101,35 @@ namespace df {
#define FW_TARGSC #define FW_TARGSC
#define FW_TARGS #define FW_TARGS
INSTANTIATE_RETURN_TYPE(())
INSTANTIATE_WRAPPERS(0, (), (), ;) INSTANTIATE_WRAPPERS(0, (), (), ;)
INSTANTIATE_WRAPPERS(0, (OSTREAM_ARG), (out), LOAD_OSTREAM(out);)
#undef FW_TARGS #undef FW_TARGS
#undef FW_TARGSC #undef FW_TARGSC
#define FW_TARGSC FW_TARGS, #define FW_TARGSC FW_TARGS,
#define FW_TARGS class A1 #define FW_TARGS class A1
INSTANTIATE_RETURN_TYPE((A1))
INSTANTIATE_WRAPPERS(1, (A1), (vA1), LOAD_ARG(A1);) INSTANTIATE_WRAPPERS(1, (A1), (vA1), LOAD_ARG(A1);)
INSTANTIATE_WRAPPERS(1, (OSTREAM_ARG,A1), (out,vA1), LOAD_OSTREAM(out); LOAD_ARG(A1);)
#undef FW_TARGS #undef FW_TARGS
#define FW_TARGS class A1, class A2 #define FW_TARGS class A1, class A2
INSTANTIATE_RETURN_TYPE((A1,A2))
INSTANTIATE_WRAPPERS(2, (A1,A2), (vA1,vA2), LOAD_ARG(A1); LOAD_ARG(A2);) INSTANTIATE_WRAPPERS(2, (A1,A2), (vA1,vA2), LOAD_ARG(A1); LOAD_ARG(A2);)
INSTANTIATE_WRAPPERS(2, (OSTREAM_ARG,A1,A2), (out,vA1,vA2),
LOAD_OSTREAM(out); LOAD_ARG(A1); LOAD_ARG(A2);)
#undef FW_TARGS #undef FW_TARGS
#define FW_TARGS class A1, class A2, class A3 #define FW_TARGS class A1, class A2, class A3
INSTANTIATE_RETURN_TYPE((A1,A2,A3))
INSTANTIATE_WRAPPERS(3, (A1,A2,A3), (vA1,vA2,vA3), LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3);) INSTANTIATE_WRAPPERS(3, (A1,A2,A3), (vA1,vA2,vA3), LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3);)
INSTANTIATE_WRAPPERS(3, (OSTREAM_ARG,A1,A2,A3), (out,vA1,vA2,vA3),
LOAD_OSTREAM(out); LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3);)
#undef FW_TARGS #undef FW_TARGS
#define FW_TARGS class A1, class A2, class A3, class A4 #define FW_TARGS class A1, class A2, class A3, class A4
INSTANTIATE_RETURN_TYPE((A1,A2,A3,A4))
INSTANTIATE_WRAPPERS(4, (A1,A2,A3,A4), (vA1,vA2,vA3,vA4), INSTANTIATE_WRAPPERS(4, (A1,A2,A3,A4), (vA1,vA2,vA3,vA4),
LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4);) LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4);)
#undef FW_TARGS #undef FW_TARGS
@ -124,6 +140,8 @@ INSTANTIATE_WRAPPERS(4, (A1,A2,A3,A4), (vA1,vA2,vA3,vA4),
#undef INVOKE_RV #undef INVOKE_RV
#undef LOAD_CLASS #undef LOAD_CLASS
#undef LOAD_ARG #undef LOAD_ARG
#undef OSTREAM_ARG
#undef LOAD_OSTREAM
template<class T> template<class T>
class function_identity : public function_identity_base { class function_identity : public function_identity_base {

@ -220,6 +220,11 @@ namespace DFHack { namespace LuaWrapper {
* and the enum itself to the _enum metafield. Pushes the key table on the stack. * and the enum itself to the _enum metafield. Pushes the key table on the stack.
*/ */
void AttachEnumKeys(lua_State *state, int meta_idx, int ftable_idx, type_identity *ienum); void AttachEnumKeys(lua_State *state, int meta_idx, int ftable_idx, type_identity *ienum);
/**
* Create a closure invoking the given function, and add it to the field table.
*/
void AddMethodWrapper(lua_State *state, int meta_idx, int field_idx,
const char *name, function_identity_base *fun);
void IndexStatics(lua_State *state, int meta_idx, int ftable_idx, struct_identity *pstruct); void IndexStatics(lua_State *state, int meta_idx, int ftable_idx, struct_identity *pstruct);