Home | History | Annotate | Download | only in lua
      1 /* -----------------------------------------------------------------------------
      2  * lua_fnptr.i
      3  *
      4  * SWIG Library file containing the main typemap code to support Lua modules.
      5  * ----------------------------------------------------------------------------- */
      6 
      7 /* -----------------------------------------------------------------------------
      8  *                          Basic function pointer support
      9  * ----------------------------------------------------------------------------- */
     10 /*
     11 The structure: SWIGLUA_FN provides a simple (local only) wrapping for a function.
     12 
     13 For example if you wanted to have a C/C++ function take a lua function as a parameter.
     14 You could declare it as:
     15   int my_func(int a, int b, SWIGLUA_FN fn);
     16 note: it should be passed by value, not byref or as a pointer.
     17 
     18 The SWIGLUA_FN holds a pointer to the lua_State, and the stack index where the function is held.
     19 The macro SWIGLUA_FN_GET() will put a copy of the lua function at the top of the stack.
     20 After that its fairly simple to write the rest of the code (assuming know how to use lua),
     21 just push the parameters, call the function and return the result.
     22 
     23   int my_func(int a, int b, SWIGLUA_FN fn)
     24   {
     25     SWIGLUA_FN_GET(fn);
     26     lua_pushnumber(fn.L,a);
     27     lua_pushnumber(fn.L,b);
     28     lua_call(fn.L,2,1);    // 2 in, 1 out
     29     return luaL_checknumber(fn.L,-1);
     30   }
     31 
     32 SWIG will automatically performs the wrapping of the arguments in and out.
     33 
     34 However: if you wish to store the function between calls, look to the SWIGLUA_REF below.
     35 
     36 */
     37 // this is for the C code only, we don't want SWIG to wrapper it for us.
     38 %{
     39 typedef struct{
     40   lua_State* L; /* the state */
     41   int idx;      /* the index on the stack */
     42 }SWIGLUA_FN;
     43 
     44 #define SWIGLUA_FN_GET(fn) {lua_pushvalue(fn.L,fn.idx);}
     45 %}
     46 
     47 // the actual typemap
     48 %typemap(in,checkfn="lua_isfunction") SWIGLUA_FN
     49 %{  $1.L=L; $1.idx=$input; %}
     50 
     51 /* -----------------------------------------------------------------------------
     52  *                          Storing lua object support
     53  * ----------------------------------------------------------------------------- */
     54 /*
     55 The structure: SWIGLUA_REF provides a mechanism to store object (usually functions)
     56 between calls to the interpreter.
     57 
     58 For example if you wanted to have a C/C++ function take a lua function as a parameter.
     59 Then call it later, You could declare it as:
     60   SWIGLUA_REF myref;
     61   void set_func(SWIGLUA_REF ref);
     62   SWIGLUA_REF get_func();
     63   void call_func(int val);
     64 note: it should be passed by value, not byref or as a pointer.
     65 
     66 The SWIGLUA_REF holds a pointer to the lua_State, and an integer reference to the object.
     67 Because it holds a permanent ref to an object, the SWIGLUA_REF must be handled with a bit more care.
     68 It should be initialised to {0,0}. The function swiglua_ref_set() should be used to set it.
     69 swiglua_ref_clear() should be used to clear it when not in use, and swiglua_ref_get() to get the
     70 data back.
     71 
     72 Note: the typemap does not check that the object is in fact a function,
     73 if you need that you must add it yourself.
     74 
     75 
     76   int my_func(int a, int b, SWIGLUA_FN fn)
     77   {
     78     SWIGLUA_FN_GET(fn);
     79     lua_pushnumber(fn.L,a);
     80     lua_pushnumber(fn.L,b);
     81     lua_call(fn.L,2,1);    // 2 in, 1 out
     82     return luaL_checknumber(fn.L,-1);
     83   }
     84 
     85 SWIG will automatically performs the wrapping of the arguments in and out.
     86 
     87 However: if you wish to store the function between calls, look to the SWIGLUA_REF below.
     88 
     89 */
     90 
     91 %{
     92 typedef struct{
     93   lua_State* L; /* the state */
     94   int ref;      /* a ref in the lua global index */
     95 }SWIGLUA_REF;
     96 
     97 
     98 void swiglua_ref_clear(SWIGLUA_REF* pref){
     99  	if (pref->L!=0 && pref->ref!=LUA_NOREF && pref->ref!=LUA_REFNIL){
    100 		luaL_unref(pref->L,LUA_REGISTRYINDEX,pref->ref);
    101 	}
    102 	pref->L=0; pref->ref=0;
    103 }
    104 
    105 void swiglua_ref_set(SWIGLUA_REF* pref,lua_State* L,int idx){
    106 //	swiglua_ref_clear(pref); /* just in case */
    107 	pref->L=L;
    108 	lua_pushvalue(L,idx);                 /* copy obj to top */
    109 	pref->ref=luaL_ref(L,LUA_REGISTRYINDEX); /* remove obj from top & put into registry */
    110 }
    111 
    112 void swiglua_ref_get(SWIGLUA_REF* pref){
    113 	if (pref->L!=0)
    114 		lua_rawgeti(pref->L,LUA_REGISTRYINDEX,pref->ref);
    115 }
    116 
    117 %}
    118 
    119 %typemap(in) SWIGLUA_REF
    120 %{  swiglua_ref_set(&$1,L,$input); %}
    121 
    122 %typemap(out) SWIGLUA_REF
    123 %{  if ($1.L!=0)  {swiglua_ref_get(&$1);} else {lua_pushnil(L);}
    124   SWIG_arg++; %}
    125 
    126