LuaTinker 使用

来源:互联网 发布:淘宝销售属性什么意思 编辑:程序博客网 时间:2024/06/05 16:52

LuaTinker的作者是Kwon-il Lee韩国人写的,最新的版本是0.2.C,这个C++ wrapper For Lua能够方便和

快捷与C/C++通信,LuaTinker参考了luabind和luaplus的特征写的,虽然没有bindlua和luaplus这本强大

和提供很多功能,LuaTinker的实现只有两个文件,但是LuaTinker提供的基本能够满足大部的要求,用户

还可以对它进一步的扩充,而且用于游戏上特为方便,以下是LuaTinker使用C++结构和类的例子:

// 一个基类
struct base
{
 base() {}

 const char* is_base(){ return "this is base"; }
};

// 一个测试类
class test : public base
{
public:
 test(int val) : _test(val) {}
 ~test() {}

 const char* is_test(){ return "this is test"; }

 void ret_void() {}
 int ret_int()   { return _test;   }
 int ret_mul(int m) const { return _test * m;  }
 A get()    { return A(_test);  }
 void set(A a)   { _test = a.value;  }
 int _test;
};

int main()
{
 // 注册base类型到LUA
 lua_tinker::class_<base>("base")
  .def("is_base", &base::is_base)
  ;
 
 // 注册test类型到LUA,注册test的成员函数和成员变量
 lua_tinker::class_<test>("test")
  .inh<base>() // 注册继承类
  .def(lua_tinker::constructor<int>()) //注册构造函数
  .def("is_test", &test::is_test)           // 注册成员函数
  .def("ret_void", &test::ret_void)
  .def("ret_int", &test::ret_int)
  .def("ret_mul", &test::ret_mul)
  .def("get", &test::get)
  .def("set", &test::set)
  .def_readwrite("_test", &test::_test) // 注册成员变量
  ;

 test g_test(11);
 
 lua_tinker::decl("g_test", &g_test);
 
}

// Lua脚本
temp = test(4)  创建一个test类
print(temp._test) 打印test的_test成员

print(g_test)     
print(g_test._test) 打印g_test的成员变量_test
print(g_test:is_test()) 输出信息  
print(g_test:ret_int()) 返回g_test的成员变量_test

这么几句就能够方便的使用C/C++定义的结构或类,下一篇将会介绍其他的用法.
介绍完用法之后会从结构上分析lua_tinker的结构和设计.

 

 

// lua_tinker.h
//
// LuaTinker - Simple and light C++ wrapper for Lua.
//
// Copyright (c) 2005 Kwon-il Lee (zupet@hitel.net)
// 
// please check Licence.txt file for licence and legal issues.

#if !defined(_LUA_TINKER_H_)
#define _LUA_TINKER_H_

#include <new>

namespace lua_tinker
{
 // debug helpers
 void enum_stack(lua_State *L, int start=0);
 int  _exception(lua_State *L);

 void dofile(const char *filename);
 void dostring(const char* buff);
 void dobuffer(const char* buff, size_t sz);

 void dofile(lua_State *L, const char *filename);
 void dostring(lua_State *L, const char* buff);
 void dobuffer(lua_State *L, const char* buff, size_t sz);

 // basic Object
 struct lua_state
 {
  static void open(lua_State *in)
  { 
   L(in); 
   init_s64(in);
   init_u64(in);
  }

  static lua_State* L(lua_State *in=NULL);
  static void   init_s64(lua_State *L);
  static void   init_u64(lua_State *L);
 };

 // for LuaBind
 struct luabind : lua_state
 {
 };

 struct lua_obj
 {
  lua_obj& operator,(const lua_obj& obj) { return *this; }
 };

 struct module
 {
  module(lua_State *L){}
  void operator[](const lua_obj& obj){}
 };

 struct lua_value
 {
  virtual void to_lua(lua_State *L) = 0;
 };

 // type trait
 template<typename T> struct class_;

 template<bool C, typename A, typename B> 
 struct if_ {};
 template<typename A, typename B> 
 struct if_<true, A, B> { typedef A type; };
 template<typename A, typename B> 
 struct if_<false, A, B> { typedef B type; };

 template<typename A>
 struct is_ptr { static const bool value = false; };
 template<typename A>
 struct is_ptr<A*> { static const bool value = true; };

