You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
4.3 KiB
129 lines
4.3 KiB
5 years ago
|
/* -----------------------------------------------------------------------------
|
||
|
* See the LICENSE file for information on copyright, usage and redistribution
|
||
|
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
|
||
|
*
|
||
|
* lua_fnptr.i
|
||
|
*
|
||
|
* SWIG Library file containing the main typemap code to support Lua modules.
|
||
|
* ----------------------------------------------------------------------------- */
|
||
|
|
||
|
/* -----------------------------------------------------------------------------
|
||
|
* Basic function pointer support
|
||
|
* ----------------------------------------------------------------------------- */
|
||
|
/*
|
||
|
The structure: SWIGLUA_FN provides a simple (local only) wrappering for a function.
|
||
|
|
||
|
For example if you wanted to have a C/C++ function take a lua function as a parameter.
|
||
|
You could declare it as:
|
||
|
int my_func(int a, int b, SWIGLUA_FN fn);
|
||
|
note: it should be passed by value, not byref or as a pointer.
|
||
|
|
||
|
The SWIGLUA_FN holds a pointer to the lua_State, and the stack index where the function is held.
|
||
|
The macro SWIGLUA_FN_GET() will put a copy of the lua function at the top of the stack.
|
||
|
After that its fairly simple to write the rest of the code (assuming know how to use lua),
|
||
|
just push the parameters, call the function and return the result.
|
||
|
|
||
|
int my_func(int a, int b, SWIGLUA_FN fn)
|
||
|
{
|
||
|
SWIGLUA_FN_GET(fn);
|
||
|
lua_pushnumber(fn.L,a);
|
||
|
lua_pushnumber(fn.L,b);
|
||
|
lua_call(fn.L,2,1); // 2 in, 1 out
|
||
|
return luaL_checknumber(fn.L,-1);
|
||
|
}
|
||
|
|
||
|
SWIG will automatically performs the wrappering of the arguments in and out.
|
||
|
|
||
|
However: if you wish to store the function between calls, look to the SWIGLUA_REF below.
|
||
|
|
||
|
*/
|
||
|
// this is for the C code only, we don't want SWIG to wrapper it for us.
|
||
|
%{
|
||
|
typedef struct{
|
||
|
lua_State* L; /* the state */
|
||
|
int idx; /* the index on the stack */
|
||
|
}SWIGLUA_FN;
|
||
|
|
||
|
#define SWIGLUA_FN_GET(fn) {lua_pushvalue(fn.L,fn.idx);}
|
||
|
%}
|
||
|
|
||
|
// the actual typemap
|
||
|
%typemap(in,checkfn="lua_isfunction") SWIGLUA_FN
|
||
|
%{ $1.L=L; $1.idx=$input; %}
|
||
|
|
||
|
/* -----------------------------------------------------------------------------
|
||
|
* Storing lua object support
|
||
|
* ----------------------------------------------------------------------------- */
|
||
|
/*
|
||
|
The structure: SWIGLUA_REF provides a mechanism to store object (usually functions)
|
||
|
between calls to the interpreter.
|
||
|
|
||
|
For example if you wanted to have a C/C++ function take a lua function as a parameter.
|
||
|
Then call it later, You could declare it as:
|
||
|
SWIGLUA_REF myref;
|
||
|
void set_func(SWIGLUA_REF ref);
|
||
|
SWIGLUA_REF get_func();
|
||
|
void call_func(int val);
|
||
|
note: it should be passed by value, not byref or as a pointer.
|
||
|
|
||
|
The SWIGLUA_REF holds a pointer to the lua_State, and an integer reference to the object.
|
||
|
Because it holds a permenet ref to an object, the SWIGLUA_REF must be handled with a bit more care.
|
||
|
It should be initalised to {0,0}. The function swiglua_ref_set() should be used to set it.
|
||
|
swiglua_ref_clear() should be used to clear it when not in use, and swiglua_ref_get() to get the
|
||
|
data back.
|
||
|
|
||
|
Note: the typemap does not check that the object is in fact a function,
|
||
|
if you need that you must add it yourself.
|
||
|
|
||
|
|
||
|
int my_func(int a, int b, SWIGLUA_FN fn)
|
||
|
{
|
||
|
SWIGLUA_FN_GET(fn);
|
||
|
lua_pushnumber(fn.L,a);
|
||
|
lua_pushnumber(fn.L,b);
|
||
|
lua_call(fn.L,2,1); // 2 in, 1 out
|
||
|
return luaL_checknumber(fn.L,-1);
|
||
|
}
|
||
|
|
||
|
SWIG will automatically performs the wrappering of the arguments in and out.
|
||
|
|
||
|
However: if you wish to store the function between calls, look to the SWIGLUA_REF below.
|
||
|
|
||
|
*/
|
||
|
|
||
|
%{
|
||
|
typedef struct{
|
||
|
lua_State* L; /* the state */
|
||
|
int ref; /* a ref in the lua global index */
|
||
|
}SWIGLUA_REF;
|
||
|
|
||
|
|
||
|
void swiglua_ref_clear(SWIGLUA_REF* pref){
|
||
|
if (pref->L!=0 && pref->ref!=LUA_NOREF && pref->ref!=LUA_REFNIL){
|
||
|
luaL_unref(pref->L,LUA_REGISTRYINDEX,pref->ref);
|
||
|
}
|
||
|
pref->L=0; pref->ref=0;
|
||
|
}
|
||
|
|
||
|
void swiglua_ref_set(SWIGLUA_REF* pref,lua_State* L,int idx){
|
||
|
// swiglua_ref_clear(pref); /* just in case */
|
||
|
pref->L=L;
|
||
|
lua_pushvalue(L,idx); /* copy obj to top */
|
||
|
pref->ref=luaL_ref(L,LUA_REGISTRYINDEX); /* remove obj from top & put into registry */
|
||
|
}
|
||
|
|
||
|
void swiglua_ref_get(SWIGLUA_REF* pref){
|
||
|
if (pref->L!=0)
|
||
|
lua_rawgeti(pref->L,LUA_REGISTRYINDEX,pref->ref);
|
||
|
}
|
||
|
|
||
|
%}
|
||
|
|
||
|
%typemap(in) SWIGLUA_REF
|
||
|
%{ swiglua_ref_set(&$1,L,$input); %}
|
||
|
|
||
|
%typemap(out) SWIGLUA_REF
|
||
|
%{ if ($1.L!=0) {swiglua_ref_get(&$1);} else {lua_pushnil(L);}
|
||
|
SWIG_arg++; %}
|
||
|
|