├── luaObject.h ├── luacommon.h ├── Makefile ├── test └── test_class │ ├── test.lua │ └── test.cpp ├── luaWrapper.h ├── luaWrapper.cpp ├── Trait.h ├── TypeList.h ├── README.md ├── utility.h ├── PopValue.h ├── any.h ├── ObjPush.h ├── luaFunction.h └── luaClass.h /luaObject.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sniperHW/luawrapper/HEAD/luaObject.h -------------------------------------------------------------------------------- /luacommon.h: -------------------------------------------------------------------------------- 1 | #ifndef _LUACOMMON_H 2 | #define _LUACOMMON_H 3 | extern "C" 4 | { 5 | #include "lua.h" 6 | #include "lauxlib.h" 7 | #include "lualib.h" 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | INCLUDE = -I/usr/local/include -I./ 2 | LIBRARY = -L/usr/local/lib 3 | 4 | all: 5 | g++ -g -c *.cpp -std=c++0x $(INCLUDE) 6 | g++ -g -o test/test_class/test test/test_class/test.cpp luaWrapper.o -llua -ldl $(LIBRARY) $(INCLUDE) 7 | -------------------------------------------------------------------------------- /test/test_class/test.lua: -------------------------------------------------------------------------------- 1 | 2 | function test1(obj1,obj2) 3 | print("test1",obj1 == obj2) 4 | print(obj1,obj2) 5 | print(obj1.memb_a) 6 | obj1.memb_a = 101 7 | obj1:show() 8 | obj1 = nil 9 | obj2 = nil 10 | collectgarbage("collect") 11 | end 12 | 13 | function test2(b,c) 14 | print("test2",b == c) 15 | print(b,c) 16 | b:show() 17 | c:show2() 18 | c:child_show() 19 | b:child_show() 20 | end 21 | 22 | function test3(obj) 23 | print("test3") 24 | print("obj.memb_a",obj.memb_a) 25 | pass_by_value(obj) 26 | print("after call pass_by_value",obj.memb_a) 27 | pass_by_reference(obj) 28 | print("after call pass_by_reference",obj.memb_a) 29 | end 30 | 31 | function test4(obj) 32 | print("test4") 33 | return {obj,obj} 34 | end 35 | 36 | function test5() 37 | print("test5") 38 | local a = test_class_A(999) 39 | local c = test_class_A(1) 40 | 41 | local mt = getmetatable(a) 42 | for k,v in pairs(mt) do 43 | print(k,v) 44 | end 45 | 46 | 47 | print(a,a.memb_a) 48 | local b = pass_by_reference(a) 49 | print(a,b,a == b) 50 | print(a,b,a.memb_a,b.memb_a) 51 | end 52 | 53 | --print(test1) -------------------------------------------------------------------------------- /luaWrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) <2012> 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | #ifndef _LUAWRAPPER_H 18 | #define _LUAWRAPPER_H 19 | 20 | #pragma once 21 | #include "luacommon.h" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "luaObject.h" 27 | #include "luaClass.h" 28 | #include "PopValue.h" 29 | #include "ObjPush.h" 30 | 31 | namespace luacpp{ 32 | 33 | class luaWrapper 34 | { 35 | public: 36 | operator lua_State* () 37 | { 38 | return lState; 39 | } 40 | 41 | void init(); 42 | luaWrapper(){init();} 43 | ~luaWrapper() 44 | { 45 | if(lState) 46 | lua_close(lState); 47 | lState = NULL; 48 | } 49 | 50 | bool dofile(const char *filename); 51 | 52 | private: 53 | lua_State *lState; 54 | }; 55 | } 56 | 57 | #endif -------------------------------------------------------------------------------- /luaWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "luaWrapper.h" 2 | #include 3 | namespace luacpp{ 4 | 5 | std::map ptrToUserData; 6 | std::set userdataSet; 7 | const char *table_userdata_info = "kenny.lualib.userdata_info"; 8 | 9 | bool luaWrapper::dofile(const char *filename) 10 | { 11 | if (luaL_dofile(lState, filename)) { 12 | const char * error = lua_tostring(lState, -1); 13 | lua_pop(lState,1); 14 | printf("%s\n",error); 15 | return false; 16 | } 17 | return true; 18 | } 19 | 20 | void luaWrapper::init() 21 | { 22 | lState = luaL_newstate(); 23 | luaL_openlibs(lState); 24 | 25 | lua_newtable(lState); 26 | lua_newtable(lState); 27 | lua_pushstring(lState,"__mode"); 28 | lua_pushstring(lState,"v"); 29 | lua_rawset(lState,-3); 30 | lua_setmetatable(lState,-2); 31 | lua_setglobal(lState,table_userdata_info); 32 | 33 | } 34 | 35 | void set_userdata(lua_State *L,void *ptr,int index) { 36 | lua_pushvalue(L,index); 37 | lua_getglobal(L,table_userdata_info); 38 | lua_pushlightuserdata(L,ptr); //push key 39 | lua_rotate(L,lua_gettop(L)-3,3); 40 | lua_rawset(L,-3); 41 | lua_pop(L,1); 42 | } 43 | 44 | void get_userdata(lua_State *L,void *ptr) { 45 | lua_getglobal(L,table_userdata_info); 46 | lua_pushlightuserdata(L,ptr); //push key 47 | lua_rawget(L,-2); 48 | lua_replace(L,-2); 49 | } 50 | 51 | int pushObj(lua_State *L,const void *ptr,const char *classname) 52 | { 53 | objUserData *userdata = (objUserData*)ptrToUserData[(void*)ptr]; 54 | if(!userdata) { 55 | size_t nbytes = sizeof(objUserData); 56 | userdata = (objUserData *)lua_newuserdata(L, nbytes); 57 | userdata->ptr = const_cast(ptr); 58 | userdata->construct_by_lua = false; 59 | ptrToUserData[(void*)ptr] = userdata; 60 | userdataSet.insert((void*)userdata); 61 | set_userdata(L,(void*)userdata,-1); 62 | luaL_setmetatable(L,classname); 63 | } else { 64 | get_userdata(L,(void*)userdata); 65 | } 66 | return 1; 67 | 68 | } 69 | 70 | void get_luatable(luatable <,lua_State *L) 71 | { 72 | lt = popvalue(L); 73 | } 74 | } -------------------------------------------------------------------------------- /Trait.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) <2012> 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | #ifndef _TRAIT_H 18 | #define _TRAIT_H 19 | 20 | //pointer traits 21 | template 22 | struct pointerTraits 23 | { 24 | enum { isPointer = false}; 25 | typedef T PointeeType; 26 | }; 27 | 28 | template 29 | struct pointerTraits 30 | { 31 | enum { isPointer = true}; 32 | typedef T PointeeType; 33 | }; 34 | 35 | template 36 | struct pointerTraits 37 | { 38 | enum { isPointer = true}; 39 | typedef const T PointeeType; 40 | }; 41 | 42 | template 43 | struct pointerTraits 44 | { 45 | enum { isPointer = true}; 46 | typedef const T PointeeType; 47 | }; 48 | 49 | 50 | template 51 | struct pointerTraits 52 | { 53 | enum { isPointer = true}; 54 | typedef T PointeeType; 55 | }; 56 | 57 | //pointer traits 58 | template 59 | struct refTraits 60 | { 61 | enum { isRef = false}; 62 | typedef T RefType; 63 | }; 64 | 65 | template 66 | struct refTraits 67 | { 68 | enum { isRef = true}; 69 | typedef T RefType; 70 | }; 71 | 72 | template 73 | struct refTraits 74 | { 75 | enum { isPointer = true}; 76 | typedef T RefType; 77 | }; 78 | ///// 79 | 80 | template 81 | struct isVoid 82 | { 83 | enum {is_Void = 0}; 84 | }; 85 | 86 | template<> 87 | struct isVoid 88 | { 89 | enum {is_Void = 1}; 90 | }; 91 | 92 | 93 | #endif -------------------------------------------------------------------------------- /TypeList.h: -------------------------------------------------------------------------------- 1 | #ifndef _TYPELIST_H 2 | #define _TYPELIST_H 3 | 4 | class NullType {}; 5 | 6 | 7 | //Typelist 8 | 9 | template 10 | struct Typelist 11 | { 12 | typedef T Head; 13 | typedef U Tail; 14 | }; 15 | 16 | template struct IndexOf; 17 | 18 | template 19 | struct IndexOf 20 | { 21 | enum { value = -1 }; 22 | }; 23 | 24 | template 25 | struct IndexOf, T> 26 | { 27 | enum { value = 0 }; 28 | }; 29 | 30 | template 31 | struct IndexOf, T> 32 | { 33 | private: 34 | enum { temp = IndexOf::value }; 35 | public: 36 | enum { value = (temp == -1 ? -1 : 1 + temp) }; 37 | }; 38 | 39 | #define LOKI_TYPELIST_1(T1) Typelist 40 | 41 | #define LOKI_TYPELIST_2(T1, T2) Typelist 42 | 43 | #define LOKI_TYPELIST_3(T1, T2, T3) Typelist 44 | 45 | #define LOKI_TYPELIST_4(T1, T2, T3, T4) \ 46 | Typelist 47 | 48 | #define LOKI_TYPELIST_5(T1, T2, T3, T4, T5) \ 49 | Typelist 50 | 51 | #define LOKI_TYPELIST_6(T1, T2, T3, T4, T5, T6) \ 52 | Typelist 53 | 54 | #define LOKI_TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \ 55 | Typelist 56 | 57 | #define LOKI_TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \ 58 | Typelist 59 | 60 | #define LOKI_TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \ 61 | Typelist 62 | 63 | #define LOKI_TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \ 64 | Typelist 65 | 66 | #define LOKI_TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \ 67 | Typelist 68 | 69 | #define LOKI_TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \ 70 | Typelist 72 | 73 | #define LOKI_TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,T13) \ 74 | Typelist 76 | 77 | #define LOKI_TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,T13,T14) \ 78 | Typelist 80 | 81 | #define LOKI_TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,T13,T14,T15) \ 82 | Typelist 84 | 85 | template 86 | struct Int2Type 87 | { 88 | enum {value = v}; 89 | }; 90 | 91 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ###C++对lua访问接口的封装,提供访问lua函数,向lua暴露普通C函数,向lua注册C++类型,对lua对象和表的封装等等. 2 | 3 | 4 | ####[向lua注册函数] 5 | 6 | static int showmsg(const char *msg) 7 | { 8 | printf("c-showmsg:%s\n",msg); 9 | return 0; 10 | } 11 | 12 | luacpp::reg_cfun(L,"cshow",showmsg); 13 | 14 | ####[调用lua函数] 15 | 16 | luacpp::call(L,"test1"); 17 | 18 | ####[注册c++类型] 19 | 20 | --C++ code 21 | 22 | class test_class_A 23 | { 24 | public: 25 | test_class_A():memb_a(0) 26 | { 27 | printf("test_class_A void\n"); 28 | } 29 | test_class_A(const test_class_A &other):memb_a(other.memb_a) 30 | { 31 | printf("test_class_A con %d \n",memb_a); 32 | } 33 | ~test_class_A() 34 | { 35 | printf("~test_class_A\n"); 36 | } 37 | int memb_a; 38 | void show() 39 | { 40 | printf("test_class_A::show\n"); 41 | } 42 | }; 43 | 44 | luacpp::reg_cclass::_reg(L,"test_class_A") 45 | .constructor()//无参构造 46 | .constructor()//一个参数构造 47 | .property("memb_a",&test_class_A::memb_a) 48 | .function("show",&test_class_A::show); 49 | 50 | --lua code 51 | 52 | function test12(obj) 53 | local t1 = test_class_A() 54 | t1.memb_a = 100 55 | local t2 = test_class_A(t1) 56 | print(t2.memb_a) 57 | t2:show() 58 | end 59 | 60 | 61 | 62 | ####[获取lua全局变量] 63 | 64 | luatable lt = luacpp::Get(L,"t_table"); 65 | 66 | ####[设置lua全局变量] 67 | 68 | luacpp::Set(L,"TEST_GLOBAL","this is test global"); 69 | 70 | 71 | ####[访问lua中的Object] 72 | 73 | --lua code 74 | Account = { 75 | balance = 10, 76 | names=0, 77 | [1] = 1, 78 | [2.2] = 2.2, 79 | } 80 | 81 | function Account:withdraw (v) 82 | self.balance = self.balance - v 83 | end 84 | 85 | function Account:new (o) 86 | o = o or {} 87 | setmetatable(o, self) 88 | self.__index = self 89 | return o 90 | end 91 | 92 | function Account:show() 93 | print("this is account show") 94 | end 95 | 96 | function Account:getBalance() 97 | return self.balance 98 | end 99 | 100 | function Account:setBalance(val) 101 | self.balance = val 102 | end 103 | 104 | function GetAccount() 105 | return Account:new() 106 | end 107 | 108 | 109 | --C++ code 110 | luaObject lo = luacpp::call(L,"GetAccount"); 111 | lo.call("show"); 112 | printf("balance:%d\n",lo.Get("balance")); 113 | lo.Set("balance",1000); 114 | printf("balance:%d\n",lo.Get("balance")); 115 | printf("1:%d\n",lo.Get(1)); 116 | printf("2:%f\n",lo.Get(2.2)); 117 | 118 | 119 | ###[访问数组形式的lua表] 120 | 121 | ####[从lua返回] 122 | 123 | --lua code 124 | function get_lua_array() 125 | return {"a","b","c","d","e","f"} 126 | end 127 | 128 | 129 | --C++ code 130 | 131 | luatable lt = luacpp::call(L,"get_lua_array"); 132 | for(int i = 0 ;i < (int)lt.size(); ++i) 133 | printf("%s\n",any_cast(lt[i]).c_str()); 134 | 135 | 136 | ####[传递到lua] 137 | --C++ code 138 | 139 | luatable lt; 140 | lt.push_back(1); 141 | lt.push_back(2); 142 | lt.push_back(3); 143 | luacpp::call(L,"pass_luatable",lt); 144 | 145 | 146 | --lua code 147 | function pass_luatable(lt) 148 | print(lt[1]) 149 | print(lt[2]) 150 | print(lt[3]) 151 | end 152 | -------------------------------------------------------------------------------- /test/test_class/test.cpp: -------------------------------------------------------------------------------- 1 | #include "luaWrapper.h" 2 | #include 3 | 4 | typedef luacpp::luatable luatable; 5 | typedef luacpp::luaObject luaObject; 6 | #define any_cast luacpp::any_cast 7 | 8 | class test_class_A 9 | { 10 | public: 11 | test_class_A():memb_a(0) 12 | { 13 | printf("test_class_A void\n"); 14 | } 15 | test_class_A(int v):memb_a(v) 16 | { 17 | printf("test_class_A int\n"); 18 | } 19 | test_class_A(const test_class_A &other):memb_a(other.memb_a) 20 | { 21 | 22 | } 23 | ~test_class_A() 24 | { 25 | 26 | } 27 | int memb_a; 28 | void show() 29 | { 30 | printf("test_class_A::show\n"); 31 | } 32 | 33 | static void func_static() 34 | { 35 | printf("func_static\n"); 36 | } 37 | }; 38 | 39 | 40 | class base 41 | { 42 | public: 43 | virtual void show() 44 | { 45 | printf("this base show\n"); 46 | } 47 | 48 | void show2() 49 | { 50 | printf("this is not virtual function\n"); 51 | } 52 | }; 53 | 54 | class child:public base 55 | { 56 | public: 57 | void show() 58 | { 59 | printf("this child show\n"); 60 | } 61 | 62 | void child_show() 63 | { 64 | printf("child_show\n"); 65 | } 66 | }; 67 | 68 | void test_call_virtual_function(lua_State *L) 69 | { 70 | printf("\n----- lua call C++ virtual function -----\n"); 71 | luacpp::reg_cclass::_reg(L,"base") 72 | .method("show",&base::show) 73 | .method("show2",&base::show2); 74 | luacpp::reg_cclass::_reg(L,"child") 75 | .method("child_show",&base::show2); 76 | child c; 77 | base *b = &c; 78 | try{ 79 | luacpp::call(L,"test7",b,&c); 80 | }catch(std::string &err) 81 | { 82 | printf("%s\n",err.c_str()); 83 | } 84 | } 85 | 86 | 87 | void pass_by_value(test_class_A a) 88 | { 89 | a.memb_a = 102; 90 | } 91 | 92 | test_class_A* pass_by_reference(test_class_A &a) 93 | { 94 | a.memb_a = 102; 95 | return &a; 96 | } 97 | 98 | int main() 99 | { 100 | luacpp::luaWrapper L; 101 | L.dofile("test/test_class/test.lua"); 102 | 103 | luacpp::reg_cclass::_reg(L,"test_class_A") 104 | .constructor()//无参构造 105 | .constructor() //一个参数构造 106 | .property("memb_a",&test_class_A::memb_a) 107 | .method("show",&test_class_A::show) 108 | .method("static_func",&test_class_A::func_static); 109 | 110 | 111 | test_class_A a; 112 | a.memb_a = 100; 113 | try{ 114 | luacpp::call(L,"test1",a,a); 115 | }catch(std::string &err) 116 | { 117 | printf("%s\n",err.c_str()); 118 | } 119 | printf("after call test1,a.memb_a:%d\n",a.memb_a); 120 | 121 | 122 | luacpp::reg_cclass::_reg(L,"base") 123 | .method("show",&base::show) 124 | .method("show2",&base::show2); 125 | luacpp::reg_cclass::_reg(L,"child") 126 | .method("child_show",&child::child_show); 127 | child c1,c2; 128 | try{ 129 | luacpp::call(L,"test2",(base*)&c1,&c2); 130 | }catch(std::string &err) 131 | { 132 | printf("%s\n",err.c_str()); 133 | } 134 | 135 | luacpp::reg_cfun(L,"pass_by_value",pass_by_value); 136 | luacpp::reg_cfun(L,"pass_by_reference",pass_by_reference); 137 | try{ 138 | luacpp::call(L,"test3",a); 139 | }catch(std::string &err) 140 | { 141 | printf("%s\n",err.c_str()); 142 | } 143 | 144 | 145 | try{ 146 | luatable lt = luacpp::call(L,"test4",a); 147 | for(int i = 0; i < (int)lt.size();++i) 148 | { 149 | test_class_A *ptr_a = any_cast(lt[i]); 150 | printf("%p,%d\n",ptr_a,ptr_a->memb_a); 151 | } 152 | }catch(std::string &err) 153 | { 154 | printf("%s\n",err.c_str()); 155 | } 156 | 157 | 158 | 159 | try{ 160 | luacpp::call(L,"test5"); 161 | }catch(std::string &err) 162 | { 163 | printf("%s\n",err.c_str()); 164 | } 165 | 166 | 167 | return 0; 168 | } -------------------------------------------------------------------------------- /utility.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) <2012> 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | #ifndef _UTILITY 18 | #define _UTILITY 19 | #include "TypeList.h" 20 | #include "Trait.h" 21 | 22 | template 23 | struct GetReplaceType 24 | { 25 | typedef T type; 26 | //typedef typename refTraits::RefType type; 27 | }; 28 | 29 | template<> 30 | struct GetReplaceType 31 | { 32 | typedef std::string type; 33 | }; 34 | 35 | template<> 36 | struct GetReplaceType 37 | { 38 | typedef std::string type; 39 | }; 40 | 41 | template 42 | struct GetRawType 43 | { 44 | typedef T type; 45 | }; 46 | 47 | template 48 | struct GetRawType 49 | { 50 | typedef T &type; 51 | }; 52 | 53 | template<> 54 | struct GetRawType 55 | { 56 | typedef const char * type; 57 | }; 58 | 59 | template 60 | inline typename GetRawType::type GetRawValue(T &in) 61 | { 62 | return in; 63 | } 64 | 65 | template<> 66 | inline GetRawType::type GetRawValue(std::string &in) 67 | { 68 | return in.c_str(); 69 | } 70 | 71 | static inline const char *stack_value_tostr(lua_State *L,int index) { 72 | static char buff[1024]; 73 | int type = lua_type(L,index); 74 | switch(type) { 75 | case LUA_TNIL:{ 76 | snprintf(buff,1023,"nil"); 77 | }break; 78 | case LUA_TUSERDATA:{ 79 | snprintf(buff,1023,"userdata"); 80 | }break; 81 | case LUA_TLIGHTUSERDATA:{ 82 | snprintf(buff,1023,"lightuserdata"); 83 | }break; 84 | case LUA_TNUMBER:{ 85 | lua_Number v = lua_tonumber(L,index); 86 | if(v != (lua_Integer)v){ 87 | snprintf(buff,1023,"%f",v); 88 | } else { 89 | snprintf(buff,1023,"%lld",lua_tointeger(L,index)); 90 | } 91 | }break; 92 | case LUA_TBOOLEAN:{ 93 | lua_Integer b = lua_tointeger(L,index); 94 | snprintf(buff,1023,"%s",b == 1 ? "true":"false"); 95 | }break; 96 | case LUA_TTABLE:{ 97 | snprintf(buff,1023,"table"); 98 | }break; 99 | case LUA_TTHREAD:{ 100 | snprintf(buff,1023,"thread"); 101 | }break; 102 | case LUA_TFUNCTION:{ 103 | snprintf(buff,1023,"function"); 104 | }break; 105 | case LUA_TSTRING:{ 106 | snprintf(buff,1023,"%s",lua_tostring(L,index)); 107 | } 108 | break; 109 | default:{ 110 | snprintf(buff,1023,"unknow"); 111 | } 112 | } 113 | 114 | buff[1023] = 0; 115 | return buff; 116 | } 117 | 118 | static inline void show_stack(lua_State *L,const char *msg = NULL) { 119 | int top = lua_gettop(L); 120 | if(msg) { 121 | printf("top:%d,%s\n",top,msg); 122 | }else { 123 | printf("top:%d\n",top); 124 | } 125 | int i; 126 | for(i = top;i > 0; --i) { 127 | if(i == top) { 128 | printf("(stack index:%d) %s <- top\n",i,stack_value_tostr(L,i)); 129 | } else { 130 | printf("(stack index:%d) %s\n",i,stack_value_tostr(L,i)); 131 | } 132 | } 133 | } 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /PopValue.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) <2012> 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | #ifndef _POPVALUE_H 18 | #define _POPVALUE_H 19 | 20 | #include 21 | 22 | namespace luacpp{ 23 | 24 | extern std::set userdataSet; 25 | 26 | template 27 | inline T _pop(lua_State *L,Int2Type) 28 | { 29 | typedef typename pointerTraits::PointeeType rType; 30 | objUserData *obj = objUserData::checkobjuserdata(L,-1); 31 | lua_pop(L,1); 32 | return obj->ptr; 33 | } 34 | 35 | template 36 | inline T _pop_impl(lua_State *L,Int2Type) 37 | { 38 | T ret = (T)lua_tonumber(L,-1); 39 | lua_pop(L,1); 40 | return ret; 41 | } 42 | 43 | template 44 | inline T _pop_impl(lua_State *L,Int2Type) 45 | { 46 | return *_pop::RefType*>(L,Int2Type()); 47 | } 48 | 49 | template 50 | inline T _pop(lua_State *L,Int2Type) 51 | { 52 | return _pop_impl(L,Int2Type::value >= 0>()); 53 | } 54 | 55 | template 56 | inline T popvalue(lua_State *L) 57 | { 58 | return _pop(L,Int2Type::isPointer>()); 59 | } 60 | 61 | 62 | template<> 63 | inline luaObject popvalue(lua_State *L) 64 | { 65 | int r = luaL_ref(L,LUA_REGISTRYINDEX); 66 | luaObject obj(L,r); 67 | return obj; 68 | } 69 | 70 | template<> 71 | inline std::string popvalue(lua_State *L) 72 | { 73 | const char *str = lua_tostring(L,-1); 74 | std::string ret(str); 75 | lua_pop(L,1); 76 | return ret; 77 | } 78 | 79 | template 80 | inline T pop_void_ptr(lua_State *L) 81 | { 82 | T ret; 83 | ret = lua_touserdata(L,-1); 84 | 85 | if(userdataSet.find((void*)ret) != userdataSet.end()) 86 | ret = ((objUserData*)ret)->ptr; 87 | lua_pop(L,1); 88 | return ret; 89 | } 90 | 91 | template<> 92 | inline const void *popvalue(lua_State *L) 93 | { 94 | return pop_void_ptr(L); 95 | } 96 | 97 | template<> 98 | inline void *popvalue(lua_State *L) 99 | { 100 | return pop_void_ptr(L); 101 | } 102 | 103 | template<> 104 | inline bool popvalue(lua_State *L) 105 | { 106 | bool ret = lua_toboolean(L,-1) == 1; 107 | lua_pop(L,1); 108 | return ret; 109 | } 110 | 111 | template<> 112 | inline double popvalue(lua_State *L) 113 | { 114 | double ret = lua_tonumber(L,-1); 115 | lua_pop(L,1); 116 | return ret; 117 | } 118 | 119 | template<> 120 | inline float popvalue(lua_State *L) 121 | { 122 | double ret = lua_tonumber(L,-1); 123 | lua_pop(L,1); 124 | return (float)ret; 125 | } 126 | 127 | template<> 128 | inline luatable popvalue(lua_State *L) 129 | { 130 | luatable ret; 131 | int len = luaL_len(L, -1); 132 | for( int i = 1; i <= len; ++i) 133 | { 134 | lua_rawgeti(L,-1,i); 135 | int type = lua_type(L,-1); 136 | if(type == LUA_TNIL) 137 | { 138 | ret.push_back(any()); 139 | lua_pop(L,1); 140 | } 141 | else if(type == LUA_TUSERDATA || type == LUA_TLIGHTUSERDATA) 142 | { 143 | void *r = lua_touserdata(L,-1); 144 | if(userdataSet.find(r) != userdataSet.end()) 145 | ret.push_back((const void*)((objUserData*)r)->ptr); 146 | else 147 | ret.push_back(r); 148 | lua_pop(L,1); 149 | } 150 | else if(type == LUA_TNUMBER){ 151 | ret.push_back(popvalue(L)); 152 | } 153 | else if(type == LUA_TSTRING) 154 | ret.push_back(popvalue(L)); 155 | else if(type == LUA_TBOOLEAN) 156 | ret.push_back(popvalue(L)); 157 | else if(type == LUA_TTABLE) 158 | { 159 | int _len = luaL_len(L, -1); 160 | if(_len == 0) 161 | { 162 | lua_pushnil(L);//push a key 163 | if(lua_next(L,-2)){ 164 | lua_pop(L,2);//pop value and value 165 | ret.push_back(popvalue(L)); 166 | } 167 | else{ 168 | ret.push_back(popvalue(L)); 169 | } 170 | }else{ 171 | ret.push_back(popvalue(L)); 172 | } 173 | } 174 | else 175 | throw std::string("error"); 176 | } 177 | lua_pop(L,1); 178 | return ret; 179 | } 180 | 181 | //Get lua global object 182 | template 183 | T Get(lua_State *L,const char *name) 184 | { 185 | lua_getglobal(L,name); 186 | return popvalue(L); 187 | } 188 | 189 | } 190 | 191 | #endif 192 | -------------------------------------------------------------------------------- /any.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) <2012> 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | #ifndef _ANY_H 18 | #define _ANY_H 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "TypeList.h" 25 | #include "Trait.h" 26 | #include "luacommon.h" 27 | 28 | namespace luacpp{ 29 | 30 | class luaObject; 31 | class any; 32 | typedef std::vector luatable; 33 | 34 | typedef LOKI_TYPELIST_15(bool,char,unsigned char,short,unsigned short,int,unsigned int,long,unsigned long,float,double,std::string,luaObject,luatable,int64_t) SupportType; 35 | 36 | typedef LOKI_TYPELIST_9(char,unsigned char,short,unsigned short,int,unsigned int,long,unsigned long,int64_t) intType; 37 | 38 | //注册到lua中的用户数据类型信息 39 | template 40 | class luaRegisterClass 41 | { 42 | public: 43 | static bool isRegister() 44 | { 45 | return m_isRegister; 46 | } 47 | 48 | static void SetRegister() 49 | { 50 | m_isRegister = true; 51 | } 52 | 53 | static void ClearRegister() 54 | { 55 | m_isRegister = false; 56 | } 57 | 58 | static void SetClassName(const char *name) 59 | { 60 | classname = name; 61 | } 62 | 63 | static const char *GetClassName() 64 | { 65 | return classname.c_str(); 66 | } 67 | 68 | private: 69 | static bool m_isRegister; 70 | static std::string classname; 71 | }; 72 | 73 | template 74 | bool luaRegisterClass::m_isRegister = false; 75 | 76 | template 77 | std::string luaRegisterClass::classname; 78 | 79 | class any; 80 | class any_pusher 81 | { 82 | public: 83 | virtual ~any_pusher(){} 84 | virtual void push(lua_State *L,any*) = 0; 85 | }; 86 | template 87 | any_pusher *create_any_pusher(); 88 | 89 | //一个精简版的boost::any 90 | class any 91 | { 92 | public: // structors 93 | 94 | any(): content(0),counter(0){} 95 | 96 | template 97 | any(const ValueType & value) 98 | :counter(new int(1)),luaRegisterClassName("") 99 | { 100 | content = create_holder(value,Int2Type::value >= 0>()); 101 | luaRegisterClassName = luaRegisterClass::PointeeType>::GetClassName(); 102 | _any_pusher = create_any_pusher(); 103 | } 104 | 105 | any(const any & other) 106 | { 107 | if(other.counter && other.content) 108 | { 109 | content = other.content; 110 | counter = other.counter; 111 | ++(*counter); 112 | luaRegisterClassName = other.luaRegisterClassName; 113 | _any_pusher = other._any_pusher; 114 | } 115 | else 116 | { 117 | content = NULL; 118 | counter = NULL; 119 | _any_pusher = NULL; 120 | } 121 | } 122 | 123 | any & operator=(const any & rhs) 124 | { 125 | if(&rhs == this) 126 | return *this; 127 | else 128 | { 129 | _destroy(); 130 | if(rhs.counter && rhs.content) 131 | { 132 | content = rhs.content; 133 | counter = rhs.counter; 134 | _any_pusher = rhs._any_pusher; 135 | ++(*counter); 136 | } 137 | else 138 | { 139 | content = 0; 140 | counter = 0; 141 | } 142 | return *this; 143 | } 144 | } 145 | 146 | ~any() 147 | { 148 | _destroy(); 149 | } 150 | 151 | private: 152 | void _destroy() 153 | { 154 | if(counter && content && --*counter <= 0) 155 | { 156 | delete counter; 157 | delete content; 158 | delete _any_pusher; 159 | } 160 | } 161 | 162 | public: // queries 163 | bool empty() const 164 | { 165 | return !content; 166 | } 167 | public: 168 | 169 | class placeholder 170 | { 171 | public: // structors 172 | virtual ~placeholder(){} 173 | }; 174 | 175 | template 176 | class holder : public placeholder 177 | { 178 | public: // structors 179 | 180 | holder(const ValueType & value) 181 | : held(value) 182 | {} 183 | public: // representation 184 | ValueType held; 185 | }; 186 | 187 | template 188 | placeholder * create_holder(ValueType v,Int2Type) 189 | { 190 | return new holder(v); 191 | } 192 | 193 | template 194 | placeholder * create_holder(ValueType v,Int2Type) 195 | { 196 | return new holder(v); 197 | } 198 | 199 | placeholder * content; 200 | int * counter; 201 | public: // representation (public so any_cast can be non-friend) 202 | any_pusher * _any_pusher; 203 | std::string luaRegisterClassName;//保存的类型在lua中注册的名字 204 | 205 | }; 206 | 207 | template 208 | inline ValueType _any_cast(const any &operand,Int2Type) 209 | { 210 | ValueType ret = (ValueType)static_cast *>(operand.content)->held; 211 | return ret; 212 | } 213 | 214 | template 215 | inline ValueType _any_cast(const any &operand,Int2Type) 216 | { 217 | return static_cast *>(operand.content)->held; 218 | } 219 | 220 | template 221 | inline ValueType any_cast(const any & operand) 222 | { 223 | return _any_cast(operand,Int2Type::value >= 0>()); 224 | } 225 | 226 | template<> 227 | inline std::string any_cast(const any & operand) 228 | { 229 | any::holder *tmp = static_cast *>(operand.content); 230 | return tmp->held; 231 | } 232 | 233 | template<> 234 | inline const char *any_cast(const any &operand){ 235 | any::holder *tmp = static_cast *>(operand.content); 236 | return tmp->held.c_str(); 237 | } 238 | 239 | 240 | template<> 241 | inline char *any_cast(const any &operand){ 242 | any::holder *tmp = static_cast *>(operand.content); 243 | return const_cast(tmp->held.c_str()); 244 | } 245 | 246 | 247 | template<> 248 | inline double any_cast(const any & operand) 249 | { 250 | any::holder *tmp = static_cast *>(operand.content); 251 | return tmp->held; 252 | } 253 | 254 | template<> 255 | inline float any_cast(const any & operand) 256 | { 257 | return (float)any_cast(operand); 258 | } 259 | 260 | 261 | 262 | //unsupported 263 | template<> 264 | const char * any_cast(const any & operand); 265 | 266 | template<> 267 | char * any_cast(const any & operand); 268 | 269 | } 270 | #endif 271 | -------------------------------------------------------------------------------- /ObjPush.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) <2012> 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | #ifndef _OBJPUSH_H 18 | #define _OBJPUSH_H 19 | 20 | namespace luacpp{ 21 | //调用lua函数时参数压栈的抽象 22 | 23 | template 24 | class objPush 25 | { 26 | public: 27 | objPush(lua_State *L,const T &arg) 28 | { 29 | _objpush(L,arg,Int2Type::value >= 0>()); 30 | } 31 | private: 32 | 33 | void _objpush(lua_State *L,const T &arg,Int2Type) 34 | { 35 | if(!luaRegisterClass::PointeeType>::isRegister()) 36 | lua_pushlightuserdata(L,(T*)&arg); 37 | else 38 | objUserData::PointeeType>::pushObj(L,&arg); 39 | } 40 | 41 | void _objpush(lua_State *L,const T &arg,Int2Type) 42 | { 43 | if((lua_Number)arg == (lua_Integer)arg) 44 | lua_pushinteger(L,(lua_Integer)arg); 45 | else 46 | lua_pushnumber(L,(lua_Number)arg); 47 | } 48 | }; 49 | 50 | 51 | //对指针类型的特化 52 | template 53 | class objPush 54 | { 55 | public: 56 | objPush(lua_State *L,T* arg) 57 | { 58 | if(!arg) 59 | lua_pushnil(L); 60 | else 61 | { 62 | if(!luaRegisterClass::PointeeType>::isRegister()) 63 | lua_pushlightuserdata(L,(T*)arg); 64 | else 65 | objUserData::PointeeType>::pushObj(L,arg); 66 | } 67 | } 68 | }; 69 | 70 | template 71 | class objPush 72 | { 73 | public: 74 | objPush(lua_State *L,const T* arg) 75 | { 76 | if(!arg) 77 | lua_pushnil(L); 78 | else 79 | { 80 | if(!luaRegisterClass::PointeeType>::isRegister()) 81 | lua_pushlightuserdata(L,(T*)arg); 82 | else 83 | objUserData::PointeeType>::pushObj(L,arg); 84 | } 85 | } 86 | }; 87 | 88 | //字符串的特化 89 | template<> 90 | class objPush 91 | { 92 | public: 93 | objPush(lua_State *L,const char *value) 94 | { 95 | lua_pushstring(L,value); 96 | } 97 | }; 98 | 99 | template<> 100 | class objPush 101 | { 102 | public: 103 | objPush(lua_State *L,char *value) 104 | { 105 | lua_pushstring(L,value); 106 | } 107 | }; 108 | 109 | //对std::string的特化 110 | template<> 111 | class objPush 112 | { 113 | public: 114 | objPush(lua_State *L,const std::string &arg) 115 | { 116 | lua_pushlstring(L,arg.c_str(),arg.size()); 117 | } 118 | }; 119 | 120 | //针对luaObject的特化 121 | template<> 122 | class objPush 123 | { 124 | public: 125 | objPush(lua_State *L,const luaObject &arg) 126 | { 127 | lua_rawgeti(L,LUA_REGISTRYINDEX,arg.getIndex()); 128 | } 129 | }; 130 | 131 | template<> 132 | class objPush 133 | { 134 | public: 135 | objPush(lua_State *L,bool arg) 136 | { 137 | lua_pushboolean(L,arg); 138 | } 139 | }; 140 | 141 | //针对luatable的特化 142 | template<> 143 | class objPush 144 | { 145 | public: 146 | objPush(lua_State *L,const luatable &arg) 147 | { 148 | if(arg.empty()) 149 | lua_pushnil(L); 150 | else{ 151 | lua_newtable(L); 152 | for(int i = 0; i < (int)arg.size(); ++i) 153 | { 154 | if(arg[i].empty()) 155 | lua_pushnil(L); 156 | else 157 | arg[i]._any_pusher->push(L,const_cast(&arg[i])); 158 | lua_rawseti(L,-2,i+1); 159 | } 160 | } 161 | } 162 | }; 163 | 164 | template 165 | void push_obj(lua_State *L,const T &obj) 166 | { 167 | objPush _obj(L,obj); 168 | } 169 | 170 | template 171 | class concrete_any_pusher : public any_pusher 172 | { 173 | public: 174 | void push(lua_State *L,any *_any) 175 | { 176 | if((lua_Number)any_cast(*_any) == (lua_Integer)any_cast(*_any)) 177 | lua_pushinteger(L,(lua_Integer)any_cast(*_any)); 178 | else 179 | lua_pushnumber(L,(lua_Number)any_cast(*_any)); 180 | } 181 | }; 182 | 183 | template 184 | class concrete_any_pusher : public any_pusher 185 | { 186 | public: 187 | void push(lua_State *L,any *_any) 188 | { 189 | //是否注册的用户类型 190 | if(_any->luaRegisterClassName == "") 191 | objPush obj(L,any_cast(*_any)); 192 | else 193 | { 194 | pushObj(L,any_cast(*_any),_any->luaRegisterClassName.c_str()); 195 | } 196 | } 197 | }; 198 | 199 | template<> 200 | class concrete_any_pusher : public any_pusher 201 | { 202 | public: 203 | void push(lua_State *L,any *_any) 204 | { 205 | lua_pushboolean(L,any_cast(*_any)); 206 | } 207 | }; 208 | 209 | template<> 210 | class concrete_any_pusher : public any_pusher 211 | { 212 | public: 213 | void push(lua_State *L,any *_any) 214 | { 215 | lua_pushstring(L,any_cast(*_any).c_str()); 216 | } 217 | }; 218 | 219 | template<> 220 | class concrete_any_pusher : public any_pusher 221 | { 222 | public: 223 | void push(lua_State *L,any *_any) 224 | { 225 | lua_pushstring(L,any_cast(*_any)); 226 | } 227 | }; 228 | 229 | template<> 230 | class concrete_any_pusher : public any_pusher 231 | { 232 | public: 233 | void push(lua_State *L,any *_any) 234 | { 235 | lua_pushstring(L,any_cast(*_any)); 236 | } 237 | }; 238 | 239 | template<> 240 | class concrete_any_pusher : public any_pusher 241 | { 242 | public: 243 | void push(lua_State *L,any *_any) 244 | { 245 | objPush obj(L,any_cast(*_any)); 246 | } 247 | }; 248 | 249 | template<> 250 | class concrete_any_pusher : public any_pusher 251 | { 252 | public: 253 | void push(lua_State *L,any *_any) 254 | { 255 | objPush obj(L,any_cast(*_any)); 256 | } 257 | }; 258 | 259 | 260 | template 261 | any_pusher *create_any_pusher() 262 | { 263 | return new concrete_any_pusher; 264 | } 265 | 266 | template 267 | inline void luaSetGlobal(lua_State *L,const char *name,const T &arg) 268 | { 269 | lua_getglobal(L,"_G"); 270 | if(!lua_istable(L, -1)) 271 | { 272 | lua_pop(L,1); 273 | lua_newtable(L); 274 | lua_pushvalue(L,-1); 275 | lua_setglobal(L,"_G"); 276 | } 277 | lua_pushstring(L,name); 278 | objPush(L,arg); 279 | lua_settable(L, -3); 280 | lua_pop(L,1); 281 | } 282 | 283 | //set lua global object 284 | inline void Set(lua_State *L,const char *name,const char *arg) 285 | { 286 | lua_getglobal(L,"_G"); 287 | if(!lua_istable(L, -1)) 288 | { 289 | lua_pop(L,1); 290 | lua_newtable(L); 291 | lua_pushvalue(L,-1); 292 | lua_setglobal(L,"_G"); 293 | } 294 | lua_pushstring(L,name); 295 | lua_pushstring(L,arg); 296 | lua_settable(L, -3); 297 | lua_pop(L,1); 298 | } 299 | 300 | inline void luaSetGlobal(lua_State *L,const char *name,char *arg) 301 | { 302 | luaSetGlobal(L,name,(const char*)arg); 303 | } 304 | 305 | } 306 | 307 | #endif 308 | -------------------------------------------------------------------------------- /luaFunction.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) <2012> 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | /* 18 | * brief : 注册全局函数 19 | * Author : huangwei 20 | */ 21 | #ifndef _LUAFUNCTION_H 22 | #define _LUAFUNCTION_H 23 | #include "utility.h" 24 | #include "any.h" 25 | #include 26 | #include 27 | 28 | namespace luacpp{ 29 | template 30 | void push_obj(lua_State *L,const T &obj); 31 | 32 | //取出栈顶的值,通知将其出栈 33 | template 34 | T popvalue(lua_State *L); 35 | 36 | template 37 | class doLuaCall 38 | { 39 | public: 40 | static Ret doCall(lua_State *L,int nArgs,int errFunc,bool callByObject = false) 41 | { 42 | typedef LOKI_TYPELIST_1(void) voidType; 43 | return call(L,nArgs,errFunc,Int2Type::value == 0>(),callByObject); 44 | } 45 | private: 46 | //返回void 47 | static Ret call(lua_State *L,int nArgs,int errFunc,Int2Type,bool callByObject) 48 | { 49 | if(lua_pcall(L, nArgs, 0, errFunc ) != 0) 50 | { 51 | const char *error = lua_tostring(L,-1); 52 | std::string err(error); 53 | lua_pop(L,1); 54 | throw err; 55 | } 56 | if(callByObject) 57 | lua_pop(L,1); 58 | } 59 | 60 | //有返回值 61 | static Ret call(lua_State *L,int nArgs,int errFunc,Int2Type,bool callByObject) 62 | { 63 | Ret ret = _call(L,nArgs,errFunc,callByObject); 64 | if(callByObject) 65 | lua_pop(L,1); 66 | return ret; 67 | } 68 | 69 | //只有一个返回值 70 | static Ret _call(lua_State *L,int nArgs,int errFunc,bool callByObject) 71 | { 72 | if(lua_pcall(L, nArgs, 1, errFunc ) != 0) 73 | { 74 | const char *error = lua_tostring(L,-1); 75 | printf("%s\n",error); 76 | std::string err(error); 77 | lua_pop(L,1); 78 | throw err; 79 | return Ret(); 80 | } 81 | return popvalue(L); 82 | } 83 | }; 84 | 85 | #ifndef PUSH_FUNCTOR 86 | #define PUSH_FUNCTOR do{\ 87 | lua_pushlightuserdata(L, (void*)_func);\ 88 | lua_pushcclosure(L,lua_cfunction,1);\ 89 | lua_setglobal(L, name);\ 90 | }while(0) 91 | #endif 92 | 93 | template 94 | class funbinder{}; 95 | 96 | //用于注册全局函数 97 | //无参 98 | template 99 | class funbinder 100 | { 101 | public: 102 | 103 | static void pushfuctor(lua_State *L,const char *name,Ret(*_func)()) 104 | { 105 | PUSH_FUNCTOR; 106 | } 107 | 108 | static int lua_cfunction(lua_State *L) 109 | { 110 | return doCall(L,(__func)lua_touserdata(L,lua_upvalueindex(1)),Int2Type::is_Void>()); 111 | } 112 | 113 | private: 114 | 115 | typedef Ret(*__func)(); 116 | 117 | template 118 | static int doCall(lua_State *L,__func func,Int2Type) 119 | { 120 | push_obj(L,func()); 121 | return 1; 122 | } 123 | 124 | template 125 | static int doCall(lua_State *L,__func func,Int2Type) 126 | { 127 | func(); 128 | return 0; 129 | } 130 | 131 | }; 132 | 133 | //单参 134 | template 135 | class funbinder 136 | { 137 | private: 138 | typedef typename refTraits::RefType arg1_ref_type; 139 | public: 140 | 141 | static void pushfuctor(lua_State *L,const char *name,Ret(*_func)(Arg1)) 142 | { 143 | PUSH_FUNCTOR; 144 | } 145 | 146 | 147 | static int lua_cfunction(lua_State *L) 148 | { 149 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 150 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 151 | return doCall(L,arg1,(__func)lua_touserdata(L,lua_upvalueindex(1)),Int2Type::is_Void>()); 152 | } 153 | 154 | private: 155 | typedef Ret(*__func)(Arg1); 156 | 157 | 158 | template 159 | static int doCall(lua_State *L,const Arg1 &arg1,__func func,Int2Type) 160 | { 161 | push_obj(L,func(arg1)); 162 | return 1; 163 | } 164 | template 165 | static int doCall(lua_State *L,const Arg1 &arg1,__func func,Int2Type) 166 | { 167 | func(arg1); 168 | return 0; 169 | } 170 | 171 | }; 172 | 173 | //2参 174 | template 175 | class funbinder 176 | { 177 | public: 178 | 179 | static void pushfuctor(lua_State *L,const char *name,Ret(*_func)(Arg1,Arg2)) 180 | { 181 | PUSH_FUNCTOR; 182 | } 183 | 184 | static int lua_cfunction(lua_State *L) 185 | { 186 | typename GetReplaceType::type tmp_arg2 = popvalue::type>(L); 187 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 188 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 189 | Arg2 arg2 = GetRawValue::type>(tmp_arg2); 190 | return doCall(L,arg1,arg2,(__func)lua_touserdata(L,lua_upvalueindex(1)),Int2Type::is_Void>()); 191 | } 192 | 193 | private: 194 | typedef Ret(*__func)(Arg1,Arg2); 195 | 196 | template 197 | static int doCall(lua_State *L,const Arg1 &arg1,const Arg2 &arg2,__func func,Int2Type) 198 | { 199 | push_obj(L,func(arg1,arg2)); 200 | return 1; 201 | } 202 | 203 | template 204 | static int doCall(lua_State *L,const Arg1 &arg1,const Arg2 &arg2,__func func,Int2Type) 205 | { 206 | func(arg1,arg2); 207 | return 0; 208 | } 209 | }; 210 | 211 | //3参 212 | template 213 | class funbinder 214 | { 215 | public: 216 | 217 | static void pushfuctor(lua_State *L,const char *name,Ret(*_func)(Arg1,Arg2,Arg3)) 218 | { 219 | PUSH_FUNCTOR; 220 | } 221 | 222 | static int lua_cfunction(lua_State *L) 223 | { 224 | typename GetReplaceType::type tmp_arg3 = popvalue::type>(L); 225 | typename GetReplaceType::type tmp_arg2 = popvalue::type>(L); 226 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 227 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 228 | Arg2 arg2 = GetRawValue::type>(tmp_arg2); 229 | Arg3 arg3 = GetRawValue::type>(tmp_arg3); 230 | return doCall(L,arg1,arg2,arg3,(__func)lua_touserdata(L,lua_upvalueindex(1)),Int2Type::is_Void>()); 231 | } 232 | 233 | private: 234 | typedef Ret(*__func)(Arg1,Arg2,Arg3); 235 | 236 | template 237 | static int doCall(lua_State *L,const Arg1 &arg1,const Arg2 &arg2,const Arg3 &arg3,__func func,Int2Type) 238 | { 239 | push_obj(L,func(arg1,arg2,arg3)); 240 | return 1; 241 | } 242 | 243 | template 244 | static int doCall(lua_State *L,const Arg1 &arg1,const Arg2 &arg2,const Arg3 &arg3,__func func,Int2Type) 245 | { 246 | func(arg1,arg2,arg3); 247 | return 0; 248 | } 249 | 250 | }; 251 | 252 | //4参 253 | template 254 | class funbinder 255 | { 256 | public: 257 | 258 | static void pushfuctor(lua_State *L,const char *name,Ret(*_func)(Arg1,Arg2,Arg3,Arg4)) 259 | { 260 | PUSH_FUNCTOR; 261 | } 262 | 263 | static int lua_cfunction(lua_State *L) 264 | { 265 | typename GetReplaceType::type tmp_arg4 = popvalue::type>(L); 266 | typename GetReplaceType::type tmp_arg3 = popvalue::type>(L); 267 | typename GetReplaceType::type tmp_arg2 = popvalue::type>(L); 268 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 269 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 270 | Arg2 arg2 = GetRawValue::type>(tmp_arg2); 271 | Arg3 arg3 = GetRawValue::type>(tmp_arg3); 272 | Arg4 arg4 = GetRawValue::type>(tmp_arg4); 273 | return doCall(L,arg1,arg2,arg3,arg4,(__func)lua_touserdata(L,lua_upvalueindex(1)),Int2Type::is_Void>()); 274 | } 275 | 276 | private: 277 | typedef Ret(*__func)(Arg1,Arg2,Arg3,Arg4); 278 | template 279 | static int doCall(lua_State *L,const Arg1 &arg1,const Arg2 &arg2,const Arg3 &arg3,const Arg4 &arg4,__func func,Int2Type) 280 | { 281 | push_obj(L,func(arg1,arg2,arg3,arg4)); 282 | return 1; 283 | } 284 | 285 | template 286 | static int doCall(lua_State *L,const Arg1 &arg1,const Arg2 &arg2,const Arg3 &arg3,const Arg4 &arg4,__func func,Int2Type) 287 | { 288 | func(arg1,arg2,arg3,arg4); 289 | return 0; 290 | } 291 | }; 292 | 293 | 294 | template 295 | void reg_cfun(lua_State *L,const char *name, FUNTOR _func) 296 | { 297 | funbinder::pushfuctor(L,name,_func); 298 | } 299 | 300 | inline void check_call(lua_State *L,const char *funname) 301 | { 302 | lua_getglobal(L,funname); 303 | if(LUA_TFUNCTION != lua_type(L,-1)) 304 | { 305 | lua_pop(L,1); 306 | char str[512]; 307 | snprintf(str,512,"lua中不存在函数%s",funname); 308 | std::string err(str); 309 | throw err; 310 | } 311 | } 312 | 313 | template 314 | Ret call(lua_State *L,const char *funname) 315 | { 316 | check_call(L,funname); 317 | return doLuaCall::doCall(L,0,0); 318 | } 319 | 320 | template 321 | Ret call(lua_State *L,const char *funname,const Arg1 &arg1) 322 | { 323 | check_call(L,funname); 324 | push_obj(L,arg1); 325 | return doLuaCall::doCall(L,1,0); 326 | } 327 | 328 | template 329 | Ret call(lua_State *L,const char *funname,const Arg1 &arg1,const Arg2 &arg2) 330 | { 331 | check_call(L,funname); 332 | push_obj(L,arg1); 333 | push_obj(L,arg2); 334 | return doLuaCall::doCall(L,2,0); 335 | } 336 | 337 | template 338 | Ret call(lua_State *L,const char *funname,const Arg1 &arg1,const Arg2 &arg2,const Arg3 &arg3) 339 | { 340 | check_call(L,funname); 341 | push_obj(L,arg1); 342 | push_obj(L,arg2); 343 | push_obj(L,arg3); 344 | return doLuaCall::doCall(L,3,0); 345 | } 346 | 347 | template 348 | Ret call(lua_State *L,const char *funname,const Arg1 &arg1,const Arg2 &arg2,const Arg3 &arg3,const Arg4 &arg4) 349 | { 350 | check_call(L,funname); 351 | push_obj(L,arg1); 352 | push_obj(L,arg2); 353 | push_obj(L,arg3); 354 | push_obj(L,arg4); 355 | return doLuaCall::doCall(L,4,0); 356 | } 357 | } 358 | #endif 359 | -------------------------------------------------------------------------------- /luaClass.h: -------------------------------------------------------------------------------- 1 | #ifndef _LUACLASS_H 2 | #define _LUACLASS_H 3 | #include 4 | #include 5 | #include 6 | #include "luacommon.h" 7 | #include "luaObject.h" 8 | #include "any.h" 9 | #include "luaFunction.h" 10 | 11 | namespace luacpp{ 12 | template 13 | void push_obj(lua_State *L,const T &obj); 14 | void set_userdata(lua_State *L,void *ptr,int index); 15 | 16 | extern std::map ptrToUserData; 17 | extern std::set userdataSet; 18 | 19 | enum{ 20 | MEMBER_FUNCTION = 1, 21 | STATIC_FUNCTION, 22 | MEMBER_FIELD, 23 | CONSTRUCTOR, 24 | }; 25 | 26 | template 27 | struct memberfield 28 | { 29 | 30 | typedef void (*property_getter)(T *,lua_State*,void *(T::*));//for property get 31 | typedef void (*property_setter)(T *,lua_State*,void *(T::*));//for property set 32 | char tt; 33 | union{ 34 | struct { 35 | property_getter getter; 36 | property_setter setter; 37 | void *(T::*property); 38 | }; 39 | struct { 40 | void (T::*mfunction)(void); //member func 41 | lua_CFunction mlua_func; 42 | }; 43 | struct { 44 | void (*sfunction)(void); //static func 45 | lua_CFunction slua_func; 46 | }; 47 | void (*constructor)(lua_State *L); 48 | }; 49 | 50 | memberfield() { 51 | memset(this,0,sizeof(*this)); 52 | } 53 | 54 | template 55 | memberfield(const memberfield &p){ 56 | memcpy(this,&p,sizeof(p)); 57 | } 58 | 59 | }; 60 | 61 | template 62 | class objUserData; 63 | 64 | template 65 | static void GetPropertyData(T *self,lua_State *L,Int2Type,void*(T::*field)) 66 | { 67 | //for obj type 68 | push_obj(L,(property_type*)&(self->*field)); 69 | } 70 | 71 | template 72 | static void GetPropertyData(T *self,lua_State *L,Int2Type,void*(T::*property)) 73 | { 74 | push_obj(L,*(property_type*)&(self->*property)); 75 | } 76 | 77 | template 78 | static void _GetProperty(T *self,lua_State *L,void*(T::*property),Int2Type) 79 | { 80 | //for other type 81 | GetPropertyData(self,L,Int2Type::isPointer\ 82 | && IndexOf::PointeeType>::value == -1>(),property); 83 | } 84 | 85 | template 86 | static void _GetProperty(T *self,lua_State *L,void*(T::*property),Int2Type) 87 | { 88 | //for luatable 89 | luatable *lt_ptr = (luatable*)(&(self->*property)); 90 | push_obj(L,*lt_ptr); 91 | } 92 | 93 | 94 | template 95 | static void GetProperty(T *self,lua_State *L,void*(T::*property) ) 96 | { 97 | typedef LOKI_TYPELIST_1(luatable) lt; 98 | _GetProperty(self,L,property,Int2Type::value==0>()); 99 | } 100 | 101 | template 102 | static void SetPropertyData(T *self,lua_State *L,Int2Type,void*(T::*property)) 103 | { 104 | //empty function for obj type 105 | } 106 | 107 | template 108 | static void SetPropertyData(T *self,lua_State *L,Int2Type,void*(T::*property)) 109 | { 110 | property_type new_value; 111 | new_value = *(property_type*)(&(self->*property)) = popvalue(L); 112 | push_obj(L,new_value); 113 | } 114 | 115 | template 116 | struct Seter 117 | { 118 | Seter(CLASS_TYPE *self,lua_State *L,void*(CLASS_TYPE::*property)) 119 | { 120 | SetPropertyData(self,L,Int2Type::PointeeType>::value == -1>(),property); 122 | } 123 | }; 124 | 125 | template 126 | struct Seter 127 | { 128 | Seter(CLASS_TYPE *self,lua_State *L,void*(CLASS_TYPE::*property)){} 129 | }; 130 | 131 | template 132 | struct Seter 133 | { 134 | Seter(CLASS_TYPE *self,lua_State *L,void*(CLASS_TYPE::*property)){} 135 | }; 136 | 137 | template 138 | struct Seter 139 | { 140 | Seter(CLASS_TYPE *self,lua_State *L,void*(CLASS_TYPE::*property)){} 141 | }; 142 | 143 | 144 | void get_luatable(luatable &,lua_State *L); 145 | 146 | template 147 | struct Seter 148 | { 149 | Seter(CLASS_TYPE *self,lua_State *L,void*(CLASS_TYPE::*property)) 150 | { 151 | luatable *lt_ptr = (luatable*)(&(self->*property)); 152 | get_luatable(*lt_ptr,L); 153 | } 154 | }; 155 | 156 | template 157 | static void SetProperty(T *self,lua_State *L,void*(T::*property) ) 158 | { 159 | Seter seter(self,L,property); 160 | } 161 | 162 | template 163 | class luaClassWrapper 164 | { 165 | friend class objUserData; 166 | 167 | public: 168 | 169 | static void luaopen_objlib(lua_State *L) { 170 | luaL_Reg meta[] = { 171 | {"__gc",&objUserData::on_gc}, 172 | {"__index",&objUserData::Index}, 173 | {"__newindex",&objUserData::NewIndex}, 174 | //{"__eq",&objUserData::Eq}, 175 | {NULL, NULL} 176 | }; 177 | luaL_newmetatable(L, luaRegisterClass::GetClassName()); 178 | luaL_setfuncs(L, meta, 0); 179 | lua_pop(L,1); 180 | } 181 | 182 | static std::map > &GetAllFields() 183 | { 184 | return fields; 185 | } 186 | 187 | static void InsertFields(const char *name,memberfield &mf) 188 | { 189 | fields.insert(std::make_pair(std::string(name),mf)); 190 | } 191 | 192 | static int InsertConstructors(int arg_count,memberfield &mf) 193 | { 194 | if(constructors[arg_count].constructor == NULL) 195 | { 196 | constructors[arg_count] = mf; 197 | ++constructor_size; 198 | return constructor_size; 199 | } 200 | return -1; 201 | } 202 | 203 | private: 204 | static std::map > fields; 205 | static int constructor_size; 206 | static memberfield constructors[16]; 207 | }; 208 | 209 | 210 | template 211 | std::map > luaClassWrapper::fields; 212 | 213 | template 214 | int luaClassWrapper::constructor_size = 0; 215 | 216 | template 217 | memberfield luaClassWrapper::constructors[16]; 218 | 219 | extern int pushObj(lua_State *L,const void *ptr,const char *classname); 220 | 221 | template 222 | class objUserData 223 | { 224 | public: 225 | 226 | static objUserData *checkobjuserdata (lua_State *L,int index) { 227 | void *ud = lua_touserdata(L,index); 228 | luaL_argcheck(L, ud != NULL, 1, "userdata expected"); 229 | return (objUserData *)ud; 230 | } 231 | 232 | static int pushObj(lua_State *L,const T *ptr) 233 | { 234 | return luacpp::pushObj(L,ptr,luaRegisterClass::GetClassName()); 235 | } 236 | 237 | static int NewIndex(lua_State *L) 238 | { 239 | objUserData *self = checkobjuserdata(L,1); 240 | const char *name = luaL_checkstring(L, 2); 241 | typename std::map >::iterator it = luaClassWrapper::fields.find(std::string(name)); 242 | if(it != luaClassWrapper::fields.end()) 243 | { 244 | memberfield &mf = it->second; 245 | if(mf.tt == MEMBER_FIELD) mf.setter(self->ptr,L,mf.property); 246 | } 247 | return 0; 248 | } 249 | 250 | static int Index(lua_State *L) 251 | { 252 | objUserData *obj = checkobjuserdata(L,1); 253 | const char *name = luaL_checkstring(L, 2); 254 | typename std::map >::iterator it = luaClassWrapper::fields.find(std::string(name)); 255 | if(it != luaClassWrapper::fields.end()) 256 | { 257 | memberfield &mf = it->second; 258 | if(mf.tt == MEMBER_FUNCTION) 259 | { 260 | lua_pushlightuserdata(L,&mf.mfunction); 261 | lua_pushcclosure(L,mf.mlua_func,1); 262 | return 1; 263 | } 264 | else if(mf.tt == STATIC_FUNCTION) 265 | { 266 | lua_pushlightuserdata(L,(void*)mf.sfunction); 267 | lua_pushcclosure(L,mf.slua_func,1); 268 | return 1; 269 | } 270 | else if(mf.tt == MEMBER_FIELD) 271 | { 272 | mf.getter(obj->ptr,L,mf.property); 273 | return 1; 274 | } 275 | } 276 | return 0; 277 | } 278 | 279 | static int Eq(lua_State *L) { 280 | if(lua_type(L,1) != lua_type(L,2)) { 281 | lua_pushboolean(L,0); 282 | return 1; 283 | } 284 | objUserData* left = (objUserData*)lua_touserdata(L,1); 285 | objUserData* right = (objUserData*)lua_touserdata(L,2); 286 | lua_pushboolean(L,left->ptr == right->ptr ? 1:0); 287 | return 1; 288 | } 289 | 290 | static int Construct(lua_State *L) 291 | { 292 | int arg_size = lua_gettop(L); 293 | if(arg_size < 16 && luaClassWrapper::constructors[arg_size].constructor) 294 | { 295 | luaClassWrapper::constructors[arg_size].constructor(L); 296 | luaL_setmetatable(L,luaRegisterClass::GetClassName()); 297 | } 298 | else 299 | { 300 | char str[512]; 301 | snprintf(str,512,"%s: unsupport %d arguments constructor\n",luaRegisterClass::GetClassName(),arg_size); 302 | luaL_error(L,str); 303 | } 304 | return 1; 305 | } 306 | 307 | static int on_gc(lua_State *L) 308 | { 309 | objUserData *self = (objUserData *)lua_touserdata(L,-1); 310 | if(self->ptr) 311 | { 312 | ptrToUserData.erase((void*)self->ptr); 313 | userdataSet.erase((void*)self); 314 | if(self->construct_by_lua) 315 | { 316 | delete self->ptr; 317 | } 318 | self->ptr = NULL; 319 | } 320 | return 0; 321 | } 322 | 323 | public: 324 | T *ptr; 325 | bool construct_by_lua; 326 | 327 | }; 328 | 329 | 330 | #ifndef _GETFUNC 331 | #define _GETFUNC (*(__func*)lua_touserdata(L,lua_upvalueindex(1))) 332 | #endif 333 | 334 | template 335 | class memberfunbinder{}; 336 | 337 | template 338 | class memberfunbinder 339 | { 340 | public: 341 | typedef Cla CLASS_TYPE; 342 | static int lua_cfunction(lua_State *L) 343 | { 344 | objUserData *obj = objUserData::checkobjuserdata(L,1); 345 | Cla *cla = obj->ptr; 346 | return doCall(L,cla,Int2Type::is_Void>()); 347 | } 348 | 349 | private: 350 | typedef Ret(Cla::*__func)(); 351 | 352 | template 353 | static int doCall(lua_State *L,Cla *cla,Int2Type) 354 | { 355 | push_obj(L,(cla->*_GETFUNC)()); 356 | return 1; 357 | } 358 | 359 | template 360 | static int doCall(lua_State *L,Cla *cla,Int2Type) 361 | { 362 | (cla->*_GETFUNC)(); 363 | return 0; 364 | } 365 | 366 | }; 367 | 368 | template 369 | class memberfunbinder 370 | { 371 | public: 372 | typedef Cla CLASS_TYPE; 373 | static int lua_cfunction(lua_State *L) 374 | { 375 | objUserData *obj = objUserData::checkobjuserdata(L,1); 376 | Cla *cla = obj->ptr; 377 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 378 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 379 | return doCall(L,cla,arg1,Int2Type::is_Void>()); 380 | } 381 | 382 | private: 383 | 384 | typedef Ret(Cla::*__func)(Arg1); 385 | 386 | template 387 | static int doCall(lua_State *L,Cla *cla,Arg1 arg1,Int2Type) 388 | { 389 | push_obj(L,(cla->*_GETFUNC)(arg1)); 390 | return 1; 391 | } 392 | 393 | template 394 | static int doCall(lua_State *L,Cla *cla,Arg1 arg1,Int2Type) 395 | { 396 | (cla->*_GETFUNC)(arg1); 397 | return 0; 398 | } 399 | 400 | }; 401 | 402 | template 403 | class memberfunbinder 404 | { 405 | public: 406 | typedef Cla CLASS_TYPE; 407 | static int lua_cfunction(lua_State *L) 408 | { 409 | objUserData *obj = objUserData::checkobjuserdata(L,1); 410 | Cla *cla = obj->ptr; 411 | typename GetReplaceType::type tmp_arg2 = popvalue::type>(L); 412 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 413 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 414 | Arg2 arg2 = GetRawValue::type>(tmp_arg2); 415 | return doCall(L,cla,arg1,arg2,Int2Type::is_Void>()); 416 | } 417 | 418 | private: 419 | 420 | typedef Ret(Cla::*__func)(Arg1,Arg2); 421 | 422 | template 423 | static int doCall(lua_State *L,Cla *cla,Arg1 arg1,Arg2 arg2,Int2Type) 424 | { 425 | push_obj(L,(cla->*_GETFUNC)(arg1,arg2)); 426 | return 1; 427 | } 428 | 429 | template 430 | static int doCall(lua_State *L,Cla *cla,Arg1 arg1,Arg2 arg2,Int2Type) 431 | { 432 | (cla->*_GETFUNC)(arg1,arg2); 433 | return 0; 434 | } 435 | }; 436 | 437 | template 438 | class memberfunbinder 439 | { 440 | public: 441 | typedef Cla CLASS_TYPE; 442 | static int lua_cfunction(lua_State *L) 443 | { 444 | objUserData *obj = objUserData::checkobjuserdata(L,1); 445 | Cla *cla = obj->ptr; 446 | typename GetReplaceType::type tmp_arg3 = popvalue::type>(L); 447 | typename GetReplaceType::type tmp_arg2 = popvalue::type>(L); 448 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 449 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 450 | Arg2 arg2 = GetRawValue::type>(tmp_arg2); 451 | Arg3 arg3 = GetRawValue::type>(tmp_arg3); 452 | return doCall(L,cla,arg1,arg2,arg3,Int2Type::is_Void>()); 453 | } 454 | 455 | private: 456 | 457 | typedef Ret(Cla::*__func)(Arg1,Arg2,Arg3); 458 | 459 | template 460 | static int doCall(lua_State *L,Cla *cla,Arg1 arg1,Arg2 arg2,Arg3 arg3,Int2Type) 461 | { 462 | push_obj(L,(cla->*_GETFUNC)(arg1,arg2,arg3)); 463 | return 1; 464 | } 465 | 466 | template 467 | static int doCall(lua_State *L,Cla *cla,Arg1 arg1,Arg2 arg2,Arg3 arg3,Int2Type) 468 | { 469 | (cla->*_GETFUNC)(arg1,arg2,arg3); 470 | return 0; 471 | } 472 | }; 473 | 474 | template 475 | class memberfunbinder 476 | { 477 | public: 478 | 479 | static int lua_cfunction(lua_State *L) 480 | { 481 | objUserData *obj = objUserData::checkobjuserdata(L,1); 482 | Cla *cla = obj->ptr; 483 | typename GetReplaceType::type tmp_arg4 = popvalue::type>(L); 484 | typename GetReplaceType::type tmp_arg3 = popvalue::type>(L); 485 | typename GetReplaceType::type tmp_arg2 = popvalue::type>(L); 486 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 487 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 488 | Arg2 arg2 = GetRawValue::type>(tmp_arg2); 489 | Arg3 arg3 = GetRawValue::type>(tmp_arg3); 490 | Arg4 arg4 = GetRawValue::type>(tmp_arg4); 491 | return doCall(L,cla,arg1,arg2,arg3,arg4,Int2Type::is_Void>()); 492 | } 493 | 494 | private: 495 | 496 | typedef Ret(Cla::*__func)(Arg1,Arg2,Arg3,Arg4); 497 | 498 | template 499 | static int doCall(lua_State *L,Cla *cla,Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Int2Type) 500 | { 501 | push_obj(L,(cla->*_GETFUNC)(arg1,arg2,arg3,arg4)); 502 | return 1; 503 | } 504 | 505 | template 506 | static int doCall(lua_State *L,Cla *cla,Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Int2Type) 507 | { 508 | (cla->*_GETFUNC)(arg1,arg2,arg3,arg4); 509 | return 0; 510 | } 511 | }; 512 | 513 | template 514 | void DefParent(Int2Type) 515 | { 516 | std::map > &parent_fields = luaClassWrapper::GetAllFields(); 517 | std::map > &filds = luaClassWrapper::GetAllFields(); 518 | typename std::map >::iterator it = parent_fields.begin(); 519 | typename std::map >::iterator end = parent_fields.end(); 520 | for( ; it != end; ++it) 521 | filds.insert(std::make_pair(it->first,it->second)); 522 | } 523 | 524 | template 525 | void DefParent(Int2Type){} 526 | 527 | 528 | 529 | template 530 | class class_def 531 | { 532 | private: 533 | class construct_function0 534 | { 535 | public: 536 | static void lua_cfunction(lua_State *L) 537 | { 538 | objUserData *obj = (objUserData *)lua_newuserdata(L, sizeof(objUserData)); 539 | obj->construct_by_lua = true; 540 | obj->ptr = new T; 541 | ptrToUserData[(void*)obj->ptr] = obj; 542 | userdataSet.insert((void*)obj); 543 | set_userdata(L,(void*)obj,-1); 544 | return; 545 | } 546 | }; 547 | 548 | template 549 | class construct_function1 550 | { 551 | public: 552 | static void lua_cfunction(lua_State *L) 553 | { 554 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 555 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 556 | objUserData *obj = (objUserData *)lua_newuserdata(L, sizeof(objUserData)); 557 | obj->construct_by_lua = true; 558 | obj->ptr = new T(arg1); 559 | ptrToUserData[(void*)obj->ptr] = obj; 560 | userdataSet.insert((void*)obj); 561 | set_userdata(L,(void*)obj,-1); 562 | } 563 | }; 564 | 565 | template 566 | class construct_function2 567 | { 568 | public: 569 | static void lua_cfunction(lua_State *L) 570 | { 571 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 572 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 573 | typename GetReplaceType::type tmp_arg2 = popvalue::type>(L); 574 | Arg2 arg2 = GetRawValue::type>(tmp_arg2); 575 | objUserData *obj = (objUserData *)lua_newuserdata(L, sizeof(objUserData)); 576 | obj->construct_by_lua = true; 577 | obj->ptr = new T(arg1,arg2); 578 | ptrToUserData[(void*)obj->ptr] = obj; 579 | userdataSet.insert((void*)obj); 580 | set_userdata(L,(void*)obj,-1); 581 | } 582 | }; 583 | 584 | template 585 | class construct_function3 586 | { 587 | public: 588 | static void lua_cfunction(lua_State *L) 589 | { 590 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 591 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 592 | typename GetReplaceType::type tmp_arg2 = popvalue::type>(L); 593 | Arg2 arg2 = GetRawValue::type>(tmp_arg2); 594 | typename GetReplaceType::type tmp_arg3 = popvalue::type>(L); 595 | Arg3 arg3 = GetRawValue::type>(tmp_arg3); 596 | objUserData *obj = (objUserData *)lua_newuserdata(L, sizeof(objUserData)); 597 | obj->construct_by_lua = true; 598 | obj->ptr = new T(arg1,arg2,arg3); 599 | ptrToUserData[(void*)obj->ptr] = obj; 600 | userdataSet.insert((void*)obj); 601 | set_userdata(L,(void*)obj,-1); 602 | } 603 | }; 604 | 605 | template 606 | class construct_function4 607 | { 608 | public: 609 | static void lua_cfunction(lua_State *L) 610 | { 611 | typename GetReplaceType::type tmp_arg1 = popvalue::type>(L); 612 | Arg1 arg1 = GetRawValue::type>(tmp_arg1); 613 | typename GetReplaceType::type tmp_arg2 = popvalue::type>(L); 614 | Arg2 arg2 = GetRawValue::type>(tmp_arg2); 615 | typename GetReplaceType::type tmp_arg3 = popvalue::type>(L); 616 | Arg3 arg3 = GetRawValue::type>(tmp_arg3); 617 | typename GetReplaceType::type tmp_arg4 = popvalue::type>(L); 618 | Arg4 arg4 = GetRawValue::type>(tmp_arg4); 619 | objUserData *obj = (objUserData *)lua_newuserdata(L, sizeof(objUserData)); 620 | obj->construct_by_lua = true; 621 | obj->ptr = new T(arg1,arg2,arg3,arg4); 622 | ptrToUserData[(void*)obj->ptr] = obj; 623 | userdataSet.insert((void*)obj); 624 | set_userdata(L,(void*)obj,-1); 625 | } 626 | }; 627 | public: 628 | class_def(lua_State *L):L(L){} 629 | 630 | template 631 | class_def& property(const char *name,property_type (T::*property)) 632 | { 633 | memberfield mf; 634 | mf.tt = MEMBER_FIELD; 635 | mf.getter = GetProperty; 636 | mf.property = (void*(T::*))property; 637 | mf.setter = SetProperty; 638 | luaClassWrapper::InsertFields(name,mf); 639 | return *this; 640 | } 641 | 642 | //class member method 643 | template 644 | class_def& method(const char *name,FUNTOR _func) 645 | { 646 | memberfield mf; 647 | mf.tt = MEMBER_FUNCTION; 648 | mf.mfunction = (void(T::*)())_func; 649 | mf.mlua_func = memberfunbinder::lua_cfunction; 650 | luaClassWrapper::InsertFields(name,mf); 651 | return *this; 652 | } 653 | 654 | //class static method 655 | template 656 | class_def& method(const char *name,Ret(*_func)()) 657 | { 658 | memberfield mf; 659 | mf.tt = STATIC_FUNCTION; 660 | mf.sfunction = (void (*)())_func; 661 | mf.slua_func = funbinder::lua_cfunction; 662 | luaClassWrapper::InsertFields(name,mf); 663 | return *this; 664 | } 665 | 666 | template 667 | class_def& method(const char *name,Ret(*_func)(Arg1)) 668 | { 669 | memberfield mf; 670 | mf.tt = STATIC_FUNCTION; 671 | mf.sfunction = (void (*)())_func; 672 | mf.slua_func = funbinder::lua_cfunction; 673 | luaClassWrapper::InsertFields(name,mf); 674 | return *this; 675 | } 676 | 677 | template 678 | class_def& method(const char *name,Ret(*_func)(Arg1,Arg2)) 679 | { 680 | memberfield mf; 681 | mf.tt = STATIC_FUNCTION; 682 | mf.sfunction = (void (*)())_func; 683 | mf.slua_func = funbinder::lua_cfunction; 684 | luaClassWrapper::InsertFields(name,mf); 685 | return *this; 686 | } 687 | 688 | template 689 | class_def& method(const char *name,Ret(*_func)(Arg1,Arg2,Arg3)) 690 | { 691 | memberfield mf; 692 | mf.tt = STATIC_FUNCTION; 693 | mf.sfunction = (void (*)())_func; 694 | mf.slua_func = funbinder::lua_cfunction; 695 | luaClassWrapper::InsertFields(name,mf); 696 | return *this; 697 | } 698 | 699 | 700 | template 701 | class_def& method(const char *name,Ret(*_func)(Arg1,Arg2,Arg3,Arg4)) 702 | { 703 | memberfield mf; 704 | mf.tt = STATIC_FUNCTION; 705 | mf.sfunction = (void (*)())_func; 706 | mf.slua_func = funbinder::lua_cfunction; 707 | luaClassWrapper::InsertFields(name,mf); 708 | return *this; 709 | } 710 | 711 | template 712 | class_def& constructor() 713 | { 714 | _constructor(Int2Type::is_Void == 1>()); 715 | return *this; 716 | } 717 | 718 | template 719 | class_def& constructor() 720 | { 721 | memberfield mf; 722 | mf.tt = CONSTRUCTOR; 723 | mf.constructor = construct_function2::lua_cfunction; 724 | _constructor(2,mf); 725 | return *this; 726 | } 727 | 728 | template 729 | class_def& constructor() 730 | { 731 | memberfield mf; 732 | mf.tt = CONSTRUCTOR; 733 | mf.constructor = construct_function3::lua_cfunction; 734 | _constructor(3,mf); 735 | return *this; 736 | } 737 | 738 | template 739 | class_def& constructor() 740 | { 741 | memberfield mf; 742 | mf.tt = CONSTRUCTOR; 743 | mf.constructor = construct_function4::lua_cfunction; 744 | _constructor(4,mf); 745 | return *this; 746 | } 747 | 748 | private: 749 | template 750 | void _constructor(Int2Type) 751 | { 752 | memberfield mf; 753 | mf.tt = CONSTRUCTOR; 754 | mf.constructor = construct_function0::lua_cfunction; 755 | _constructor(0,mf); 756 | } 757 | 758 | template 759 | void _constructor(Int2Type) 760 | { 761 | memberfield mf; 762 | mf.tt = CONSTRUCTOR; 763 | mf.constructor = construct_function1::lua_cfunction; 764 | _constructor(1,mf); 765 | } 766 | 767 | void _constructor(int arg_size,memberfield &mf) 768 | { 769 | if(1 == luaClassWrapper::InsertConstructors(arg_size,mf)) 770 | { 771 | lua_pushcfunction(L,objUserData::Construct); 772 | lua_setglobal(L,luaRegisterClass::GetClassName()); 773 | } 774 | } 775 | lua_State *L; 776 | 777 | }; 778 | 779 | template 780 | struct reg_cclass 781 | { 782 | static class_def _reg(lua_State *L,const char *name) 783 | { 784 | luaRegisterClass::SetClassName(name); 785 | luaClassWrapper::luaopen_objlib(L); 786 | luaRegisterClass::SetRegister(); 787 | DefParent(Int2Type::is_Void>()); 788 | DefParent(Int2Type::is_Void>()); 789 | DefParent(Int2Type::is_Void>()); 790 | DefParent(Int2Type::is_Void>()); 791 | return class_def(L); 792 | } 793 | }; 794 | 795 | } 796 | #endif 797 | --------------------------------------------------------------------------------