 template<typename A>
 struct is_ref { static const bool value = false; };
 template<typename A>
 struct is_ref<A&> { static const bool value = true; };

 template<typename A>
 struct remove_const { typedef A type; };
 template<typename A>
 struct remove_const<const A> { typedef A type; };

 template<typename A>
 struct base_type { typedef A type; };
 template<typename A>
 struct base_type<A*> { typedef A type; };
 template<typename A>
 struct base_type<A&> { typedef A type; };

 template<typename A>
 struct class_type { typedef typename remove_const<typename base_type<A>::type>::type type; };
 
 /////////////////////////////////
 enum { no = 1, yes = 2 }; 
 typedef char (& no_type )[no]; 
 typedef char (& yes_type)[yes];

 struct int_conv_type { int_conv_type(int); };

 no_type int_conv_tester (...); 
 yes_type int_conv_tester (int_conv_type);

 no_type vfnd_ptr_tester (const volatile char *); 
 no_type vfnd_ptr_tester (const volatile short *); 
 no_type vfnd_ptr_tester (const volatile int *); 
 no_type vfnd_ptr_tester (const volatile long *); 
 no_type vfnd_ptr_tester (const volatile double *); 
 no_type vfnd_ptr_tester (const volatile float *); 
 no_type vfnd_ptr_tester (const volatile bool *); 
 yes_type vfnd_ptr_tester (const volatile void *);

 template <typename T> T* add_ptr(T&);

 template <bool C> struct bool_to_yesno { typedef no_type type; }; 
 template <> struct bool_to_yesno<true> { typedef yes_type type; };

 template <typename T> 
 struct is_enum 
 { 
  static T arg; 
  static const bool value = ( (sizeof(int_conv_tester(arg)) == sizeof(yes_type)) && (sizeof(vfnd_ptr_tester(add_ptr(arg))) == sizeof(yes_type)) ); 
 }; 
 /////////////////////////////////

 // from lua
 template<typename T>
 struct void2val { static T invoke(void* input){ return *(T*)input; } };
 template<typename T>
 struct void2ptr { static T* invoke(void* input){ return (T*)input; } };
 template<typename T>
 struct void2ref { static T& invoke(void* input){ return *(T*)input; } };

 template<typename T>  
 struct void2type
 {
  static T invoke(void* ptr)
  {
   return if_<is_ptr<T>::value
      ,void2ptr<base_type<T>::type>
      ,if_<is_ref<T>::value
       ,void2ref<base_type<T>::type>
       ,void2val<base_type<T>::type>
      >::type
     >::type::invoke(ptr);
  }
 };

 template<typename T>  
 struct user2type { static T invoke(lua_State *L, int index) { return void2type<T>::invoke(lua_touserdata(L, index)); } };

 template<typename T>
 struct lua2enum { static T invoke(lua_State *L, int index) { return (T)(int)lua_tonumber(L, index); } };

 template<typename T>
 struct lua2object
 { 
  static T invoke(lua_State *L, int index) 
  { 
   if(!lua_isuserdata(L,index))
   {
    lua_pushstring(L, "no class at first argument. (forgot ':' expression ?)");
    lua_error(L);
   }
   return void2type<T>::invoke(user2type<user*>::invoke(L,index)->m_p); 
  } 
 };

 template<typename T>
 struct lua2type
 {
  static T invoke(lua_State *L, int index)
  {
   return if_<is_enum<T>::value
      ,lua2enum<T>
      ,lua2object<T> 
     >::type::invoke(L, index);
  }
 };

 struct user
 {
  user(void* p) : m_p(p) {}
  virtual ~user() {}
  void* m_p;
 };

 template<typename T>
 struct val2user : user
 {
  val2user() : user(new T) {}

  template<typename T1>
  val2user(T1 t1) : user(new T(t1)) {}

  template<typename T1, typename T2>
  val2user(T1 t1, T2 t2) : user(new T(t1, t2)) {}

  template<typename T1, typename T2, typename T3>
  val2user(T1 t1, T2 t2, T3 t3) : user(new T(t1, t2, t3)) {}

  ~val2user() { delete ((T*)m_p); }
 };

 template<typename T>
 struct ptr2user : user
 {
  ptr2user(T* t) : user((void*)t) {}
 };

