libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo es el conjunto de objetos y funciones, que permiten ejecutar las operaciones básicas de la plataforma Moldeo, y que compone su núcleo.
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Amigas 'defines' Grupos Páginas
moScript.cpp
Ir a la documentación de este archivo.
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