1899
|
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
|