 template<typename T>
 struct ref2user : user
 {
  ref2user(T& t) : user(&t) {}
 };

 // to lua
 template<typename T>
 struct val2lua { static void invoke(lua_State *L, T& input){ new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(input); } };
 template<typename T>
 struct ptr2lua { static void invoke(lua_State *L, T* input){ if(input) new(lua_newuserdata(L, sizeof(ptr2user<T>))) ptr2user<T>(input); else lua_pushnil(L); } };
 template<typename T>
 struct ref2lua { static void invoke(lua_State *L, T& input){ new(lua_newuserdata(L, sizeof(ref2user<T>))) ref2user<T>(input); } };

 template<typename T>
 struct enum2lua { static void invoke(lua_State *L, T val) { lua_pushnumber(L, (int)val); } };

 template<typename T>
 struct object2lua 
 { 
  static void invoke(lua_State *L, T val) 
  { 
   if_<is_ptr<T>::value
    ,ptr2lua<base_type<T>::type>
    ,if_<is_ref<T>::value
     ,ref2lua<base_type<T>::type>
     ,val2lua<base_type<T>::type>
    >::type
   >::type::invoke(L, val);

   class_<class_type<T>::type>::push_meta(L);
   lua_setmetatable(L, -2);
  } 
 };

 template<typename T>
 struct type2lua
 {
  static void invoke(lua_State *L, T val)
  {
   if_<is_enum<T>::value
    ,enum2lua<T>
    ,object2lua<T>
   >::type::invoke(L, val);
  };
 };

 //
 template<typename T>  
 T func_(lua_State *L)
 {
  return user2type<T>::invoke(L, lua_upvalueindex(1));
 }

 // arguments
 struct pop_ 
 {
  template<typename T>  
  static T invoke(lua_State *L, int index)    { return lua2type<T>::invoke(L, index);     }
  template<> 
  static char* invoke(lua_State *L, int index)   { return (char*)lua_tostring(L, index);     }
  template<> 
  static const char* invoke(lua_State *L, int index)  { return (const char*)lua_tostring(L, index);   }
  template<> 
  static char invoke(lua_State *L, int index)    { return (char)lua_tonumber(L, index);     }
  template<> 
  static unsigned char invoke(lua_State *L, int index) { return (unsigned char)lua_tonumber(L, index);   }
  template<> 
  static short invoke(lua_State *L, int index)   { return (short)lua_tonumber(L, index);     }
  template<> 
  static unsigned short invoke(lua_State *L, int index) { return (unsigned short)lua_tonumber(L, index);  }
  template<> 
  static long invoke(lua_State *L, int index)    { return (long)lua_tonumber(L, index);     }
  template<> 
  static unsigned long invoke(lua_State *L, int index) { return (unsigned long)lua_tonumber(L, index);   }
  template<> 
  static int invoke(lua_State *L, int index)    { return (int)lua_tonumber(L, index);     }
  template<> 
  static unsigned int invoke(lua_State *L, int index)  { return (unsigned int)lua_tonumber(L, index);   }
  template<> 
  static float invoke(lua_State *L, int index)   { return (float)lua_tonumber(L, index);     }
  template<> 
  static double invoke(lua_State *L, int index)   { return (double)lua_tonumber(L, index);    }
  template<> 
  static bool invoke(lua_State *L, int index)    { return lua_toboolean(L, index) != 0;     }
  template<> 
  static void invoke(lua_State *L, int index)    { return;            }
  template<> 
  static __int64 invoke(lua_State *L, int index)
  {
   if(lua_isnumber(L,index))
    return (__int64)lua_tonumber(L, index);
   else
    return *(__int64*)lua_touserdata(L, index);
  }
  template<> 
  static unsigned __int64 invoke(lua_State *L, int index)
  {
   if(lua_isnumber(L,index))
    return (unsigned __int64)lua_tonumber(L, index);
   else
    return *(unsigned __int64*)lua_touserdata(L, index);
  }
 };

