Lua Utils
Biblioteca utilitária para facilitar a integração de Lua com C++
luaMethod.h
Go to the documentation of this file.
1 /************************************************************************
2 **
3 ** Copyright (C) 2009 K2FS Sistemas e Projetos Ltd.
4 ** All rights reserved.
5 **
6 ************************************************************************/
7 
18 #ifndef _LUA_METHOD_H_
19 #define _LUA_METHOD_H_
20 
21 #include "luaConfig.h"
22 
23 #include "luaEnv.h"
24 #include "luaProxy.h"
25 #include "luaStackBalancer.h"
26 
69 template <typename T> class LuaMethod
70 {
71 public:
72 
74  typedef int (T::*MethodType)(lua_State*);
75 
77  struct MethodRegistry {
78  const char* _name;
80  };
81 
97  static void registerMethods(lua_State* L, struct MethodRegistry* methods, int upvalues = 0)
98  {
99  LUA_SAVE_TOPL(L);
100 
101  if(!upvalues)
102  {
103  // Pilha = tabela
104  for(MethodRegistry* r = methods; r->_name; ++r)
105  {
106  lua_pushstring(L, r->_name); // Pilha = tabela, nome
107  lua_pushlightuserdata(L, r); // Pilha = tabela, nome, ud
108  lua_pushcclosure(L, methodRedirector, 1); // Pilha = tabela, nome, funçao
109  lua_settable(L, -3); // Pilha = tabela
110  }
111  }
112  else
113  {
114  // Caso geral: Pilha = tabela, uv(1)..uv(n)
115  lua_pushvalue(L, -(upvalues+1)); // Pilha = tabela, uv(1)..uv(n), tabela
116  for(MethodRegistry* r = methods; r->_name; ++r)
117  {
118  lua_pushstring(L, r->_name); // Pilha = tabela, uv(1)..uv(n), tabela, nome
119  lua_pushlightuserdata(L, r); // Pilha = tabela, uv(1)..uv(n), tabela, nome, ud
120 
121  for(int i = 0; i<upvalues; i++)
122  lua_pushvalue(L, -(3+upvalues)); // Pilha = tabela, uv(1)..uv(n), tabela, nome, ud, uv(1)..uv(i+1)
123 
124  lua_pushcclosure(L, methodRedirector, 1+upvalues); // Pilha = tabela, uv(1)..uv(n), tabela, nome, funçao
125  lua_settable(L, -3); // Pilha = tabela, uv(1)..uv(n), tabela
126  }
127  lua_pop(L, 1); // Pilha = tabela, uv(1)..uv(n)
128  }
129 
130  LUA_CHECK_TOPL(L);
131  }
132 
133 private:
134 
143  static int methodRedirector(lua_State* L)
144  {
145 #ifdef LUAUTILS_CANCEL
146  // Verifica se a execução do script Lua deve ser cancelada
147  if(LuaEnv::cancelRequested(L))
148  return luaL_error(L, "%s", luaPrintable(QObject::tr("Script canceled.")));
149 #endif
150 
151  // Obtem upvalue com definição do método a ser chamado
152  MethodRegistry* reg = (MethodRegistry*)lua_touserdata(L, lua_upvalueindex(1));
153 
154  // Obtem objeto do qual o método será chamado
155  T* proxy = LuaProxy::toObjectOfClass<T>(L, 1);
156  if(!proxy)
157  return luaL_error(L, "%s", luaPrintable(QObject::tr("Redirector for method %1 called on incorrect object type.").arg(reg->_name)));
158 
159  // Chama o método do objeto passado como parâmetro
160  MethodType method = reg->_method;
161  return (proxy->*method)(L);
162  }
163 };
164 
165 
176 template <typename T> class LuaUpMethod
177 {
178 public:
179 
181  typedef int (T::*MethodType)(lua_State*);
182 
184  struct MethodRegistry {
185  const char* _name;
187  };
188 
200  static void registerMethods(lua_State* L, struct MethodRegistry* methods, T* obj)
201  {
202  LUA_SAVE_TOPL(L);
203  assert(obj);
204 
205  // Pilha = tabela
206  for(MethodRegistry* r = methods; r->_name; ++r)
207  {
208  lua_pushstring(L, r->_name); // Pilha = tabela, nome
209  lua_pushlightuserdata(L, r); // Pilha = tabela, nome, ud_reg
210  lua_pushlightuserdata(L, obj); // Pilha = tabela, nome, ud_reg, ud_obj
211  lua_pushcclosure(L, methodRedirector, 2); // Pilha = tabela, nome, funçao
212  lua_settable(L, -3); // Pilha = tabela
213  }
214 
215  LUA_CHECK_TOPL(L);
216  }
217 
218 private:
219 
227  static int methodRedirector(lua_State* L)
228  {
229 #ifdef LUAUTILS_CANCEL
230  // Verifica se a execução do script Lua deve ser cancelada
231  if(LuaEnv::cancelRequested(L))
232  return luaL_error(L, "%s", luaPrintable(QObject::tr("Script canceled.")));
233 #endif
234 
235  // Obtem upvalue com definição do método a ser chamado
236  MethodRegistry* reg = (MethodRegistry*)lua_touserdata(L, lua_upvalueindex(1));
237 
238  // Obtem upvalue com definição do objeto a ser chamado
239  T* obj = (T*)lua_touserdata(L, lua_upvalueindex(2));
240 
241  // Chama o método do objeto passado como parâmetro
242  MethodType method = reg->_method;
243  return (obj->*method)(L);
244  }
245 };
246 
247 
248 
249 #endif
static void registerMethods(lua_State *L, struct MethodRegistry *methods, int upvalues=0)
Registra na tabela contida na pilha as funções contidas em methods. Permite que sejam associados upva...
Definition: luaMethod.h:97
#define LUA_SAVE_TOPL(L)
Macro utilizada para salvar a posiçao do topo da pilha. Recebe um lua_State.
Definition: luaStackBalancer.h:50
MethodType _method
Ponteiro para o método a ser chamado.
Definition: luaMethod.h:79
Classe similar a LuaMethod porém com algumas diferenças fundamentais:
Definition: luaMethod.h:176
const char * _name
Nome do método exportado.
Definition: luaMethod.h:185
QString tr(const char *sourceText, const char *disambiguation, int n)
const char * _name
Nome do método exportado.
Definition: luaMethod.h:78
static int methodRedirector(lua_State *L)
Stub utilizado para chamada dos métodos da classe T.
Definition: luaMethod.h:143
Definicao das classes LuaEnv e AutoLuaEnv.
MethodType _method
Ponteiro para o método a ser chamado.
Definition: luaMethod.h:186
Definicao da classe LuaStackBalancer.
Classe auxiliar para registro dos nomes e métodos a serem chamados.
Definition: luaMethod.h:77
Classe auxiliar para registro dos nomes e métodos a serem chamados.
Definition: luaMethod.h:184
static int methodRedirector(lua_State *L)
Stub utilizado para chamada dos métodos da classe T.
Definition: luaMethod.h:227
Declaration of usefull configuration definitions and some compatibility options fro compiling with se...
static void registerMethods(lua_State *L, struct MethodRegistry *methods, T *obj)
Registra na tabela contida na pilha as funções contidas em methods. Obj deve conter ponteiro par o ob...
Definition: luaMethod.h:200
int(T::* MethodType)(lua_State *)
Typedef para método de T com assinatura de uma função chamada por Lua.
Definition: luaMethod.h:74
Definicao das classes LuaProxy e LuaSimpleProxy.
int(T::* MethodType)(lua_State *)
Typedef para método de T com assinatura de uma função chamada por Lua.
Definition: luaMethod.h:181
Classe auxiliar para facilitar o cadastro de métodos a serem chamados por Lua.
Definition: luaMethod.h:69
#define LUA_CHECK_TOPL(L)
Macro utilizada para verificar se o topo atual da pilha é igual ao valor salvo. Recebe um lua_State.
Definition: luaStackBalancer.h:53