diff options
Diffstat (limited to 'include/BLua.h')
-rw-r--r-- | include/BLua.h | 751 |
1 files changed, 376 insertions, 375 deletions
diff --git a/include/BLua.h b/include/BLua.h index a0daa59..52918ee 100644 --- a/include/BLua.h +++ b/include/BLua.h @@ -1,375 +1,376 @@ -/* - * Baltisot - * Copyright (C) 1999-2003 Nicolas "Pixel" Noble - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: BLua.h,v 1.17 2004-07-23 13:08:22 pixel Exp $ */ - -#ifndef __BLUA_H__ -#define __BLUA_H__ - -struct lua_State; - -extern "C" { - void do_lua_lock(lua_State *); - void do_lua_unlock(lua_State *); -} - -#define lua_lock(L) do_lua_lock(L) -#define lua_unlock(L) do_lua_unlock(L) - -#include <lua.h> -#include <map> -#include <Exceptions.h> -#include <Handle.h> - -class Lua : public Base { - public: - Lua(); - Lua(const Lua &) throw (GeneralException); - virtual ~Lua(); - void open_base(); - void open_table(); - void open_io(); - void open_string(); - void open_math(); - void open_debug(); - void declarefunc(const String &, lua_CFunction, int = LUA_GLOBALSINDEX); - void call(const String &, int = LUA_GLOBALSINDEX, int = 0, int = 0); - void call(int = 0, int = 0); - void push(); - void push(lua_Number); - void push(const String &); - void push(bool); - void push(char *, int size = -1); - void push(void *); - void push(lua_CFunction, int = 0); - void pop(int = 1); - void newtable(); - void * newuser(size_t); - void settable(int = -3, bool raw = false); - void gettable(int = -2, bool raw = false); - void setvar(); - int gettop(); - void error(const String &); - int type(int = -1); - bool isnil(int = -1); - bool isboolean(int = -1); - bool isnumber(int = -1); - bool isstring(int = -1); - bool istable(int = -1); - bool isfunction(int = -1); - bool iscfunction(int = -1); - bool isuserdata(int = -1); - bool islightuserdata(int = -1); - bool toboolean(int = -1); - lua_Number tonumber(int = -1); - String tostring(int = -1); - lua_CFunction tocfunction(int = -1); - void * touserdata(int = -1); - Lua * tothread(int = -1); - void load(Handle *, bool docall = true) throw (GeneralException); - void dump(Handle *, bool strip = true); - Lua * thread(); - int yield(int nargs = 0); - int resume(int nresults = 0); - static Lua * find(lua_State *) throw (GeneralException); - void showerror(); - int getmetatable(int = -1); - int setmetatable(int = -2); - int sethook(lua_Hook func, int mask, int count); - - void do_break(); - - virtual void lock() {} - virtual void unlock() {} - private: - Lua(lua_State *); - lua_State * L; - static std::map<lua_State *, Lua *> lualist; -}; - -class LuaObject : public Base { - public: - LuaObject() : wantdestruct(false), pushed(false) {} - virtual void push(Lua *) throw (GeneralException); - static void * getme(Lua *, int = 1); - void pushdestruct(Lua *) throw (GeneralException); - protected: - virtual void pushmembers(Lua *) = 0; - void pushme(Lua *, void *, bool = true); - static void pushit(Lua *, const String &, lua_CFunction); - static void pushmeta(Lua *, const String &, lua_CFunction); - bool wantdestruct, pushed; -}; - -class LuaException : public GeneralException { - public: - LuaException(String); - protected: - LuaException(); -}; - -enum Lua_types_t { - LUA_OBJECT = 0x01, - LUA_TABLE = 0x02, - LUA_BOOLEAN = 0x04, - LUA_NUMBER = 0x08, - LUA_STRING = 0x10, - LUA_FUNCTION = 0x20, - LUA_NIL = 0x40, - LUA_ANY = 0x7f, -}; - -#define MAX_TYPE 7 - -#define MAXARGS 32 - -struct lua_functypes_t { - int number; - char * name; - int minargs, maxargs; - int argtypes[MAXARGS]; -}; - -#define DECLARE_METHOD(classname, enumvar) static int method_##enumvar(lua_State * L) { \ - return LuaHelpers<classname>::method_multiplex( \ - enumvar, \ - L, \ - sLua_##classname::classname##_proceed, \ - 0, \ - classname##_methods, \ - true); \ - } - -#define DECLARE_FUNCTION(classname, enumvar) static int function_##enumvar(lua_State * L) { \ - return LuaHelpers<classname>::method_multiplex( \ - enumvar, \ - L, \ - 0, \ - sLua_##classname::classname##_proceed_statics, \ - classname##_functions, \ - false); \ - } - -#define PUSH_METHOD(classname, enumvar) pushit( \ - L, \ - classname##_methods[enumvar].name, \ - sLua_##classname::method_##enumvar) - -#define PUSH_METAMETHOD(classname, enumvar) pushmeta( \ - L, \ - String("__") + classname##_methods[enumvar].name, \ - sLua_##classname::method_##enumvar) - -#define PUSH_FUNCTION(classname, enumvar) L->declarefunc( \ - classname##_functions[enumvar].name, \ - sLua_##classname::function_##enumvar) - - -#define CHECK_METHODS(classname) { \ - int i = 0; \ - while (classname##_methods[i].number != -1) { \ - if (i != classname##_methods[i].number) { \ - throw GeneralException("Datas of " #classname "_methods inconsistants!"); \ - } \ - i++; \ - } \ -} - -#define CHECK_FUNCTIONS(classname) { \ - int i = 0; \ - while (classname##_functions[i].number != -1) { \ - if (i != classname##_functions[i].number) { \ - throw GeneralException("Datas of " #classname "_functions inconsistants!"); \ - } \ - i++; \ - } \ -} - -#include <typeinfo> - -template <class T> -class LuaHelpers : public Base { - public: - static int method_multiplex(int caller, lua_State * _L, int (*proceed)(Lua * L, int n, T * obj, int caller), int (*proceed_static)(Lua * L, int n, int caller), lua_functypes_t * tab, bool method) { - Lua * L = Lua::find(_L); - int add = method ? 1 : 0; - int n = L->gettop() - add; - T * obj = 0; - int i, j, mask; - bool invalid = false, arg_valid; - - if (method) - obj = (T *) LuaObject::getme(L); - - if ((n < tab[caller].minargs) || (n > tab[caller].maxargs)) { - invalid = true; - } else { - for (i = 0; i < tab[caller].maxargs && !invalid; i++) { - if (n >= (i + 1)) { - arg_valid = false; - for (j = 0; j < MAX_TYPE && !arg_valid; j++) { - mask = 1 << j; - if (tab[caller].argtypes[i] & mask) { - switch(mask) { - case LUA_OBJECT: - if (L->istable(i + 1 + add)) { - L->push("__obj"); - L->gettable(i + 1 + add); - arg_valid = L->isuserdata(); - L->pop(); - } else { - arg_valid = L->isnil(i + 1 + add); - } - break; - case LUA_TABLE: - arg_valid = L->istable(i + 1 + add); - break; - case LUA_BOOLEAN: - arg_valid = L->isboolean(i + 1 + add); - break; - case LUA_NUMBER: - arg_valid = L->isnumber(i + 1 + add); - break; - case LUA_STRING: - arg_valid = L->isstring(i + 1 + add); - break; - case LUA_FUNCTION: - arg_valid = L->isfunction(i + 1 + add); - break; - case LUA_NIL: - arg_valid = L->isnil(i + 1 + add); - break; - } - } - } - invalid = !arg_valid; - } - } - } - - if (invalid) { - if (method) { - L->error(String("Invalid arguments to method `") + typeid(T).name() + "::" + tab[caller].name + "'"); - } else { - L->error(String("Invalid arguments to function `") + typeid(T).name() + "::" + tab[caller].name + "'"); - } - } - - if (method) { - return proceed(L, n, obj, caller); - } else { - return proceed_static(L, n, caller); - } - } -}; - - - /*******************************\ -|** Let's have a sample of use **| - \*******************************/ - -#ifdef THIS_IS_A_SAMPLE_WHICH_DOES_NOT_COMPILE -Luacdfile::Luacdfile(cdfile * h) : LuaHandle(h) { } - -enum cdfile_methods_t { - CDFILE_XXX = 0, - CDFILE_YYY -}; - -enum cdfile_functions_t { - CDFILE_NEWCDFILE = 0, -}; - -struct lua_functypes_t cdutils_methods[] = { - { CDFILE_XXX, "xxx", 1, 1, {LUA_OBJECT} }, - { CDFILE_YYY, "yyy", 0, 2, {LUA_NUMBER, LUA_NUMBER} }, - { -1, 0, 0, 0, 0 } -}; - -struct lua_functypes_t cdfile_functions[] = { - { CDFILE_NEWCDFILE, "cdfile", 1, 4, {LUA_OBJECT, LUA_ANY, LUA_NUMBER, LUA_NUMBER} }, - { -1, 0, 0, 0, 0 } -}; - -class sLua_cdfile : public Base { - public: - static int newcdfile(lua_State * L); - DECLARE_METHOD(cdfile, CDFILE_XXX); - DECLARE_METHOD(cdfile, CDFILE_YYY); - DECLARE_FUNCTION(cdfile, CDFILE_NEWCDFILE); - private: - static int cdfile_proceed(Lua * L, int n, cdfile * obj, int caller); - static int cdfile_proceed_statics(Lua * L, int n, int caller); -}; - -void Luacdfile::pushmembers(Lua * L) { - { - LuaHandle::pushmembers(L); - or - pushme(L, SomeObject); - } - PUSH_METHOD(cdfile, CDFILE_XXX); - PUSH_METHOD(cdfile, CDFILE_YYY); -} - -void Luacdfile::pushstatics(Lua * L) { - CHECK_METHODS(cdfile); - CHECK_FUNCTIONS(cdfile); - - PUSH_FUNCTION(cdfile, CDFILE_NEWCDFILE); -} - -int sLua_cdfile::cdfile_proceed(Lua * L, int n, cdfile * cdfile, int caller) { - int r = 0; - SomeObj * obj; - int arg1 = DEFAULT1, arg2 = DEFAULT2; - - switch(caller) { - case CDFILE_XXX: - obj = (SomeObj *) LuaObject::getme(L, 2); - cdfile->xxx(obj); - break; - case CDFILE_YYY: - if (n >= 1) - arg1 = L->tonumber(2); - if (n >= 2) - arg2 = L->tonumber(3); - L->push((lua_Number) cdfile->yyy(arg1, arg2)); - r = 1; - break; - } - - return r; -} - -int sLua_cdfile::cdfile_proceed_statics(Lua * L, int n, int caller) { - int r = 0; - - switch(caller) { - case CDFILE_NEWCDFILE: - /****TODO****/ - break; - } - - return r; -} - -#endif - -#endif +/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: BLua.h,v 1.18 2004-11-27 21:01:20 pixel Exp $ */
+
+#ifndef __BLUA_H__
+#define __BLUA_H__
+
+struct lua_State;
+
+extern "C" {
+ void do_lua_lock(lua_State *);
+ void do_lua_unlock(lua_State *);
+}
+
+#define lua_lock(L) do_lua_lock(L)
+#define lua_unlock(L) do_lua_unlock(L)
+
+#include <lua.h>
+#include <map>
+#include <Exceptions.h>
+#include <Handle.h>
+
+class Lua : public Base {
+ public:
+ Lua();
+ Lua(const Lua &) throw (GeneralException);
+ virtual ~Lua();
+ void open_base();
+ void open_table();
+ void open_io();
+ void open_string();
+ void open_math();
+ void open_debug();
+ void open_dir();
+ void declarefunc(const String &, lua_CFunction, int = LUA_GLOBALSINDEX);
+ void call(const String &, int = LUA_GLOBALSINDEX, int = 0, int = 0);
+ void call(int = 0, int = 0);
+ void push();
+ void push(lua_Number);
+ void push(const String &);
+ void push(bool);
+ void push(char *, int size = -1);
+ void push(void *);
+ void push(lua_CFunction, int = 0);
+ void pop(int = 1);
+ void newtable();
+ void * newuser(size_t);
+ void settable(int = -3, bool raw = false);
+ void gettable(int = -2, bool raw = false);
+ void setvar();
+ int gettop();
+ void error(const String &);
+ int type(int = -1);
+ bool isnil(int = -1);
+ bool isboolean(int = -1);
+ bool isnumber(int = -1);
+ bool isstring(int = -1);
+ bool istable(int = -1);
+ bool isfunction(int = -1);
+ bool iscfunction(int = -1);
+ bool isuserdata(int = -1);
+ bool islightuserdata(int = -1);
+ bool toboolean(int = -1);
+ lua_Number tonumber(int = -1);
+ String tostring(int = -1);
+ lua_CFunction tocfunction(int = -1);
+ void * touserdata(int = -1);
+ Lua * tothread(int = -1);
+ void load(Handle *, bool docall = true) throw (GeneralException);
+ void dump(Handle *, bool strip = true);
+ Lua * thread();
+ int yield(int nargs = 0);
+ int resume(int nresults = 0);
+ static Lua * find(lua_State *) throw (GeneralException);
+ void showerror();
+ int getmetatable(int = -1);
+ int setmetatable(int = -2);
+ int sethook(lua_Hook func, int mask, int count);
+
+ void do_break();
+
+ virtual void lock() {}
+ virtual void unlock() {}
+ private:
+ Lua(lua_State *);
+ lua_State * L;
+ static std::map<lua_State *, Lua *> lualist;
+};
+
+class LuaObject : public Base {
+ public:
+ LuaObject() : wantdestruct(false), pushed(false) {}
+ virtual void push(Lua *) throw (GeneralException);
+ static void * getme(Lua *, int = 1);
+ void pushdestruct(Lua *) throw (GeneralException);
+ protected:
+ virtual void pushmembers(Lua *) = 0;
+ void pushme(Lua *, void *, bool = true);
+ static void pushit(Lua *, const String &, lua_CFunction);
+ static void pushmeta(Lua *, const String &, lua_CFunction);
+ bool wantdestruct, pushed;
+};
+
+class LuaException : public GeneralException {
+ public:
+ LuaException(String);
+ protected:
+ LuaException();
+};
+
+enum Lua_types_t {
+ LUA_OBJECT = 0x01,
+ LUA_TABLE = 0x02,
+ LUA_BOOLEAN = 0x04,
+ LUA_NUMBER = 0x08,
+ LUA_STRING = 0x10,
+ LUA_FUNCTION = 0x20,
+ LUA_NIL = 0x40,
+ LUA_ANY = 0x7f,
+};
+
+#define MAX_TYPE 7
+
+#define MAXARGS 32
+
+struct lua_functypes_t {
+ int number;
+ char * name;
+ int minargs, maxargs;
+ int argtypes[MAXARGS];
+};
+
+#define DECLARE_METHOD(classname, enumvar) static int method_##enumvar(lua_State * L) { \
+ return LuaHelpers<classname>::method_multiplex( \
+ enumvar, \
+ L, \
+ sLua_##classname::classname##_proceed, \
+ 0, \
+ classname##_methods, \
+ true); \
+ }
+
+#define DECLARE_FUNCTION(classname, enumvar) static int function_##enumvar(lua_State * L) { \
+ return LuaHelpers<classname>::method_multiplex( \
+ enumvar, \
+ L, \
+ 0, \
+ sLua_##classname::classname##_proceed_statics, \
+ classname##_functions, \
+ false); \
+ }
+
+#define PUSH_METHOD(classname, enumvar) pushit( \
+ L, \
+ classname##_methods[enumvar].name, \
+ sLua_##classname::method_##enumvar)
+
+#define PUSH_METAMETHOD(classname, enumvar) pushmeta( \
+ L, \
+ String("__") + classname##_methods[enumvar].name, \
+ sLua_##classname::method_##enumvar)
+
+#define PUSH_FUNCTION(classname, enumvar) L->declarefunc( \
+ classname##_functions[enumvar].name, \
+ sLua_##classname::function_##enumvar)
+
+
+#define CHECK_METHODS(classname) { \
+ int i = 0; \
+ while (classname##_methods[i].number != -1) { \
+ if (i != classname##_methods[i].number) { \
+ throw GeneralException("Datas of " #classname "_methods inconsistants!"); \
+ } \
+ i++; \
+ } \
+}
+
+#define CHECK_FUNCTIONS(classname) { \
+ int i = 0; \
+ while (classname##_functions[i].number != -1) { \
+ if (i != classname##_functions[i].number) { \
+ throw GeneralException("Datas of " #classname "_functions inconsistants!"); \
+ } \
+ i++; \
+ } \
+}
+
+#include <typeinfo>
+
+template <class T>
+class LuaHelpers : public Base {
+ public:
+ static int method_multiplex(int caller, lua_State * _L, int (*proceed)(Lua * L, int n, T * obj, int caller), int (*proceed_static)(Lua * L, int n, int caller), lua_functypes_t * tab, bool method) {
+ Lua * L = Lua::find(_L);
+ int add = method ? 1 : 0;
+ int n = L->gettop() - add;
+ T * obj = 0;
+ int i, j, mask;
+ bool invalid = false, arg_valid;
+
+ if (method)
+ obj = (T *) LuaObject::getme(L);
+
+ if ((n < tab[caller].minargs) || (n > tab[caller].maxargs)) {
+ invalid = true;
+ } else {
+ for (i = 0; i < tab[caller].maxargs && !invalid; i++) {
+ if (n >= (i + 1)) {
+ arg_valid = false;
+ for (j = 0; j < MAX_TYPE && !arg_valid; j++) {
+ mask = 1 << j;
+ if (tab[caller].argtypes[i] & mask) {
+ switch(mask) {
+ case LUA_OBJECT:
+ if (L->istable(i + 1 + add)) {
+ L->push("__obj");
+ L->gettable(i + 1 + add);
+ arg_valid = L->isuserdata();
+ L->pop();
+ } else {
+ arg_valid = L->isnil(i + 1 + add);
+ }
+ break;
+ case LUA_TABLE:
+ arg_valid = L->istable(i + 1 + add);
+ break;
+ case LUA_BOOLEAN:
+ arg_valid = L->isboolean(i + 1 + add);
+ break;
+ case LUA_NUMBER:
+ arg_valid = L->isnumber(i + 1 + add);
+ break;
+ case LUA_STRING:
+ arg_valid = L->isstring(i + 1 + add);
+ break;
+ case LUA_FUNCTION:
+ arg_valid = L->isfunction(i + 1 + add);
+ break;
+ case LUA_NIL:
+ arg_valid = L->isnil(i + 1 + add);
+ break;
+ }
+ }
+ }
+ invalid = !arg_valid;
+ }
+ }
+ }
+
+ if (invalid) {
+ if (method) {
+ L->error(String("Invalid arguments to method `") + typeid(T).name() + "::" + tab[caller].name + "'");
+ } else {
+ L->error(String("Invalid arguments to function `") + typeid(T).name() + "::" + tab[caller].name + "'");
+ }
+ }
+
+ if (method) {
+ return proceed(L, n, obj, caller);
+ } else {
+ return proceed_static(L, n, caller);
+ }
+ }
+};
+
+
+ /*******************************\
+|** Let's have a sample of use **|
+ \*******************************/
+
+#ifdef THIS_IS_A_SAMPLE_WHICH_DOES_NOT_COMPILE
+Luacdfile::Luacdfile(cdfile * h) : LuaHandle(h) { }
+
+enum cdfile_methods_t {
+ CDFILE_XXX = 0,
+ CDFILE_YYY
+};
+
+enum cdfile_functions_t {
+ CDFILE_NEWCDFILE = 0,
+};
+
+struct lua_functypes_t cdutils_methods[] = {
+ { CDFILE_XXX, "xxx", 1, 1, {LUA_OBJECT} },
+ { CDFILE_YYY, "yyy", 0, 2, {LUA_NUMBER, LUA_NUMBER} },
+ { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t cdfile_functions[] = {
+ { CDFILE_NEWCDFILE, "cdfile", 1, 4, {LUA_OBJECT, LUA_ANY, LUA_NUMBER, LUA_NUMBER} },
+ { -1, 0, 0, 0, 0 }
+};
+
+class sLua_cdfile : public Base {
+ public:
+ static int newcdfile(lua_State * L);
+ DECLARE_METHOD(cdfile, CDFILE_XXX);
+ DECLARE_METHOD(cdfile, CDFILE_YYY);
+ DECLARE_FUNCTION(cdfile, CDFILE_NEWCDFILE);
+ private:
+ static int cdfile_proceed(Lua * L, int n, cdfile * obj, int caller);
+ static int cdfile_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luacdfile::pushmembers(Lua * L) {
+ {
+ LuaHandle::pushmembers(L);
+ or
+ pushme(L, SomeObject);
+ }
+ PUSH_METHOD(cdfile, CDFILE_XXX);
+ PUSH_METHOD(cdfile, CDFILE_YYY);
+}
+
+void Luacdfile::pushstatics(Lua * L) {
+ CHECK_METHODS(cdfile);
+ CHECK_FUNCTIONS(cdfile);
+
+ PUSH_FUNCTION(cdfile, CDFILE_NEWCDFILE);
+}
+
+int sLua_cdfile::cdfile_proceed(Lua * L, int n, cdfile * cdfile, int caller) {
+ int r = 0;
+ SomeObj * obj;
+ int arg1 = DEFAULT1, arg2 = DEFAULT2;
+
+ switch(caller) {
+ case CDFILE_XXX:
+ obj = (SomeObj *) LuaObject::getme(L, 2);
+ cdfile->xxx(obj);
+ break;
+ case CDFILE_YYY:
+ if (n >= 1)
+ arg1 = L->tonumber(2);
+ if (n >= 2)
+ arg2 = L->tonumber(3);
+ L->push((lua_Number) cdfile->yyy(arg1, arg2));
+ r = 1;
+ break;
+ }
+
+ return r;
+}
+
+int sLua_cdfile::cdfile_proceed_statics(Lua * L, int n, int caller) {
+ int r = 0;
+
+ switch(caller) {
+ case CDFILE_NEWCDFILE:
+ /****TODO****/
+ break;
+ }
+
+ return r;
+}
+
+#endif
+
+#endif
|