libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo is the group of objects and functions that executes the basic operations of Moldeo 1.0 Platform.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
moScript.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 
3  moScript.cpp
4 
5  ****************************************************************************
6  * *
7  * This source is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This code is distributed in the hope that it will be useful, but *
13  * WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15  * General Public License for more details. *
16  * *
17  * A copy of the GNU General Public License is available on the World *
18  * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
19  * obtain it by writing to the Free Software Foundation, *
20  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  * *
22  ****************************************************************************
23 
24  Copyright (C) 2006 Fabricio Costa
25 
26  Authors:
27  Fabricio Costa
28 
29 
30  Description:
31  Base class for Lua-scriptable classes.
32 
33 *******************************************************************************/
34 
35 #include <assert.h>
36 #include "moScript.h"
37 #include "moScriptManager.h"
38 
40 moLuaDebugger moScript::m_dbg (moScript::m_vm);
41 
42 
43 // ---------------------------------------------------------------------------
44 
45 #define BEGIN_LUA_CHECK(vm) lua_State *state = (lua_State *) vm; \
46  if (vm.Ok ()) {
47 #define END_LUA_CHECK }
48 
49 
50 //============================================================================
51 // int LuaCallback
52 //---------------------------------------------------------------------------
53 // Lua C-API calling that figures out which object to hand over to
54 //
55 // Parameter Dir Description
56 // --------- --- -----------
57 // lua IN State variable
58 //
59 // Return
60 // ------
61 // Number of return varaibles on the stack
62 //
63 // Comments
64 // --------
65 // This is the function lua calls for each C-Function that is
66 // registered with lua. At the time of registering the function
67 // with lua, we make lua record the method "number" so we can
68 // know what method was actually called. The lua stack is the
69 // following structure:
70 // 0: 'this' (table)
71 // 1 - ...: parameters passed in
72 //
73 //============================================================================
74 static int LuaCallback (lua_State *lua)
75 {
76  // Locate the psudo-index for the function number
77  int iNumberIdx = lua_upvalueindex (1);
78  int nRetsOnStack = 0;
79 
80  bool fSuccess = false;
81 
82  // Check for the "this" table
83  if (lua_istable (lua, 1))
84  {
85  // Found the "this" table. The object pointer is at the index 0
86  lua_rawgeti (lua, 1, 0);
87 
88  if (lua_islightuserdata (lua, -1))
89  {
90  // Found the pointer, need to cast it
91  moScript *pThis = (moScript *) lua_touserdata (lua, -1);
92 
93  // Get the method index
94  int iMethodIdx = (int) lua_tonumber (lua, iNumberIdx);
95 
96  // Check that the method is correct index
97  assert (!(iMethodIdx > pThis->methods ()));
98 
99  // Reformat the stack so our parameters are correct
100  // Clean up the "this" table
101  lua_remove (lua, 1);
102  // Clean up the pThis pointer
103  lua_remove (lua, -1);
104 
105  // Call the class
106  nRetsOnStack = pThis->ScriptCalling (pThis->mvm (), iMethodIdx);
107 
108  fSuccess = true;
109  }
110  }
111 
112  if (fSuccess == false)
113  {
114  lua_pushstring (lua, "LuaCallback -> Failed to call the class function");
115  lua_error (lua);
116  }
117 
118  // Number of return variables
119  return nRetsOnStack;
120 }
121 
122 
123 //============================================================================
124 // moScript::moScript
125 //---------------------------------------------------------------------------
126 // Default constructor.
127 //
128 // Parameter Dir Description
129 // --------- --- -----------
130 // None.
131 //
132 // Return
133 // ------
134 // None.
135 //
136 //============================================================================
138  : m_initialized(false),
139  m_nMethods (0),
140  m_iThisRef (0),
141  m_nArgs (0),
142  m_iMethodBase(-1),
143  m_iMethodBaseIterator(0),
144  m_iMethodBaseAncestors(0)
145 {
146  m_iMethodBase = -1;
147  memset( m_MethodBases, -1, sizeof(int)*256);
148 }
149 
150 //============================================================================
151 // moScript::~moScript
152 //---------------------------------------------------------------------------
153 // Destructor
154 //
155 // Parameter Dir Description
156 // --------- --- -----------
157 // None.
158 //
159 // Return
160 // ------
161 // None.
162 //
163 //============================================================================
165 {
167 }
168 
169 //============================================================================
170 // moScript::Init
171 //---------------------------------------------------------------------------
172 // Function
173 //
174 // Parameter Dir Description
175 // --------- --- -----------
176 // Initializes the script with the VM
177 //
178 // Return
179 // ------
180 // None.
181 //
182 //============================================================================
184 {
185 
187  if (!m_vm.Ok()) moScriptManager::InitVM();
188 
190  // Create a reference to the "this" table. Each reference is unique
191  lua_newtable (state);
192  m_iThisRef = luaL_ref (state, LUA_REGISTRYINDEX);
193 
194  // Save the "this" table to index 0 of the "this" table
195  moLuaRestoreStack rs (m_vm);
196  lua_rawgeti (state, LUA_REGISTRYINDEX, m_iThisRef);
197  lua_pushlightuserdata (state, (void *) this);
198  lua_rawseti (state, -2, 0);
199 
200  m_initialized = true;
202 }
203 
205 {
206  moLuaRestoreStack rs (m_vm);
207 
209  // Get the reference "this" table
210  lua_rawgeti (state, LUA_REGISTRYINDEX, m_iThisRef);
211 
212  // Clear index 0
213  lua_pushnil (state);
214  lua_rawseti (state, -2, 0);
215 
216  m_initialized = false;
218 }
219 
220 //============================================================================
221 // bool moScript::CompileBuffer
222 //---------------------------------------------------------------------------
223 // Compiles a given buffer
224 //
225 // Parameter Dir Description
226 // --------- --- -----------
227 // pbBuffer IN Data buffer
228 // szLen IN Length of buffer
229 //
230 // Return
231 // ------
232 // Success
233 //
234 //============================================================================
235 bool moScript::CompileBuffer (unsigned char *pbBuffer, size_t szLen)
236 {
237  assert (pbBuffer != NULL && "moScript::CompileBuffer -> pbBuffer == NULL");
238  assert (szLen != 0 && "moScript::CompileBuffer -> szLen == 0");
239  assert (m_vm.Ok () && "VM Not OK");
240 
241  // Make sure we have the correct "this" table
242  moLuaThis luaThis (m_vm, m_iThisRef);
243 
244  return m_vm.RunBuffer (pbBuffer, szLen);
245 }
246 
247 //============================================================================
248 // bool moScript::CompileBuffer
249 //---------------------------------------------------------------------------
250 // Compiles a given file
251 //
252 // Parameter Dir Description
253 // --------- --- -----------
254 // strFilename IN File name to compile
255 //
256 // Return
257 // ------
258 // Success
259 //
260 //============================================================================
261 bool moScript::CompileFile (const char *strFilename)
262 {
263  assert (strFilename != NULL && "moScript::CompileFile -> strFilename == NULL");
264  assert (m_vm.Ok () && "VM Not OK");
265 
266  // Make sure we have the correct "this" table
267  moLuaThis luaThis (m_vm, m_iThisRef);
268 
269  return m_vm.RunFile (strFilename);
270 }
271 
272 //============================================================================
273 // int moScript::RegisterFunction
274 //---------------------------------------------------------------------------
275 // Registers a function with Lua
276 //
277 // Parameter Dir Description
278 // --------- --- -----------
279 // strFuncName IN Function name
280 //
281 // Return
282 // ------
283 // Success
284 //
285 //============================================================================
286 int moScript::RegisterFunction (const char *strFuncName, moScript::Function& fun )
287 {
288  assert (strFuncName != NULL && "moScript::RegisterFunction -> strFuncName == NULL");
289  assert (m_vm.Ok () && "VM Not OK");
290 
291  int iMethodIdx = -1;
292 
293  moLuaRestoreStack rs (m_vm);
294 
296  iMethodIdx = ++m_nMethods;
297  Functions[iMethodIdx] = fun;
298 
299  // Register a function with the lua script. Added it to the "this" table
300  lua_rawgeti (state, LUA_REGISTRYINDEX, m_iThisRef);
301 
302  // Push the function and parameters
303  lua_pushstring (state, strFuncName);
304  lua_pushnumber (state, (lua_Number) iMethodIdx);
305  lua_pushcclosure (state, LuaCallback, 1);
306  lua_settable (state, -3);
307 
309 
310  return iMethodIdx;
311 }
312 
313 int moScript::RegisterFunction (const char *strFuncName)
314 {
315  assert (strFuncName != NULL && "moScript::RegisterFunction -> strFuncName == NULL");
316  assert (m_vm.Ok () && "VM Not OK");
317 
318  int iMethodIdx = -1;
319 
320  moLuaRestoreStack rs (m_vm);
321 
323  iMethodIdx = ++m_nMethods;
324  //Functions[iMethodIdx] = ;
325 
326  // Register a function with the lua script. Added it to the "this" table
327  lua_rawgeti (state, LUA_REGISTRYINDEX, m_iThisRef);
328 
329  // Push the function and parameters
330  lua_pushstring (state, strFuncName);
331  lua_pushnumber (state, (lua_Number) iMethodIdx);
332  lua_pushcclosure (state, LuaCallback, 1);
333  lua_settable (state, -3);
334 
336 
337  return iMethodIdx;
338 }
339 
340 int moScript::RegisterBaseFunction (const char *strFuncName) {
341 
342  int MethodBase = m_iMethodBase;
343 
344  m_iMethodBase = RegisterFunction( strFuncName );
345  moDebugManager::Message(moText("RegisterFunction > m_iMethodBase: ") + IntToStr(m_iMethodBase)+ moText("for: ") + strFuncName );
346 
347  if (MethodBase!=m_iMethodBase && m_iMethodBase!=-1) {
351  }
352  return m_iMethodBase;
353 }
354 
355 
356 //============================================================================
357 // bool moScript::SelectScriptFunction
358 //---------------------------------------------------------------------------
359 // Selects a script function to run
360 //
361 // Parameter Dir Description
362 // --------- --- -----------
363 // strFuncName IN Function name
364 //
365 // Return
366 // ------
367 // Success
368 //
369 //============================================================================
370 bool moScript::SelectScriptFunction (const char *strFuncName)
371 {
372  assert (strFuncName != NULL && "moScript::SelectScriptFunction -> strFuncName == NULL");
373  assert (m_vm.Ok () && "VM Not OK");
374 
375  bool fSuccess = true;
376 
378  // Look up function name
379  lua_rawgeti (state, LUA_REGISTRYINDEX, m_iThisRef);
380  lua_pushstring (state, strFuncName);
381  lua_rawget (state, -2);
382  lua_remove (state, -2);
383 
384  // Put the "this" table back
385  lua_rawgeti (state, LUA_REGISTRYINDEX, m_iThisRef);
386 
387  // Check that we have a valid function
388  if (!lua_isfunction (state, -2))
389  {
390  fSuccess = false;
391  lua_pop (state, 2);
392  }
393  else
394  {
395  m_nArgs = 0;
396  m_strFunctionName = strFuncName;
397  }
399 
400  return fSuccess;
401 }
402 
403 //============================================================================
404 // bool moScript::ScriptHasFunction
405 //---------------------------------------------------------------------------
406 // Checks to see if a function exists
407 //
408 // Parameter Dir Description
409 // --------- --- -----------
410 // strScriptName IN Function name
411 //
412 // Return
413 // ------
414 // Success
415 //
416 //============================================================================
417 bool moScript::ScriptHasFunction (const char *strScriptName)
418 {
419  //assert (strScriptName != NULL && "moScript::ScriptHasFunction -> strScriptName == NULL");
420  //assert (m_vm.Ok () && "VM Not OK");
421  if ( !m_vm.Ok () ) return false;
422 
423  moLuaRestoreStack rs (m_vm);
424 
425  bool fFoundFunc = false;
426 
428  lua_rawgeti (state, LUA_REGISTRYINDEX, m_iThisRef);
429  lua_pushstring (state, strScriptName);
430  lua_rawget (state, -2);
431  lua_remove (state, -2);
432 
433  if (lua_isfunction (state, -1))
434  {
435  fFoundFunc = true;
436  }
438 
439  return fFoundFunc;
440 }
441 
442 //============================================================================
443 // void moScript::AddFunctionParam
444 //---------------------------------------------------------------------------
445 // Adds a parameter to the parameter list
446 //
447 // Parameter Dir Description
448 // --------- --- -----------
449 // string IN string param
450 //
451 // Return
452 // ------
453 // None.
454 //
455 //============================================================================
456 void moScript::AddFunctionParam (char *string)
457 {
458  assert (string != NULL && "moScript::AddFunctionParam -> string == NULL");
459  assert (m_vm.Ok () && "VM Not OK");
460 
462  lua_pushstring (state, string);
463  ++m_nArgs;
465 }
466 
467 //============================================================================
468 // void moScript::AddFunctionParam
469 //---------------------------------------------------------------------------
470 // Adds a parameter to the parameter list
471 //
472 // Parameter Dir Description
473 // --------- --- -----------
474 // iInt IN int param
475 //
476 // Return
477 // ------
478 // None.
479 //
480 //============================================================================
482 {
483  assert (m_vm.Ok () && "VM Not OK");
484 
486  lua_pushnumber (state, (lua_Number) iInt);
487  ++m_nArgs;
489 }
490 
491 //============================================================================
492 // void moScript::AddFunctionParam
493 //---------------------------------------------------------------------------
494 // Adds a parameter to the parameter list
495 //
496 // Parameter Dir Description
497 // --------- --- -----------
498 // fFloat IN float param
499 //
500 // Return
501 // ------
502 // None.
503 //
504 //============================================================================
505 void moScript::AddFunctionParam (float fFloat)
506 {
507  assert (m_vm.Ok () && "VM Not OK");
508 
510  lua_pushnumber (state, (lua_Number) fFloat);
511  ++m_nArgs;
513 }
514 
515 //============================================================================
516 // bool moScript::Go
517 //---------------------------------------------------------------------------
518 // Runs the selected script function
519 //
520 // Parameter Dir Description
521 // --------- --- -----------
522 // nReturns IN Number of expected returns
523 //
524 // Return
525 // ------
526 // None.
527 //
528 //============================================================================
529 bool moScript::RunSelectedFunction (int nReturns /* = 0 */)
530 {
531  assert (m_vm.Ok () && "VM Not OK");
532 
533  // At this point there should be a parameters and a function on the
534  // Lua stack. Each function get a "this" parameter as default and is
535  // pushed onto the stack when the method is selected
536 
537  bool fSuccess = m_vm.CallFunction (m_nArgs + 1, nReturns);
538 
539  if (fSuccess == true && nReturns > 0)
540  {
541  // Check for returns
543  lua_pop ((lua_State *) m_vm, nReturns);
544  }
545 
546  return fSuccess;
547 }
548 
int(* Function)(moLuaVirtualMachine &vm)
Definition: moScript.h:52
int RegisterBaseFunction(const char *strFuncName)
Definition: moScript.cpp:340
Function Functions[255]
Definition: moScript.h:54
virtual bool Ok(void)
Definition: moLuaBase.h:129
static void Message(moText p_text)
Anuncia un mensaje al usuario además de guardarlo en el log de texto.
bool CompileFile(const char *strFilename)
Definition: moScript.cpp:261
int m_MethodBases[256]
increment on each call to RegisterFunctions
Definition: moScript.h:210
bool RunSelectedFunction(int nReturns=0)
Definition: moScript.cpp:529
static moLuaDebugger m_dbg
Definition: moScript.h:200
virtual ~moScript(void)
Definition: moScript.cpp:164
int m_iThisRef
Definition: moScript.h:201
moText0 moText
Definition: moText.h:291
bool CompileBuffer(unsigned char *pbBuffer, size_t szLen)
Definition: moScript.cpp:235
bool ScriptHasFunction(const char *strScriptName)
Definition: moScript.cpp:417
void FinishScript()
Definition: moScript.cpp:204
virtual int ScriptCalling(moLuaVirtualMachine &vm, int iFunctionNumber)=0
bool CallFunction(int nArgs, int nReturns=0)
Definition: moLuaBase.cpp:295
void AddFunctionParam(int iInt)
Definition: moScript.cpp:481
static void InitVM()
const char * m_strFunctionName
Definition: moScript.h:203
int m_nMethods
Definition: moScript.h:198
int methods(void)
Definition: moScript.h:153
void InitScript()
Definition: moScript.cpp:183
restaurador del stack de LUA
Definition: moLuaBase.h:199
bool m_initialized
Definition: moScript.h:197
bool RunBuffer(const unsigned char *pbBuffer, size_t szLen, const char *strName=NULL)
Definition: moLuaBase.cpp:252
static moLuaVirtualMachine m_vm
Definition: moScript.h:199
LIBMOLDEO_API moText0 IntToStr(int a)
Definition: moText.cpp:1070
int m_iMethodBaseAncestors
actual class iterator index method base
Definition: moScript.h:209
bool RunFile(const char *strFilename)
Definition: moLuaBase.cpp:214
#define END_LUA_CHECK
Definition: moScript.cpp:47
bool SelectScriptFunction(const char *strFuncName)
Definition: moScript.cpp:370
#define BEGIN_LUA_CHECK(vm)
Definition: moScript.cpp:45
virtual void HandleReturns(moLuaVirtualMachine &vm, const char *strFunc)=0
int m_nArgs
Definition: moScript.h:202
int RegisterFunction(const char *strFuncName, moScript::Function &fun)
Definition: moScript.cpp:286
int m_iMethodBase
Definition: moScript.h:206
moLuaVirtualMachine & mvm(void)
Definition: moScript.h:195