diff options
Diffstat (limited to 'lib/BLua.cc')
-rw-r--r-- | lib/BLua.cc | 1036 |
1 files changed, 518 insertions, 518 deletions
diff --git a/lib/BLua.cc b/lib/BLua.cc index 7c91bb1..a9780fa 100644 --- a/lib/BLua.cc +++ b/lib/BLua.cc @@ -17,446 +17,446 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: BLua.cc,v 1.11 2003-12-10 02:59:31 pixel Exp $ */ - -#include <lualib.h>
-
-#include "BLua.h"
-
-#ifndef BUFFERSIZE
-#define BUFFERSIZE 2048
-#endif
-
-typedef GeneralException LuaException;
-
-class LuaStatics : public Base {
- public:
- static const char * getF(lua_State *, void *, size_t *);
- static int putF(lua_State *, const void *, size_t, void *);
- static int luapanic(lua_State *);
- static int trueluapanic(lua_State *) throw(GeneralException);
- static int destructor(lua_State *);
-
- static int andB(lua_State *);
- static int orB(lua_State *);
- static int xorB(lua_State *);
- static int notB(lua_State *);
- static int hex(lua_State *);
- static int shl(lua_State *);
- static int shr(lua_State *);
-};
-
-std::map<lua_State *, Lua *> Lua::lualist;
-
-int LuaStatics::luapanic(lua_State * L) {
- return trueluapanic(L);
-}
-
-int LuaStatics::trueluapanic(lua_State * L) throw (GeneralException) {
- Lua::find(L)->showerror();
- throw LuaException("Error running Lua code, bailing out.");
-}
-
-int LuaStatics::andB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
- L->error("Incorrect arguments to function `andB'");
- }
-
- a = L->tonumber(1);
- b = L->tonumber(2);
-
- L->push((lua_Number) (a & b));
-
- return 1;
-}
-
-int LuaStatics::orB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
- L->error("Incorrect arguments to function `orB'");
- }
-
- a = L->tonumber(1);
- b = L->tonumber(2);
-
- L->push((lua_Number) (a | b));
-
- return 1;
-}
-
-int LuaStatics::xorB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
- L->error("Incorrect arguments to function `xorB'");
- }
-
- a = L->tonumber(1);
- b = L->tonumber(2);
-
- L->push((lua_Number) (a ^ b));
-
- return 1;
-}
-
-int LuaStatics::notB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 x;
-
- if ((n != 1) && !L->isnumber()) {
- L->error("Incorrect arguments to function `notB'");
- }
-
- x = L->tonumber();
-
- L->push((lua_Number) (~x));
-
- return 1;
-}
-
-int LuaStatics::shl(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) {
- L->error("Incorrect arguments to function `shl'");
- }
-
- a = L->tonumber(1);
- if (n == 2)
- b = L->tonumber(2);
- else
- b = 1;
-
- L->push((lua_Number) (a << b));
-
- return 1;
-}
-
-int LuaStatics::shr(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) {
- L->error("Incorrect arguments to function `shr'");
- }
-
- a = L->tonumber(1);
- if (n == 2)
- b = L->tonumber(2);
- else
- b = 1;
-
- L->push((lua_Number) (a >> b));
-
- return 1;
-}
-
-int LuaStatics::hex(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- int x;
- String r;
-
- if (((n != 1) || (n != 2)) && !L->isnumber(1) && ((n == 2) && !L->isstring(2))) {
- L->error("Incorrect arguments to function `hex'");
- }
-
- x = L->tonumber(1);
- String fmt = n == 2 ? L->tostring() : "%02x";
- r.set(fmt.to_charp(), x);
-
- L->push(r);
-
- return 1;
-}
-
-Lua::Lua() : L(lua_open()) {
+/* $Id: BLua.cc,v 1.12 2003-12-11 16:53:28 pixel Exp $ */ + +#include <lualib.h> + +#include "BLua.h" + +#ifndef BUFFERSIZE +#define BUFFERSIZE 2048 +#endif + +typedef GeneralException LuaException; + +class LuaStatics : public Base { + public: + static const char * getF(lua_State *, void *, size_t *); + static int putF(lua_State *, const void *, size_t, void *); + static int luapanic(lua_State *); + static int trueluapanic(lua_State *) throw(GeneralException); + static int destructor(lua_State *); + + static int andB(lua_State *); + static int orB(lua_State *); + static int xorB(lua_State *); + static int notB(lua_State *); + static int hex(lua_State *); + static int shl(lua_State *); + static int shr(lua_State *); +}; + +std::map<lua_State *, Lua *> Lua::lualist; + +int LuaStatics::luapanic(lua_State * L) { + return trueluapanic(L); +} + +int LuaStatics::trueluapanic(lua_State * L) throw (GeneralException) { + Lua::find(L)->showerror(); + throw LuaException("Error running Lua code, bailing out."); +} + +int LuaStatics::andB(lua_State * _L) { + Lua * L = Lua::find(_L); + int n = L->gettop(); + Uint32 a, b; + + if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) { + L->error("Incorrect arguments to function `andB'"); + } + + a = L->tonumber(1); + b = L->tonumber(2); + + L->push((lua_Number) (a & b)); + + return 1; +} + +int LuaStatics::orB(lua_State * _L) { + Lua * L = Lua::find(_L); + int n = L->gettop(); + Uint32 a, b; + + if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) { + L->error("Incorrect arguments to function `orB'"); + } + + a = L->tonumber(1); + b = L->tonumber(2); + + L->push((lua_Number) (a | b)); + + return 1; +} + +int LuaStatics::xorB(lua_State * _L) { + Lua * L = Lua::find(_L); + int n = L->gettop(); + Uint32 a, b; + + if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) { + L->error("Incorrect arguments to function `xorB'"); + } + + a = L->tonumber(1); + b = L->tonumber(2); + + L->push((lua_Number) (a ^ b)); + + return 1; +} + +int LuaStatics::notB(lua_State * _L) { + Lua * L = Lua::find(_L); + int n = L->gettop(); + Uint32 x; + + if ((n != 1) && !L->isnumber()) { + L->error("Incorrect arguments to function `notB'"); + } + + x = L->tonumber(); + + L->push((lua_Number) (~x)); + + return 1; +} + +int LuaStatics::shl(lua_State * _L) { + Lua * L = Lua::find(_L); + int n = L->gettop(); + Uint32 a, b; + + if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) { + L->error("Incorrect arguments to function `shl'"); + } + + a = L->tonumber(1); + if (n == 2) + b = L->tonumber(2); + else + b = 1; + + L->push((lua_Number) (a << b)); + + return 1; +} + +int LuaStatics::shr(lua_State * _L) { + Lua * L = Lua::find(_L); + int n = L->gettop(); + Uint32 a, b; + + if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) { + L->error("Incorrect arguments to function `shr'"); + } + + a = L->tonumber(1); + if (n == 2) + b = L->tonumber(2); + else + b = 1; + + L->push((lua_Number) (a >> b)); + + return 1; +} + +int LuaStatics::hex(lua_State * _L) { + Lua * L = Lua::find(_L); + int n = L->gettop(); + int x; + String r; + + if (((n != 1) || (n != 2)) && !L->isnumber(1) && ((n == 2) && !L->isstring(2))) { + L->error("Incorrect arguments to function `hex'"); + } + + x = L->tonumber(1); + String fmt = n == 2 ? L->tostring() : "%02x"; + r.set(fmt.to_charp(), x); + + L->push(r); + + return 1; +} + +Lua::Lua() : L(lua_open()) { lua_atpanic(L, LuaStatics::luapanic); - lualist[L] = this;
-
- declarefunc("andB", LuaStatics::andB);
- declarefunc("orB", LuaStatics::orB);
- declarefunc("xorB", LuaStatics::xorB);
- declarefunc("notB", LuaStatics::notB);
- declarefunc("shl", LuaStatics::shl);
- declarefunc("shr", LuaStatics::shr);
- declarefunc("hex", LuaStatics::hex);
-}
-
-Lua::Lua(lua_State * _L) : L(_L) {
+ lualist[L] = this; + + declarefunc("andB", LuaStatics::andB); + declarefunc("orB", LuaStatics::orB); + declarefunc("xorB", LuaStatics::xorB); + declarefunc("notB", LuaStatics::notB); + declarefunc("shl", LuaStatics::shl); + declarefunc("shr", LuaStatics::shr); + declarefunc("hex", LuaStatics::hex); +} + +Lua::Lua(lua_State * _L) : L(_L) { lua_atpanic(L, LuaStatics::luapanic); - lualist[L] = this;
-}
-
-Lua::~Lua() {
- lua_setgcthreshold(L, 0);
- lua_close(L);
-}
-
-Lua::Lua(const Lua & l) throw (GeneralException) {
- throw GeneralException("Error: can't duplicate a Lua object.");
-}
-
-void Lua::open_base() {
- luaopen_base(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_table() {
- luaopen_table(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_io() {
- luaopen_io(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_string() {
- luaopen_string(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_math() {
- luaopen_math(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_debug() {
- luaopen_debug(L);
- lua_pop(L, 1);
-}
-
-void Lua::declarefunc(const String & name, lua_CFunction f, int i) {
- lua_pushstring(L, name.to_charp());
- lua_pushcfunction(L, f);
- lua_settable(L, i);
-}
-
-void Lua::call(const String & f, int i, int nargs, int nresults) {
+ lualist[L] = this; +} + +Lua::~Lua() { + lua_setgcthreshold(L, 0); + lua_close(L); +} + +Lua::Lua(const Lua & l) throw (GeneralException) { + throw GeneralException("Error: can't duplicate a Lua object."); +} + +void Lua::open_base() { + luaopen_base(L); + lua_pop(L, 1); +} + +void Lua::open_table() { + luaopen_table(L); + lua_pop(L, 1); +} + +void Lua::open_io() { + luaopen_io(L); + lua_pop(L, 1); +} + +void Lua::open_string() { + luaopen_string(L); + lua_pop(L, 1); +} + +void Lua::open_math() { + luaopen_math(L); + lua_pop(L, 1); +} + +void Lua::open_debug() { + luaopen_debug(L); + lua_pop(L, 1); +} + +void Lua::declarefunc(const String & name, lua_CFunction f, int i) { + lua_pushstring(L, name.to_charp()); + lua_pushcfunction(L, f); + lua_settable(L, i); +} + +void Lua::call(const String & f, int i, int nargs, int nresults) { lua_pushstring(L, f.to_charp()); - lua_gettable(L, i);
- lua_insert(L, -1 - nargs - nresults);
- lua_call(L, nargs, nresults);
-}
-
-void Lua::call(int nargs, int nresults) {
- lua_call(L, nargs, nresults);
-}
-
-void Lua::push() {
- lua_pushnil(L);
-}
-
-void Lua::push(lua_Number n) {
- lua_pushnumber(L, n);
-}
-
-void Lua::push(const String & s) {
- lua_pushlstring(L, s.to_charp(), s.strlen());
-}
-
-void Lua::push(bool b) {
- lua_pushboolean(L, b);
-}
-
-void Lua::push(char * s, int size) {
- if (size < 0) {
- lua_pushstring(L, s);
- } else {
- lua_pushlstring(L, s, size);
- }
-}
-
-void Lua::push(void * p) {
- lua_pushlightuserdata(L, p);
-}
-
-void Lua::push(lua_CFunction f, int n) {
- lua_pushcclosure(L, f, n);
-}
-
-void Lua::pop(int n) {
- lua_pop(L, n);
-}
-
-void Lua::newtable() {
- lua_newtable(L);
-}
-
-void Lua::settable(int i, bool raw) {
- if (raw) {
- lua_rawset(L, i);
- } else {
- lua_settable(L, i);
- }
-}
-
-void Lua::gettable(int i, bool raw) {
- if (raw) {
- lua_rawget(L, i);
- } else {
- lua_gettable(L, i);
- }
-}
-
-void Lua::setvar() {
- lua_settable(L, LUA_GLOBALSINDEX);
-}
-
-int Lua::gettop() {
- return lua_gettop(L);
-}
-
-void Lua::error(const String & msg) {
- push(msg);
- lua_error(L);
-}
-
-int Lua::type(int i) {
- return lua_type(L, i);
-}
-
-bool Lua::isnil(int i) {
- return lua_isnil(L, i);
-}
-
-bool Lua::isboolean(int i) {
- return lua_isboolean(L, i);
-}
-
-bool Lua::isnumber(int i) {
- return lua_isnumber(L, i);
-}
-
-bool Lua::isstring(int i) {
- return lua_isstring(L, i);
-}
-
-bool Lua::istable(int i) {
- return lua_istable(L, i);
-}
-
-bool Lua::isfunction(int i) {
- return lua_isfunction(L, i);
-}
-
-bool Lua::iscfunction(int i) {
- return lua_iscfunction(L, i);
-}
-
-bool Lua::isuserdata(int i) {
- return lua_isuserdata(L, i);
-}
-
-bool Lua::islightuserdata(int i) {
- return lua_islightuserdata(L, i);
-}
-
-bool Lua::toboolean(int i) {
- return lua_toboolean(L, i);
-}
-
-lua_Number Lua::tonumber(int i) {
- return lua_tonumber(L, i);
-}
-
-String Lua::tostring(int i) {
- if (isnil(i))
- return String();
- return String(lua_tostring(L, i));
-}
-
-lua_CFunction Lua::tocfunction(int i) {
- return lua_tocfunction(L, i);
-}
-
-void * Lua::touserdata(int i) {
- return lua_touserdata(L, i);
-}
-
-Lua * Lua::tothread(int i) {
- return find(lua_tothread(L, i));
-}
-
-struct LoadF {
- Handle * f;
- char buff[BUFFERSIZE];
-};
-
-const char * LuaStatics::getF(lua_State * L, void * ud, size_t * size) {
- LoadF *lf = (LoadF *)ud;
- (void)L;
-
- *size = lf->f->read(lf->buff, BUFFERSIZE);
- return (*size > 0) ? lf->buff : NULL;
-}
-
-struct DumpF {
- Handle * f;
-};
-
-int LuaStatics::putF(lua_State * L, const void * p, size_t size, void * ud) {
- DumpF *lf = (DumpF *)ud;
- (void)L;
-
- return lf->f->write(p, size) == size;
-}
-
-void Lua::load(Handle * h, bool docall) throw (GeneralException) {
- LoadF lf;
- int status;
-
- lf.f = h;
-
- status = lua_load(L, LuaStatics::getF, &lf, h->GetName().to_charp());
-
- if (status) {
- showerror();
- throw LuaException("Error loading lua chunk from Handle `" + h->GetName() + "'");
- }
-
- if (docall)
- call();
-}
-
-extern "C" void luacmain(lua_State * L, int stripping, lua_Chunkwriter w, void * uD);
-
-void Lua::dump(Handle * h, bool strip) {
- DumpF lf;
-
- lf.f = h;
-
- luacmain(L, strip, LuaStatics::putF, &lf);
-}
-
-Lua * Lua::thread() {
- return new Lua(lua_newthread(L));
-}
-
-Lua * Lua::find(lua_State * _L) throw (GeneralException) {
- std::map<lua_State *, Lua *>::iterator i;
-
- if ((i = lualist.find(_L)) == lualist.end()) {
- throw GeneralException("Unable to find the Lua object for this context");
- }
-
- return i->second;
-}
-
+ lua_gettable(L, i); + lua_insert(L, -1 - nargs - nresults); + lua_call(L, nargs, nresults); +} + +void Lua::call(int nargs, int nresults) { + lua_call(L, nargs, nresults); +} + +void Lua::push() { + lua_pushnil(L); +} + +void Lua::push(lua_Number n) { + lua_pushnumber(L, n); +} + +void Lua::push(const String & s) { + lua_pushlstring(L, s.to_charp(), s.strlen()); +} + +void Lua::push(bool b) { + lua_pushboolean(L, b); +} + +void Lua::push(char * s, int size) { + if (size < 0) { + lua_pushstring(L, s); + } else { + lua_pushlstring(L, s, size); + } +} + +void Lua::push(void * p) { + lua_pushlightuserdata(L, p); +} + +void Lua::push(lua_CFunction f, int n) { + lua_pushcclosure(L, f, n); +} + +void Lua::pop(int n) { + lua_pop(L, n); +} + +void Lua::newtable() { + lua_newtable(L); +} + +void Lua::settable(int i, bool raw) { + if (raw) { + lua_rawset(L, i); + } else { + lua_settable(L, i); + } +} + +void Lua::gettable(int i, bool raw) { + if (raw) { + lua_rawget(L, i); + } else { + lua_gettable(L, i); + } +} + +void Lua::setvar() { + lua_settable(L, LUA_GLOBALSINDEX); +} + +int Lua::gettop() { + return lua_gettop(L); +} + +void Lua::error(const String & msg) { + push(msg); + lua_error(L); +} + +int Lua::type(int i) { + return lua_type(L, i); +} + +bool Lua::isnil(int i) { + return lua_isnil(L, i); +} + +bool Lua::isboolean(int i) { + return lua_isboolean(L, i); +} + +bool Lua::isnumber(int i) { + return lua_isnumber(L, i); +} + +bool Lua::isstring(int i) { + return lua_isstring(L, i); +} + +bool Lua::istable(int i) { + return lua_istable(L, i); +} + +bool Lua::isfunction(int i) { + return lua_isfunction(L, i); +} + +bool Lua::iscfunction(int i) { + return lua_iscfunction(L, i); +} + +bool Lua::isuserdata(int i) { + return lua_isuserdata(L, i); +} + +bool Lua::islightuserdata(int i) { + return lua_islightuserdata(L, i); +} + +bool Lua::toboolean(int i) { + return lua_toboolean(L, i); +} + +lua_Number Lua::tonumber(int i) { + return lua_tonumber(L, i); +} + +String Lua::tostring(int i) { + if (isnil(i)) + return String(); + return String(lua_tostring(L, i)); +} + +lua_CFunction Lua::tocfunction(int i) { + return lua_tocfunction(L, i); +} + +void * Lua::touserdata(int i) { + return lua_touserdata(L, i); +} + +Lua * Lua::tothread(int i) { + return find(lua_tothread(L, i)); +} + +struct LoadF { + Handle * f; + char buff[BUFFERSIZE]; +}; + +const char * LuaStatics::getF(lua_State * L, void * ud, size_t * size) { + LoadF *lf = (LoadF *)ud; + (void)L; + + *size = lf->f->read(lf->buff, BUFFERSIZE); + return (*size > 0) ? lf->buff : NULL; +} + +struct DumpF { + Handle * f; +}; + +int LuaStatics::putF(lua_State * L, const void * p, size_t size, void * ud) { + DumpF *lf = (DumpF *)ud; + (void)L; + + return lf->f->write(p, size) == size; +} + +void Lua::load(Handle * h, bool docall) throw (GeneralException) { + LoadF lf; + int status; + + lf.f = h; + + status = lua_load(L, LuaStatics::getF, &lf, h->GetName().to_charp()); + + if (status) { + showerror(); + throw LuaException("Error loading lua chunk from Handle `" + h->GetName() + "'"); + } + + if (docall) + call(); +} + +extern "C" void luacmain(lua_State * L, int stripping, lua_Chunkwriter w, void * uD); + +void Lua::dump(Handle * h, bool strip) { + DumpF lf; + + lf.f = h; + + luacmain(L, strip, LuaStatics::putF, &lf); +} + +Lua * Lua::thread() { + return new Lua(lua_newthread(L)); +} + +Lua * Lua::find(lua_State * _L) throw (GeneralException) { + std::map<lua_State *, Lua *>::iterator i; + + if ((i = lualist.find(_L)) == lualist.end()) { + throw GeneralException("Unable to find the Lua object for this context"); + } + + return i->second; +} + void Lua::showerror() { int n = lua_gettop(L); int i; @@ -499,84 +499,84 @@ void Lua::showerror() { printm(M_ERROR, String(i) + ": " + t + "\n"); } -}
-
-int Lua::getmetatable(int i) {
- return lua_getmetatable(L, i);
-}
-
-int Lua::setmetatable(int i) {
- return lua_setmetatable(L, i);
-}
-
-void LuaObject::push(Lua * L) throw (GeneralException) {
- if (pushed && wantdestruct) {
- throw GeneralException("Error: object is owned by the LUA script and can not be pushed.");
- }
- L->newtable();
- pushmembers(L);
- pushed = true;
-}
-
-void LuaObject::pushme(Lua * L, void * o) {
- L->push("__obj");
- L->push(o);
- L->settable(-3, true);
-}
-
-void * LuaObject::getme(Lua * L, int i) {
- void * r;
-
- if (L->istable(i)) {
- L->push("__obj");
- L->gettable(i, true);
- if (!(r = L->touserdata())) {
- L->error("Lua object already destroyed, or table is not an object.");
- }
- L->pop();
- } else if (L->isnil(i)) {
- r = 0;
- } else {
- L->error("Not an object");
- }
-
- return r;
-}
-
-void LuaObject::pushit(Lua * L, const String & s, lua_CFunction f) {
- L->push(s);
- L->push(f);
- L->settable(-3, true);
-}
-
-void LuaObject::pushmeta(Lua * L, const String & s, lua_CFunction f) {
- if (!L->getmetatable()) {
- L->newtable();
- }
- L->push(s);
- L->push(f);
- L->settable();
- L->setmetatable();
-}
-
-int LuaStatics::destructor(lua_State * _L) {
- Lua * L = Lua::find(_L);
- Base * b = (Base *) LuaObject::getme(L);
- delete b;
- L->push("__obj");
- L->push((void *) 0);
- L->settable(-3, true);
- printm(M_INFO, "Destructing an object from LUA\n");
- return 0;
-}
-
-void LuaObject::pushdestruct(Lua * L) throw (GeneralException) {
- if (pushed) {
- throw GeneralException("Error: can't push destructor, object already pushed");
- }
- push(L);
- pushmeta(L, "__gc", LuaStatics::destructor);
- pushit(L, "destroy", LuaStatics::destructor);
-
- wantdestruct = true;
-}
+} + +int Lua::getmetatable(int i) { + return lua_getmetatable(L, i); +} + +int Lua::setmetatable(int i) { + return lua_setmetatable(L, i); +} + +void LuaObject::push(Lua * L) throw (GeneralException) { + if (pushed && wantdestruct) { + throw GeneralException("Error: object is owned by the LUA script and can not be pushed."); + } + L->newtable(); + pushmembers(L); + pushed = true; +} + +void LuaObject::pushme(Lua * L, void * o) { + L->push("__obj"); + L->push(o); + L->settable(-3, true); +} + +void * LuaObject::getme(Lua * L, int i) { + void * r; + + if (L->istable(i)) { + L->push("__obj"); + L->gettable(i, true); + if (!(r = L->touserdata())) { + L->error("Lua object already destroyed, or table is not an object."); + } + L->pop(); + } else if (L->isnil(i)) { + r = 0; + } else { + L->error("Not an object"); + } + + return r; +} + +void LuaObject::pushit(Lua * L, const String & s, lua_CFunction f) { + L->push(s); + L->push(f); + L->settable(-3, true); +} + +void LuaObject::pushmeta(Lua * L, const String & s, lua_CFunction f) { + if (!L->getmetatable()) { + L->newtable(); + } + L->push(s); + L->push(f); + L->settable(); + L->setmetatable(); +} + +int LuaStatics::destructor(lua_State * _L) { + Lua * L = Lua::find(_L); + Base * b = (Base *) LuaObject::getme(L); + delete b; + L->push("__obj"); + L->push((void *) 0); + L->settable(-3, true); + printm(M_INFO, "Destructing an object from LUA\n"); + return 0; +} + +void LuaObject::pushdestruct(Lua * L) throw (GeneralException) { + if (pushed) { + throw GeneralException("Error: can't push destructor, object already pushed"); + } + push(L); + pushmeta(L, "__gc", LuaStatics::destructor); + pushit(L, "destroy", LuaStatics::destructor); + + wantdestruct = true; +} |