 // return value
 struct push_
 {
  template<typename T>  
  static void invoke(lua_State *L, T ret)     { type2lua<T>::invoke(L, ret); }
  template<>
  static void invoke(lua_State *L, char ret)    { lua_pushnumber(L, ret);  }
  template<>
  static void invoke(lua_State *L, unsigned char ret)  { lua_pushnumber(L, ret);  }
  template<>
  static void invoke(lua_State *L, short ret)    { lua_pushnumber(L, ret);  }
  template<>
  static void invoke(lua_State *L, unsigned short ret) { lua_pushnumber(L, ret);  }
  template<>
  static void invoke(lua_State *L, long ret)    { lua_pushnumber(L, ret);  }
  template<>
  static void invoke(lua_State *L, unsigned long ret)  { lua_pushnumber(L, ret);  }
  template<>
  static void invoke(lua_State *L, int ret)    { lua_pushnumber(L, ret);  }
  template<>
  static void invoke(lua_State *L, unsigned int ret)  { lua_pushnumber(L, ret);  }
  template<>
  static void invoke(lua_State *L, float ret)    { lua_pushnumber(L, ret);  }
  template<>
  static void invoke(lua_State *L, double ret)   { lua_pushnumber(L, ret);  }
  template<>
  static void invoke(lua_State *L, char* ret)    { lua_pushstring(L, ret);  }
  template<>
  static void invoke(lua_State *L, const char* ret)  { lua_pushstring(L, ret);  }
  template<>
  static void invoke(lua_State *L, bool ret)    { lua_pushboolean(L, ret);  }
  template<>
  static void invoke(lua_State *L, lua_value* ret)  { if(ret) ret->to_lua(L); else lua_pushnil(L); }
  template<> 
  static void invoke(lua_State *L, __int64 ret)   
  { 
   *(__int64*)lua_newuserdata(L, sizeof(__int64)) = ret;
   lua_pushstring(L, "__s64");
   lua_gettable(L, LUA_GLOBALSINDEX);
   lua_setmetatable(L, -2);
  }
  template<> 
  static void invoke(lua_State *L, unsigned __int64 ret)
  {
   *(unsigned __int64*)lua_newuserdata(L, sizeof(unsigned __int64)) = ret;
   lua_pushstring(L, "__u64");
   lua_gettable(L, LUA_GLOBALSINDEX);
   lua_setmetatable(L, -2);
  }
 };

 template<typename T>
 struct ret_ { static const int value = 1; };
 template<>
 struct ret_<void> { static const int value = 0; };

