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
moLuna.h
Ir a la documentación de este archivo.
1 /*******************************************************************************
2 
3  moLuna.h
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  Andrés Colubri
29 
30  Description:
31  Implementa un método para agregar clases de moldeo a la máquina virtual de LUA,
32  de manera tal que puedan ser creadas y accedidas desde los scripts. Para mas
33  información al respecto:
34  http://lua-users.org/wiki/SimpleCppBinding
35  http://lua-users.org/wiki/SimplerCppBinding
36  http://lua-users.org/wiki/CppBindingWithLunar
37  Cada link describe un método diferente, el que se utiliza aquí es el segundo.
38 
39  Fabricio Costa > versión 2011 implementada en base a:
40  http://lua-users.org/wiki/LunaFourCode
41  http://lua-users.org/wiki/LunaFour
42 
43 *******************************************************************************/
44 
45 #ifndef __MO_LUNA_H__
46 #define __MO_LUNA_H__
47 
48 #include "moTypes.h"
49 
50 #undef check
51 
53 #include <string>
54 #include <vector>
55 #include <list>
56 
57 extern "C"
58 {
59  #include "lua.h"
60  #include "lauxlib.h"
61  #include "lualib.h"
62 }
63 
68 template <typename T> class moLuna {
69  typedef struct { T *pT; } userdataType;
70 public:
71 
73  enum { NUMBER, STRING };
74 
76  struct PropertyType {
77  const char *name;
78  int (T::*getter) (lua_State *);
79  int (T::*setter) (lua_State *);
80  };
81 
83  struct FunctionType {
84  const char *name;
85  int (T::*function) (lua_State *);
86  };
87 
88 
90  //typedef int (T::*mfp)(lua_State *L);
91  //typedef struct { const char *name; mfp mfunc; } RegType;
92 
93 
95 
105  /*
106  static T *check(lua_State * L, int narg) {
107  // Check to see whether we are a table
108  if (lua_istable(L,narg+1))
109  {
110  lua_gettablevalue(L,narg+1,0);
111  userdataType *ud =
112  static_cast <userdataType * >(luaL_checkudata(L, -1, T::className));
113  if (!ud)
114  luaL_typerror(L, narg+1, T::className);
115  lua_pop(L,1);
116  return ud->pT; // pointer to T object
117  }
118  else
119  {
120  luaL_typerror(L, narg+1, T::className);
121  }
122  }
123 */
136 
148  /*
149  static T *lightcheck(lua_State * L, int narg) {
150  // Check to see whether we are a table
151  if (lua_istable(L,narg+1))
152  {
153  lua_gettablevalue(L,narg+1,0); ///doesn't work
154  userdataType *ud =
155  static_cast <userdataType * >(luaL_testudata(L, -1, T::className));
156  if (!ud)
157  return NULL; // lightcheck returns NULL if not found.
158  lua_pop(L,1);
159  return ud->pT; // pointer to T object
160  }
161  else
162  {
163  return NULL;
164  }
165  }
166 */
167 
173  /*
174  static void Register(lua_State *L) {
175  lua_newtable(L);
176  int methods = lua_gettop(L);
177 
178  luaL_newmetatable(L, T::className);
179  int metatable = lua_gettop(L);
180 
181  // store method table in globals so that
182  // scripts can add functions written in Lua.
183  lua_pushstring(L, T::className);
184  lua_pushvalue(L, methods);
185  lua_settable(L, LUA_GLOBALSINDEX);
186 
187  lua_pushliteral(L, "__metatable");
188  lua_pushvalue(L, methods);
189  lua_settable(L, metatable); // hide metatable from Lua getmetatable()
190 
191  lua_pushliteral(L, "__index");
192  lua_pushvalue(L, methods);
193  lua_settable(L, metatable);
194 
195  lua_pushliteral(L, "__tostring");
196  lua_pushcfunction(L, tostring_T);
197  lua_settable(L, metatable);
198 
199  lua_pushliteral(L, "__gc");
200  lua_pushcfunction(L, gc_T);
201  lua_settable(L, metatable);
202 
203  lua_newtable(L); // mt for method table
204  int mt = lua_gettop(L);
205  lua_pushliteral(L, "__call");
206  lua_pushcfunction(L, new_T);
207  lua_pushliteral(L, "new");
208  lua_pushvalue(L, -2); // dup new_T function
209  lua_settable(L, methods); // add new_T to method table
210  lua_settable(L, mt); // mt.__call = new_T
211  lua_setmetatable(L, methods);
212 
213  // fill method table with methods from class T
214  for (RegType *l = T::methods; l->name; l++) {
215  // edited by Snaily: shouldn't it be const RegType *l ... ?
216  lua_pushstring(L, l->name);
217  lua_pushlightuserdata(L, (void*)l);
218  lua_pushcclosure(L, thunk, 1);
219  lua_settable(L, methods);
220  }
221 
222  lua_pop(L, 2); // drop metatable and method table
223  }
224 */
225 
227 
236  // REGISTER CLASS AS A GLOBAL TABLE
237  static void Register(lua_State * L, const char *namespac = "") {
238 
239  if (strcmp(namespac, "") != 0) {
240  lua_getglobal(L, namespac);
241  lua_pushcfunction(L, &moLuna < T >::constructor);
242  lua_setfield(L, -2, T::className);
243  lua_pop(L, 1);
244  } else {
245  lua_pushcfunction(L, &moLuna < T >::constructor);
246  lua_setglobal(L, T::className);
247  }
248 
249  luaL_newmetatable(L, T::className);
250  int metatable = lua_gettop(L);
251 
252  lua_pushstring(L, "__gc");
253  lua_pushcfunction(L, &moLuna < T >::gc_obj);
254  lua_settable(L, metatable);
255 
256  lua_pushstring(L, "__index");
257  lua_pushcfunction(L, &moLuna < T >::property_getter);
258  lua_settable(L, metatable);
259 
260  lua_pushstring(L, "__setindex");
261  lua_pushcfunction(L, &moLuna < T >::property_setter);
262  lua_settable(L, metatable);
263 
264  }
265 
267 
274  static int constructor(lua_State * L) {
275 
276  lua_newtable(L);
277 
278  int newtable = lua_gettop(L);
279 
280  lua_pushnumber(L, 0);
281 
282  T **a = (T **) lua_newuserdata(L, sizeof(T *));
283  //correction
284  //T *obj = new T(L, true);
285  T *obj = new T(L);
286  *a = obj;
287 
288  int userdata = lua_gettop(L);
289 
290  luaL_getmetatable(L, T::className);
291 
292  lua_setmetatable(L, userdata);
293 
294  lua_settable(L, newtable);
295 
296  luaL_getmetatable(L, T::className);
297  lua_setmetatable(L, newtable);
298 
299  luaL_getmetatable(L, T::className);
300 
301  for (int i = 0; T::Properties[i].name; i++) {
302  lua_pushstring(L, T::Properties[i].name);
303  lua_pushnumber(L, i);
304  lua_settable(L, -3);
305  }
306 
307  lua_pop(L, 1);
308 
309  for (int i = 0; T::Functions[i].name; i++) {
310  lua_pushstring(L, T::Functions[i].name);
311  lua_pushnumber(L, i);
312  lua_pushcclosure(L, &moLuna < T >::function_dispatch, 1);
313  lua_settable(L, newtable);
314  }
315 
316  return 1;
317  }
318 
328  static T *createNew(lua_State * L) {
329 
330  lua_newtable(L);
331 
332  int newtable = lua_gettop(L);
333 
334  lua_pushnumber(L, 0);
335 
336  T **a = (T **) lua_newuserdata(L, sizeof(T *));
337  T *obj = new T(L, false);
338  obj->isExisting = false;
339  *a = obj;
340 
341  int userdata = lua_gettop(L);
342 
343  luaL_getmetatable(L, T::className);
344 
345  lua_setmetatable(L, userdata);
346 
347  lua_settable(L, newtable);
348 
349  luaL_getmetatable(L, T::className);
350  lua_setmetatable(L, newtable);
351 
352  luaL_getmetatable(L, T::className);
353 
354  for (int i = 0; T::Properties[i].name; i++) {
355  // ADD NAME KEY
356  lua_pushstring(L, T::Properties[i].name);
357  lua_pushnumber(L, i);
358  lua_settable(L, -3);
359  }
360 
361  lua_pop(L, 1);
362 
363  for (int i = 0; T::Functions[i].name; i++) {
364  lua_pushstring(L, T::Functions[i].name);
365  lua_pushnumber(L, i);
366  lua_pushcclosure(L, &moLuna < T >::function_dispatch, 1);
367  lua_settable(L, newtable);
368  }
369 
370  return obj;
371  }
372 
384  static T *createFromExisting(lua_State * L, T * existingobj) {
385 
386  lua_newtable(L);
387 
388  int newtable = lua_gettop(L);
389 
390  lua_pushnumber(L, 0);
391 
392  T **a = (T **) lua_newuserdata(L, sizeof(T *));
393  T *obj = existingobj;
394  obj->isExisting = true;
395  *a = obj;
396 
397  int userdata = lua_gettop(L);
398 
399 
400  luaL_getmetatable(L, T::className);
401 
402  lua_setmetatable(L, userdata);
403 
404  lua_settable(L, newtable);
405 
406  luaL_getmetatable(L, T::className);
407  lua_setmetatable(L, newtable);
408 
409  luaL_getmetatable(L, T::className);
410 
411  for (int i = 0; T::Properties[i].name; i++) {
412  lua_pushstring(L, T::Properties[i].name);
413  lua_pushnumber(L, i);
414  lua_settable(L, -3);
415  }
416 
417  lua_pop(L, 1);
418 
419  for (int i = 0; T::Functions[i].name; i++) {
420  lua_pushstring(L, T::Functions[i].name);
421  lua_pushnumber(L, i);
422  lua_pushcclosure(L, &moLuna < T >::function_dispatch, 1);
423  lua_settable(L, newtable);
424  }
425 
426  return obj;
427  }
428 
435  static int property_getter(lua_State * L) {
436 
437  lua_pushvalue(L, 2);
438 
439  lua_getmetatable(L, 1);
440 
441  lua_pushvalue(L, 2);
442  lua_rawget(L, -2);
443 
444  if (lua_isnumber(L, -1)) {
445 
446  int _index = lua_tonumber(L, -1);
447 
448  lua_pushnumber(L, 0);
449  lua_rawget(L, 1);
450 
451  T **obj =
452  static_cast < T ** >(lua_touserdata(L, -1));
453 
454  lua_pushvalue(L, 3);
455 
456  //const PropertyType *_properties = (*obj)->T::Properties;
457 
458  int result = ((*obj)->*(T::Properties[_index].getter)) (L);
459 
460  return result;
461 
462  }
463  // PUSH NIL
464  lua_pushnil(L);
465 
466  return 1;
467 
468  }
469 
476  static int property_setter(lua_State * L) {
477 
478  lua_getmetatable(L, 1);
479 
480  lua_pushvalue(L, 2);
481  lua_rawget(L, -2);
482 
483  if (lua_isnil(L, -1)) {
484 
485  lua_pop(L, 2);
486 
487  lua_rawset(L, 1);
488 
489  return 0;
490  } else {
491 
492  int _index = lua_tonumber(L, -1);
493 
494  lua_pushnumber(L, 0);
495  lua_rawget(L, 1);
496 
497  T **obj =
498  static_cast < T ** >(lua_touserdata(L, -1));
499 
500  lua_pushvalue(L, 3);
501 
502  //const PropertyType *_properties = (*obj)->T::Properties;
503 
504  return ((*obj)->*(T::Properties[_index].setter)) (L);
505 
506  }
507 
508  }
509 
516  static int function_dispatch(lua_State * L) {
517 
518  int i = (int) lua_tonumber(L, lua_upvalueindex(1));
519 
520  lua_pushnumber(L, 0);
521  lua_rawget(L, 1);
522 
523  T **obj = static_cast < T ** >(lua_touserdata(L, -1));
524 
525  lua_pop(L, 1);
526 
527  return ((*obj)->*(T::Functions[i].function)) (L);
528  }
529 
536  static int gc_obj(lua_State * L) {
537 
538  T **obj =
539  static_cast < T ** >(luaL_checkudata(L, -1, T::className));
540 
541  if (!(*obj)->isExisting && !(*obj)->isPrecious)
542  {
543  cout << "Cleaning up a " << T::className << "." << endl;
544  delete(*obj);
545  }
546 
547  return 0;
548  }
549 
550 
551 private:
552 
553 /*
554  moLuna(); // hide default constructor
555 
556 
557  // member function dispatcher
558  static int thunk(lua_State *L) {
559  // stack has userdata, followed by method args
560  T *obj = check(L, 1); // get 'self', or if you prefer, 'this'
561  lua_remove(L, 1); // remove self so member function args start at index 1
562  // get member function from upvalue
563  RegType *l = static_cast<RegType*>(lua_touserdata(L, lua_upvalueindex(1)));
564  return (obj->*(l->mfunc))(L); // call member function
565  }
566 
567  // create a new T object and
568  // push onto the Lua stack a userdata containing a pointer to T object
569  static int new_T(lua_State *L) {
570  lua_remove(L, 1); // use classname:new(), instead of classname.new()
571  T *obj = new T(L); // call constructor for T objects
572  userdataType *ud =
573  static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType)));
574  ud->pT = obj; // store pointer to object in userdata
575  luaL_getmetatable(L, T::className); // lookup metatable in Lua registry
576  lua_setmetatable(L, -2);
577  return 1; // userdata containing pointer to T object
578  }
579 
580  // garbage collection metamethod
581  static int gc_T(lua_State *L) {
582  userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1));
583  T *obj = ud->pT;
584  if ( obj )
585  {
586  delete obj; // call destructor for T objects
587  obj = 0;
588  }
589  return 0;
590  }
591 
592  static int tostring_T (lua_State *L) {
593  char buff[32];
594  userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1));
595  T *obj = ud->pT;
596  sprintf(buff, "%p", obj);
597  lua_pushfstring(L, "%s (%s)", T::className, buff);
598  return 1;
599  }
600  */
601 };
602 
603 #define DECLARE_SCRIPT_CLASS(ClassName) \
604  public: \
605  static const char className[]; \
606  static moLuna<ClassName>::PropertyType Properties[]; \
607  static moLuna<ClassName>::FunctionType Functions[];\
608 \
609  bool isExisting; \
610  bool isPrecious;
611 
612 
613 #define IMPLEMENT_SCRIPT_CLASS(ClassName) \
614  const char ClassName::className[] = #ClassName;
615 
616 #define DEFINE_SCRIPT_CLASS_FUNCTIONS(ClassName) \
617  moLuna<ClassName>::FunctionType ClassName::Functions[] = {
618 
619 #define SCRIPT_FUNCTION(ClassName, FunctionName) { #FunctionName, &ClassName::FunctionName }
620 
621 #define END_SCRIPT_CLASS_FUNCTIONS };
622 
623 
624 #define DEFINE_SCRIPT_CLASS_PROPERTIES(ClassName) \
625  moLuna<ClassName>::PropertyType ClassName::Properties[] = {
626 
627 #define SCRIPT_PROPERTY(ClassName, PropertyName, PropertyGetter, PropertySetter ) { #PropertyName, &ClassName::PropertyGetter, &ClassName::PropertySetter }
628 
629 #define END_SCRIPT_CLASS_PROPERTIES };
630 
631 #define REGISTER_CLASS(ClassName, LuaState) \
632  moLuna<ClassName>::Register(LuaState);
633 
634 #define SCRIPT_CONSTRUCTOR_DECLARATION(ClassName) ClassName(lua_State* L);
635 #define SCRIPT_CONSTRUCTOR_IMPLEMENTATION(ClassName) ClassName::ClassName(lua_State* L)
636 
637 #define SCRIPT_FUNCTION_DECLARATION(FunctionName) int FunctionName(lua_State* L);
638 #define SCRIPT_FUNCTION_IMPLEMENTATION(ClassName, FunctionName) int ClassName::FunctionName(lua_State* L)
639 
640 #endif
int(T::* setter)(lua_State *)
Definition: moLuna.h:79
static void Register(lua_State *L, const char *namespac="")
eso no esta en LunaFourCode
Definition: moLuna.h:237
static int constructor(lua_State *L)
LunaFourCode.
Definition: moLuna.h:274
function a
Definition: jquery.js:41
static T * createFromExisting(lua_State *L, T *existingobj)
Definition: moLuna.h:384
static int property_getter(lua_State *L)
Definition: moLuna.h:435
moTypes MOint moText moParamIndex moParamReference int iRow int int i int i
Definition: all_f.js:18
static int gc_obj(lua_State *L)
Definition: moLuna.h:536
function L
Definition: jquery.js:16
const char * name
Definition: moLuna.h:77
LunaFourCode.
Definition: moLuna.h:83
LunaFourCode.
Definition: moLuna.h:76
const char * name
Definition: moLuna.h:84
static T * createNew(lua_State *L)
Definition: moLuna.h:328
int(T::* getter)(lua_State *)
Definition: moLuna.h:78
LunaFourCode.
Definition: moLuna.h:68
static int property_setter(lua_State *L)
Definition: moLuna.h:476
static int function_dispatch(lua_State *L)
Definition: moLuna.h:516