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
#include "DataDefs.h"
#include "DataIdentity.h"
#include "DataFuncs.h"
#include "modules/World.h"
#include "modules/Gui.h"
#include "LuaWrapper.h"
#include "LuaTools.h"
#include "MiscUtils.h"
#include "df/job.h"
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
@ -868,6 +872,8 @@ lua_State *DFHack::Lua::Open(color_ostream &out, lua_State *state)
OpenPersistent(state);
LuaWrapper::AddMethodWrapper(state, 0, -1, "getSelectedJob", df::wrap_function(&Gui::getSelectedJob));
lua_setglobal(state, "dfhack");
// 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.
*/
static void AddMethodWrapper(lua_State *state, int meta_idx, int field_idx,
const char *name, function_identity_base *fun)
void LuaWrapper::AddMethodWrapper(lua_State *state, int meta_idx, int field_idx,
const char *name, function_identity_base *fun)
{
field_idx = lua_absindex(state, field_idx);
lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN);
lua_pushvalue(state, meta_idx);
if (meta_idx)
lua_pushvalue(state, meta_idx);
else
lua_pushlightuserdata(state, NULL); // can't be a metatable
lua_pushfstring(state, "%s()", name);
lua_pushlightuserdata(state, fun);
lua_pushcclosure(state, meta_call_function, 4);

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

@ -67,10 +67,15 @@ namespace df {
CT *self = (CT*)DFHack::LuaWrapper::get_object_addr(state, base++, UPVAL_METHOD_NAME, "invoke");
#define LOAD_ARG(type) \
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, 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> { \
static const bool is_method = false; \
static const int num_args = Count; \
@ -96,24 +101,35 @@ namespace df {
#define FW_TARGSC
#define FW_TARGS
INSTANTIATE_RETURN_TYPE(())
INSTANTIATE_WRAPPERS(0, (), (), ;)
INSTANTIATE_WRAPPERS(0, (OSTREAM_ARG), (out), LOAD_OSTREAM(out);)
#undef FW_TARGS
#undef FW_TARGSC
#define FW_TARGSC FW_TARGS,
#define FW_TARGS class A1
INSTANTIATE_RETURN_TYPE((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
#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, (OSTREAM_ARG,A1,A2), (out,vA1,vA2),
LOAD_OSTREAM(out); LOAD_ARG(A1); LOAD_ARG(A2);)
#undef FW_TARGS
#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, (OSTREAM_ARG,A1,A2,A3), (out,vA1,vA2,vA3),
LOAD_OSTREAM(out); LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3);)
#undef FW_TARGS
#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),
LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4);)
#undef FW_TARGS
@ -124,6 +140,8 @@ INSTANTIATE_WRAPPERS(4, (A1,A2,A3,A4), (vA1,vA2,vA3,vA4),
#undef INVOKE_RV
#undef LOAD_CLASS
#undef LOAD_ARG
#undef OSTREAM_ARG
#undef LOAD_OSTREAM
template<class T>
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.
*/
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);