 // caller
 template<typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
 struct caller
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3,T4,T5)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4),pop_::invoke<T5>(L,5))); }
  template<>
  static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3,T4,T5)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4),pop_::invoke<T5>(L,5)); }
 };

 template<typename T1, typename T2, typename T3, typename T4>
 struct caller<T1,T2,T3,T4> 
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3,T4)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4))); }
  template<>
  static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3,T4)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4)); }
 };

 template<typename T1, typename T2, typename T3>
 struct caller<T1,T2,T3> 
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3))); }
  template<>
  static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3)); }
 };

 template<typename T1, typename T2>
 struct caller<T1,T2> 
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2))); }
  template<>
  static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2)); }
 };

 template<typename T1>
 struct caller<T1> 
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1)>(L)(pop_::invoke<T1>(L,1))); }
  template<>
  static void invoke<void>(lua_State *L) { func_<void(*)(T1)>(L)(pop_::invoke<T1>(L,1)); }
 };

 template<>
 struct caller<void> 
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)()>(L)()); }
  template<>
  static void invoke<void>(lua_State *L) { func_<void(*)()>(L)(); }
 };

 // function
 template<typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
 struct functor
 {
  template<typename RVal>
  static int invoke(lua_State *L) { caller<T1,T2,T3,T4,T5>::invoke<RVal>(L); return ret_<RVal>::value; }
 };

 template<typename RVal> 
 void push_func(lua_State *L, RVal (*func)())
 {
  lua_pushcclosure(L, functor<>::invoke<RVal>, 1);
 }

 template<typename RVal,class T1> 
 void push_func(lua_State *L, RVal (*func)(T1))
 { 
  lua_pushcclosure(L, functor<T1>::invoke<RVal>, 1);
 }

 template<typename RVal,class T1,class T2> 
 void push_func(lua_State *L, RVal (*func)(T1,T2))
 { 
  lua_pushcclosure(L, functor<T1,T2>::invoke<RVal>, 1);
 }

 template<typename RVal,class T1,class T2, typename T3> 
 void push_func(lua_State *L, RVal (*func)(T1,T2,T3))
 { 
  lua_pushcclosure(L, functor<T1,T2,T3>::invoke<RVal>, 1);
 }

 template<typename RVal,class T1,class T2, typename T3, typename T4> 
 void push_func(lua_State *L, RVal (*func)(T1,T2,T3,T4))
 { 
  lua_pushcclosure(L, functor<T1,T2,T3,T4>::invoke<RVal>, 1);
 }

 template<typename RVal,class T1,class T2, typename T3, typename T4, typename T5> 
 void push_func(lua_State *L, RVal (*func)(T1,T2,T3,T4,T5))
 { 
  lua_pushcclosure(L, functor<T1,T2,T3,T4,T5>::invoke<RVal>, 1);
 }

 // member variable
 template<typename T>
 T* this_(lua_State *L) 
 { 
  return pop_::invoke<T*>(L, 1); 
 }

 struct var_base
 {
  virtual void get(lua_State *L) = 0;
  virtual void set(lua_State *L) = 0;
 };

 template<typename T, typename V>
 struct mem_var : var_base
 {
  V T::*_var;
  mem_var(V T::*val) : _var(val) {}
  void get(lua_State *L) { push_::invoke(L, this_<T>(L)->*(_var));  }
  void set(lua_State *L) { this_<T>(L)->*(_var) = pop_::invoke<V>(L, 3); }
 };

 // member function
 template<typename T,class T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
 struct mem_caller
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3,T4,T5)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5),pop_::invoke<T5>(L,6))); }
  template<>
  static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3,T4,T5)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5),pop_::invoke<T5>(L,6)); }
 };

 template<typename T, typename T1, typename T2, typename T3, typename T4> 
 struct mem_caller<T,T1,T2,T3,T4>
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3,T4)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5))); }
  template<>
  static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3,T4)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5)); }
 };

 template<typename T, typename T1, typename T2, typename T3> 
 struct mem_caller<T,T1,T2,T3>
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4))); }
  template<>
  static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4)); }
 };

 template<typename T, typename T1, typename T2> 
 struct mem_caller<T,T1, T2>
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3))); }
  template<>
  static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3)); }
 };

 template<typename T, typename T1> 
 struct mem_caller<T,T1>
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1)>(L))(pop_::invoke<T1>(L,2))); }
  template<>
  static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1)>(L))(pop_::invoke<T1>(L,2)); }
 };

 template<typename T> 
 struct mem_caller<T>
 {
  template<typename RVal>
  static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)()>(L))()); }
  template<>
  static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)()>(L))(); }
 };
 
 // 
 template<typename T, typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void> 
 struct mem_functor
 {
  template<typename RVal>
  static int invoke(lua_State *L) { mem_caller<T,T1,T2,T3,T4,T5>::invoke<RVal>(L); return ret_<RVal>::value; }
 };

 template<typename RVal, typename T>
 void push_func(lua_State *L, RVal (T::*func)()) 
 { 
  lua_pushcclosure(L, mem_functor<T>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T>
 void push_func(lua_State *L, RVal (T::*func)() const) 
 { 
  lua_pushcclosure(L, mem_functor<T>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T, typename T1>
 void push_func(lua_State *L, RVal (T::*func)(T1)) 
 { 
  lua_pushcclosure(L, mem_functor<T,T1>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T, typename T1>
 void push_func(lua_State *L, RVal (T::*func)(T1) const) 
 { 
  lua_pushcclosure(L, mem_functor<T,T1>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T, typename T1, typename T2>
 void push_func(lua_State *L, RVal (T::*func)(T1,T2)) 
 { 
  lua_pushcclosure(L, mem_functor<T,T1,T2>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T, typename T1, typename T2>
 void push_func(lua_State *L, RVal (T::*func)(T1,T2) const) 
 { 
  lua_pushcclosure(L, mem_functor<T,T1,T2>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T, typename T1, typename T2, typename T3>
 void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3)) 
 { 
  lua_pushcclosure(L, mem_functor<T,T1,T2,T3>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T, typename T1, typename T2, typename T3>
 void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3) const) 
 { 
  lua_pushcclosure(L, mem_functor<T,T1,T2,T3>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4>
 void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4)) 
 { 
  lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4>
 void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4) const) 
 { 
  lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
 void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4,T5)) 
 { 
  lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4,T5>::invoke<RVal>, 1); 
 }

 template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
 void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4,T5) const) 
 { 
  lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4,T5>::invoke<RVal>, 1); 
 }

 // constructor
 template<typename T1=void, typename T2=void, typename T3=void, typename T4=void>
 struct constructor {};

 template<typename T1, typename T2, typename T3>
 struct constructor<T1,T2,T3>
 {
  template<typename T>
  static void invoke(lua_State *L)
  {
   new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4));
  }
 };


 template<typename T1, typename T2>
 struct constructor<T1,T2>
 {
  template<typename T>
  static void invoke(lua_State *L)
  {
   new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3));
  }
 };

 template<typename T1>
 struct constructor<T1>
 {
  template<typename T>
  static void invoke(lua_State *L)
  {
   new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2));
  }
 };

 template<>
 struct constructor<void>
 { 
  template<typename T>
  static void invoke(lua_State *L) 
  { 
   new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>();
  } 
 };

 template<typename T>
 struct creator
 {
  template<typename CONSTRUCTOR>
  static int invoke(lua_State *L) 
  { 
   CONSTRUCTOR::invoke<T>(L);
   class_<class_type<T>::type>::push_meta(L);
   lua_setmetatable(L, -2);

   return 1; 
  }
 };

 // destroyer
 template<typename T>
 struct destroyer
 {
  static int invoke(lua_State *L) 
  { 
   ((user*)lua_touserdata(L, 1))->~user();
   return 0;
  }
 };

 // get
 int get_var(lua_State *L);
 int set_var(lua_State *L);

 // Tinker Function
 template<typename F> 
 lua_obj def(const char* name, F func)
 { 
  lua_State *L = lua_state::L();
  lua_pushstring(L, name);
  lua_pushlightuserdata(L, func);
  push_func(L, func);
  lua_settable(L, LUA_GLOBALSINDEX);

  return lua_obj();
 }

 // Tinker Global
 template<typename T>
 lua_obj decl(const char* name, T object)
 {
  lua_State *L = lua_state::L();
  lua_pushstring(L, name);
  push_::invoke(L, object);
  lua_settable(L, LUA_GLOBALSINDEX);

  return lua_obj();
 }

 // Tinker Call
 template<typename RVal>
 RVal call(const char* name)
 {
  lua_State *L = lua_state::L();

  lua_pushcclosure(L, _exception, 0);
  lua_pushstring(L, name);
  lua_gettable(L, LUA_GLOBALSINDEX);
  if(lua_isfunction(L,-1))
  {
   lua_pcall(L, 0, ret_<RVal>::value, 1);
  }
  else
  {
   lua_pushfstring(L, "lua_tinker : attempt to call global `%s' (not a function)", name);
   _exception(L);
  }

  lua_remove(L, 1);
  return pop_::invoke<RVal>(L, -1);
 }

 template<typename RVal, typename T1>
 RVal call(const char* name, T1 arg)
 {
  lua_State *L = lua_state::L();

  lua_pushcclosure(L, _exception, 0);
  lua_pushstring(L, name);
  lua_gettable(L, LUA_GLOBALSINDEX);
  push_::invoke(L, arg);
  lua_pcall(L, 1, ret_<RVal>::value, 1);
  lua_remove(L, 1);
  return pop_::invoke<RVal>(L, -1);
 }

 template<typename RVal, typename T1, typename T2>
 RVal call(const char* name, T1 arg1, T2 arg2)
 {
  lua_State *L = lua_state::L();

  lua_pushcclosure(L, _exception, 0);
  lua_pushstring(L, name);
  lua_gettable(L, LUA_GLOBALSINDEX);
  push_::invoke(L, arg1);
  push_::invoke(L, arg2);
  lua_pcall(L, 2, ret_<RVal>::value, 1);
  lua_remove(L, 1);
  return pop_::invoke<RVal>(L, -1);
 }

 template<typename RVal, typename T1, typename T2, typename T3>
 RVal call(const char* name, T1 arg1, T2 arg2, T3 arg3)
 {
  lua_State *L = lua_state::L();

  lua_pushcclosure(L, _exception, 0);
  lua_pushstring(L, name);
  lua_gettable(L, LUA_GLOBALSINDEX);
  push_::invoke(L, arg1);
  push_::invoke(L, arg2);
  push_::invoke(L, arg3);
  lua_pcall(L, 3, ret_<RVal>::value, 1);
  lua_remove(L, 1);
  return pop_::invoke<RVal>(L, -1);
 }

 // Tinker Class
 template<typename T>
 struct class_ : lua_obj
 {
  // initialize
  class_(const char* name) 
  : m_L(lua_state::L())
  { 
   _name(name);

   lua_pushstring(m_L, name);
   lua_newtable(m_L);

   lua_pushstring(m_L, "__name");
   lua_pushstring(m_L, name);
   lua_rawset(m_L, -3);

   lua_pushstring(m_L, "__index");
   lua_pushcclosure(m_L, get_var, 0);
   lua_rawset(m_L, -3);

   lua_pushstring(m_L, "__newindex");
   lua_pushcclosure(m_L, set_var, 0);
   lua_rawset(m_L, -3);

   lua_pushstring(m_L, "__gc");
   lua_pushcclosure(m_L, destroyer<T>::invoke, 0);
   lua_rawset(m_L, -3);

   lua_settable(m_L, LUA_GLOBALSINDEX);
  }

  // constructor
  template<typename CONSTRUCTOR>
  class_<T>& def(CONSTRUCTOR)
  {
   class_<class_type<T>::type>::push_meta(m_L);

   lua_newtable(m_L);
   lua_pushstring(m_L, "__call");
   lua_pushcclosure(m_L, creator<T>::invoke<CONSTRUCTOR>, 0);
   lua_rawset(m_L, -3);
   lua_setmetatable(m_L, -2);
   lua_pop(m_L,1);
   return *this; 
  }

  // inheritence
  template<typename P>
  class_<T>& inh()
  {
   class_<class_type<T>::type>::push_meta(m_L);
   lua_pushstring(m_L, "__parent");
   class_<class_type<P>::type>::push_meta(m_L);
   lua_rawset(m_L, -3);
   lua_pop(m_L,1);
   return *this; 
  }

  // functions
  template<typename F>
  class_<T>& def(const char* name, F func) 
  { 
   class_<class_type<T>::type>::push_meta(m_L);

   lua_pushstring(m_L, name);
   new(lua_newuserdata(m_L,sizeof(F))) F(func);
   push_func(m_L, func);
   lua_rawset(m_L, -3);

   lua_pop(m_L,1);
   return *this; 
  }

  // variables
  template<typename BASE, typename VAR>
  class_<T>& def_readwrite(const char* name, VAR BASE::*val) 
  { 
   class_<class_type<T>::type>::push_meta(m_L);

   lua_pushstring(m_L, name);
   new(lua_newuserdata(m_L,sizeof(mem_var<BASE,VAR>))) mem_var<BASE,VAR>(val);
   lua_rawset(m_L, -3);

   lua_pop(m_L,1);
   return *this; 
  }

  // metatable
  static void push_meta(lua_State *L)
  {
   const char* name = _name();
   if(name[0])
   {
    lua_pushstring(L, name);
    lua_gettable(L, LUA_GLOBALSINDEX);
   }
   else
   {
    lua_pushnil(L);
   }
  }

  // global name
  static const char* _name(const char* name = NULL)
  {
   static char temp[256] = "";
   if(name) strcpy(temp, name);
   return temp;
  }

  lua_State* m_L;     
 };

} // namespace lua_tinker

