]>
git.r.bdr.sh - rbdr/pico-engine/blob - LuaScript.cpp
1 // ---------------------------------------------------------------------------
2 // FILE NAME : LuaScript.cpp
3 // ---------------------------------------------------------------------------
6 // Simple debugging routines
8 // ---------------------------------------------------------------------------
11 // AUTHOR : Richard Shephard
12 // ---------------------------------------------------------------------------
13 // LIBRARY INCLUDE FILES
16 #include "luascript.h"
17 #include "luarestorestack.h"
19 // ---------------------------------------------------------------------------
21 #define BEGIN_LUA_CHECK(vm) lua_State *state = (lua_State *) vm; \
23 #define END_LUA_CHECK }
26 //============================================================================
28 //---------------------------------------------------------------------------
29 // Lua C-API calling that figures out which object to hand over to
31 // Parameter Dir Description
32 // --------- --- -----------
33 // lua IN State variable
37 // Number of return varaibles on the stack
41 // This is the function lua calls for each C-Function that is
42 // registered with lua. At the time of registering the function
43 // with lua, we make lua record the method "number" so we can
44 // know what method was actually called. The lua stack is the
45 // following structure:
47 // 1 - ...: parameters passed in
49 //============================================================================
50 static int LuaCallback (lua_State
*lua
)
52 // Locate the psudo-index for the function number
53 int iNumberIdx
= lua_upvalueindex (1);
56 bool fSuccess
= false;
58 // Check for the "this" table
59 if (lua_istable (lua
, 1))
61 // Found the "this" table. The object pointer is at the index 0
62 lua_rawgeti (lua
, 1, 0);
64 if (lua_islightuserdata (lua
, -1))
66 // Found the pointer, need to cast it
67 CLuaScript
*pThis
= (CLuaScript
*) lua_touserdata (lua
, -1);
69 // Get the method index
70 int iMethodIdx
= (int) lua_tonumber (lua
, iNumberIdx
);
72 // Check that the method is correct index
73 assert (!(iMethodIdx
> pThis
->methods ()));
75 // Reformat the stack so our parameters are correct
76 // Clean up the "this" table
78 // Clean up the pThis pointer
82 nRetsOnStack
= pThis
->ScriptCalling (pThis
->vm (), iMethodIdx
);
88 if (fSuccess
== false)
90 lua_pushstring (lua
, "LuaCallback -> Failed to call the class function");
94 // Number of return variables
99 //============================================================================
100 // CLuaScript::CLuaScript
101 //---------------------------------------------------------------------------
102 // Constructor. Sets up the lua stack and the "this" table
104 // Parameter Dir Description
105 // --------- --- -----------
106 // CLuaVirtualMachine IN VM to run on
112 //============================================================================
113 CLuaScript::CLuaScript (CLuaVirtualMachine
& vm
)
114 : m_vm (vm
), m_nMethods (0), m_iThisRef (0), m_nArgs (0)
117 // Create a reference to the "this" table. Each reference is unique
118 lua_newtable (state
);
119 m_iThisRef
= luaL_ref (state
, LUA_REGISTRYINDEX
);
121 // Save the "this" table to index 0 of the "this" table
122 CLuaRestoreStack
rs (vm
);
123 lua_rawgeti (state
, LUA_REGISTRYINDEX
, m_iThisRef
);
124 lua_pushlightuserdata (state
, (void *) this);
125 lua_rawseti (state
, -2, 0);
129 //============================================================================
130 // CLuaScript::~CLuaScript
131 //---------------------------------------------------------------------------
134 // Parameter Dir Description
135 // --------- --- -----------
142 //============================================================================
143 CLuaScript::~CLuaScript (void)
145 CLuaRestoreStack
rs (m_vm
);
147 BEGIN_LUA_CHECK (m_vm
)
148 // Get the reference "this" table
149 lua_rawgeti (state
, LUA_REGISTRYINDEX
, m_iThisRef
);
153 lua_rawseti (state
, -2, 0);
158 //============================================================================
159 // bool CLuaScript::CompileBuffer
160 //---------------------------------------------------------------------------
161 // Compiles a given buffer
163 // Parameter Dir Description
164 // --------- --- -----------
165 // pbBuffer IN Data buffer
166 // szLen IN Length of buffer
172 //============================================================================
173 bool CLuaScript::CompileBuffer (unsigned char *pbBuffer
, size_t szLen
)
175 assert (pbBuffer
!= NULL
&& "CLuaScript::CompileBuffer -> pbBuffer == NULL");
176 assert (szLen
!= 0 && "CLuaScript::CompileBuffer -> szLen == 0");
177 assert (m_vm
.Ok () && "VM Not OK");
179 // Make sure we have the correct "this" table
180 CLuaThis
luaThis (m_vm
, m_iThisRef
);
182 return m_vm
.RunBuffer (pbBuffer
, szLen
);
185 //============================================================================
186 // bool CLuaScript::CompileBuffer
187 //---------------------------------------------------------------------------
188 // Compiles a given file
190 // Parameter Dir Description
191 // --------- --- -----------
192 // strFilename IN File name to compile
198 //============================================================================
199 bool CLuaScript::CompileFile (const char *strFilename
)
201 assert (strFilename
!= NULL
&& "CLuaScript::CompileFile -> strFilename == NULL");
202 assert (m_vm
.Ok () && "VM Not OK");
204 // Make sure we have the correct "this" table
205 CLuaThis
luaThis (m_vm
, m_iThisRef
);
207 return m_vm
.RunFile (strFilename
);
210 //============================================================================
211 // int CLuaScript::RegisterFunction
212 //---------------------------------------------------------------------------
213 // Registers a function with Lua
215 // Parameter Dir Description
216 // --------- --- -----------
217 // strFuncName IN Function name
223 //============================================================================
224 int CLuaScript::RegisterFunction (const char *strFuncName
)
226 assert (strFuncName
!= NULL
&& "CLuaScript::RegisterFunction -> strFuncName == NULL");
227 assert (m_vm
.Ok () && "VM Not OK");
231 CLuaRestoreStack
rs (m_vm
);
233 BEGIN_LUA_CHECK (m_vm
)
234 iMethodIdx
= ++m_nMethods
;
236 // Register a function with the lua script. Added it to the "this" table
237 lua_rawgeti (state
, LUA_REGISTRYINDEX
, m_iThisRef
);
239 // Push the function and parameters
240 lua_pushstring (state
, strFuncName
);
241 lua_pushnumber (state
, (lua_Number
) iMethodIdx
);
242 lua_pushcclosure (state
, LuaCallback
, 1);
243 lua_settable (state
, -3);
250 //============================================================================
251 // bool CLuaScript::SelectScriptFunction
252 //---------------------------------------------------------------------------
253 // Selects a script function to run
255 // Parameter Dir Description
256 // --------- --- -----------
257 // strFuncName IN Function name
263 //============================================================================
264 bool CLuaScript::SelectScriptFunction (const char *strFuncName
)
266 assert (strFuncName
!= NULL
&& "CLuaScript::SelectScriptFunction -> strFuncName == NULL");
267 assert (m_vm
.Ok () && "VM Not OK");
269 bool fSuccess
= true;
271 BEGIN_LUA_CHECK (m_vm
)
272 // Look up function name
273 lua_rawgeti (state
, LUA_REGISTRYINDEX
, m_iThisRef
);
274 lua_pushstring (state
, strFuncName
);
275 lua_rawget (state
, -2);
276 lua_remove (state
, -2);
278 // Put the "this" table back
279 lua_rawgeti (state
, LUA_REGISTRYINDEX
, m_iThisRef
);
281 // Check that we have a valid function
282 if (!lua_isfunction (state
, -2))
290 m_strFunctionName
= strFuncName
;
297 //============================================================================
298 // bool CLuaScript::ScriptHasFunction
299 //---------------------------------------------------------------------------
300 // Checks to see if a function exists
302 // Parameter Dir Description
303 // --------- --- -----------
304 // strScriptName IN Function name
310 //============================================================================
311 bool CLuaScript::ScriptHasFunction (const char *strScriptName
)
313 assert (strScriptName
!= NULL
&& "CLuaScript::ScriptHasFunction -> strScriptName == NULL");
314 assert (m_vm
.Ok () && "VM Not OK");
316 CLuaRestoreStack
rs (m_vm
);
318 bool fFoundFunc
= false;
320 BEGIN_LUA_CHECK (m_vm
)
321 lua_rawgeti (state
, LUA_REGISTRYINDEX
, m_iThisRef
);
322 lua_pushstring (state
, strScriptName
);
323 lua_rawget (state
, -2);
324 lua_remove (state
, -2);
326 if (lua_isfunction (state
, -1))
335 //============================================================================
336 // void CLuaScript::AddParam
337 //---------------------------------------------------------------------------
338 // Adds a parameter to the parameter list
340 // Parameter Dir Description
341 // --------- --- -----------
342 // string IN string param
348 //============================================================================
349 void CLuaScript::AddParam (char *string
)
351 assert (string
!= NULL
&& "CLuaScript::AddParam -> string == NULL");
352 assert (m_vm
.Ok () && "VM Not OK");
354 BEGIN_LUA_CHECK (m_vm
)
355 lua_pushstring (state
, string
);
360 //============================================================================
361 // void CLuaScript::AddParam
362 //---------------------------------------------------------------------------
363 // Adds a parameter to the parameter list
365 // Parameter Dir Description
366 // --------- --- -----------
373 //============================================================================
374 void CLuaScript::AddParam (int iInt
)
376 assert (m_vm
.Ok () && "VM Not OK");
378 BEGIN_LUA_CHECK (m_vm
)
379 lua_pushnumber (state
, (lua_Number
) iInt
);
384 //============================================================================
385 // void CLuaScript::AddParam
386 //---------------------------------------------------------------------------
387 // Adds a parameter to the parameter list
389 // Parameter Dir Description
390 // --------- --- -----------
391 // fFloat IN float param
397 //============================================================================
398 void CLuaScript::AddParam (float fFloat
)
400 assert (m_vm
.Ok () && "VM Not OK");
402 BEGIN_LUA_CHECK (m_vm
)
403 lua_pushnumber (state
, (lua_Number
) fFloat
);
408 //============================================================================
409 // bool CLuaScript::Go
410 //---------------------------------------------------------------------------
411 // Runs the selected script function
413 // Parameter Dir Description
414 // --------- --- -----------
415 // nReturns IN Number of expected returns
421 //============================================================================
422 bool CLuaScript::Go (int nReturns
/* = 0 */)
424 assert (m_vm
.Ok () && "VM Not OK");
426 // At this point there should be a parameters and a function on the
427 // Lua stack. Each function get a "this" parameter as default and is
428 // pushed onto the stack when the method is selected
430 bool fSuccess
= m_vm
.CallFunction (m_nArgs
+ 1, nReturns
);
432 if (fSuccess
== true && nReturns
> 0)
435 HandleReturns (m_vm
, m_strFunctionName
);
436 lua_pop ((lua_State
*) m_vm
, nReturns
);