#endif //_LUA_TINKER_H_

 

// Lua Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "lua_tinker/lua_tinker.h"

struct A
{
 A(int v) : value(v) {}
 int value;
};

struct base
{
 base() {}

 const char* is_base(){ return "this is base"; }
};

class test : public base
{
public:
 test(int val) : _test(val) {}
 ~test() {}

 const char* is_test(){ return "this is test"; }

 void ret_void() {}
 int ret_int()    { return _test;   }
 int ret_mul(int m) const { return _test * m;  }
 A get()      { return A(_test);  }
 void set(A a)    { _test = a.value;  }

 int _test;
};

test g_test(11);

class parent : public lua_tinker::lua_value
{
public:
 void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐

 virtual const char* name() { return "parent"; }

 int m_parent;
};

class child : public parent
{
public:
 void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐

 const char* name() { return "child"; }

 int m_child;
};

class grandchild : public child
{
public:
 void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐

 const char* name() { return "grandchild"; }

 int m_grandchild;
};

lua_tinker::lua_value* GetChild(int n)
{
 static parent _parent;
 static child _child;
 static grandchild _grandchild;

 if(n == 0)
  return &_parent;
 else if(n == 1)
  return &_child;
 else
  return &_grandchild;
}

int _tmain(int argc, _TCHAR* argv[])
{
 lua_State* L = lua_open();

 // init Lua
 luaopen_base(L);
 luaopen_string(L);
 luaopen_table(L);

 lua_settop(L, 0);

 // LuaTinker
 lua_tinker::lua_state::open(L);

 lua_tinker::class_<base>("base")
  .def("is_base", &base::is_base)
  ;

 lua_tinker::class_<test>("test")
  .inh<base>()
  .def(lua_tinker::constructor<int>())
  .def("is_test", &test::is_test)
  .def("ret_void", &test::ret_void)
  .def("ret_int", &test::ret_int)
  .def("ret_mul", &test::ret_mul)
  .def("get", &test::get)
  .def("set", &test::set)
  .def_readwrite("_test", &test::_test)
  ;
 lua_tinker::decl("g_test", &g_test);

 lua_tinker::class_<parent>("parent")
  .def("name", &parent::name)
  .def_readwrite("m_parent", &parent::m_parent)
  ;

 lua_tinker::class_<child>("child")
  .inh<parent>()
  .def_readwrite("m_child", &child::m_child)
  ;

 lua_tinker::class_<grandchild>("grandchild")
  .inh<child>()
  .def_readwrite("m_grandchild", &grandchild::m_grandchild)
  ;

 lua_tinker::def("GetChild", GetChild);


 // lua_tinker 龋免 抛胶飘
 lua_tinker::dofile(L, "test.lua");

 lua_tinker::call<void>("print", "-------------------------- call<>");
 lua_tinker::call<void>("dir", g_test);
 lua_tinker::call<void>("print", "-------------------------- call<> finished");

 char temp[1024];
 while(true)
 {
  printf(">");
  if(stricmp(gets(temp), "quit") == 0)
   break;
  lua_tinker::dostring(L, temp);
 }

 // close Lua
 lua_close(L);

 return 0;
}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 崇拜瑜伽老师喜欢上他了怎么办 练瑜伽下不了腰贴不住腿怎么办 吃母乳宝宝吸的奶头疼怎么办 孩子吃奶把奶头咬破了怎么办 奶头边上让孩子咬破了吃奶疼怎么办 腰部受过伤久坐缓解腰疼怎么办 小孩八个月了还在软得很怎么办 产后第三天乳房胀痛有硬块怎么办 怀孕七个多月了胎位不正怎么办 怀孕6个月梅毒1:4怎么办 怀孕了胃酸胃涨吐酸水怎么办 怀孕了胃酸胃胀吐酸水怎么办 练瑜伽大腿外侧扭筋了怎么办 膝盖运动时疼痛睡觉不疼怎么办 在农村里床上老是有小蜈蚣该怎么办 瑜伽垫晒太阳后散发的甲醛怎么办 杯子盖上的皮垫子掉了漏水怎么办 20个月宝宝天天晚上不睡觉怎么办 八个月大小孩天天晚上不睡觉怎么办 如果开了光的貔貅不要了要怎么办 刚岀生的婴儿长得太快怎么办 呼市去办牌照时没有牌照怎么办 宾馆发现隐藏的摄像头怎么办报警吗 拍拍贷律师函寄到家里了怎么办 欠了拍拍贷本息一万多了怎么办 把人偷小孩的人贩子打死了怎么办 怀孕3个月没有胎心怎么办 社保局打印关系转移信封之后怎么办 长裙变装外出被发现了怎么办 超变陀螺怎么绳子拉不出来怎么办 梦幻诛仙传说时间得不到东西怎么办 夹在强势母亲和强势老公中间怎么办 工作调动校长总拖着不盖章怎么办 宝贝在妈妈肚子里发育慢怎么办 领导安排你负责一次讲座你怎么办 雷蛇北海巨妖耳机有回音怎么办 手机直播声卡有杂音有回音怎么办 大班见到陌生人入园怎么办安全教案 两首歌合并到一起中间有停顿怎么办 想做主持人但不是播音专业怎么办 动脉造影术2天后穿刺点出血怎么办