Luna Wrap |
|
LunaWrapFunc(function)它将生成一个完整且最小的临时函数,可以通过例如 LunaFive 推送。
LunaWrap 包含 5 个文件,因此已打包到 ZIP 存档中:[LunaWrap.zip] 注意:我已将所有文件从我自己的项目中复制出来,这意味着我没有单独测试它们。反过来意味着它可能还没有编译,但我将尽快测试并可能修复所有文件。
LunaWrap::check( lua_State* state , int index ) 的行为与 luaL_check* 在任意类型 T 上的行为相同。 LunaWrap::lightcheck<T>( lua_State* state , int index , T fallback = T() ) 检查堆栈位置是否存在必要的值并返回它。如果不存在,则返回指定回退值的第三个参数。 LunaWrap::is_a<T>( lua_State* state , int index ) 返回 true,如果提供的堆栈位置的值为 T,否则返回 false。通过使用 LunaWrap::push( lua_State* state , ... ),您可以通过 ... 推送任意数量的 C++ 类型,而 push() 将始终返回它推送到堆栈上的 lua 值的数量。这样,您可以轻松地执行
int foo( lua_State* state ){ return LunaWrap::push( state , 5 , std::string("Hello World") , std::map<int,int>() );
以下示例以众所周知的 Account 类为特色。请注意,您不再需要编写 Lua “代理” 函数,因为它们是由 LunaWrap 为您生成的。我所说的“代理” 函数是指那些接受 lua_State*、从 lua 堆栈中读取 C++ 函数的所有参数、调用实际的 C++ 函数并返回它返回的值数量(通常为 1)的函数。您真的可以立即在 Lua 中开始使用您的 C++ 类!
#include "Luna.h" #include "LunaWrapFunc.h" class Account { private: int balance; public: Account() : balance( 0 ) {} void deposit( int amount ){ if( amount >= 0 ) balance += amount; } int withdraw( int amount ){ if( balance < amount ) amount = balance; balance -= amount; return amount; } int balance() const { return balance; } //! Lua!// static const char className[]; static Luna<Account>::FunctionType methods[]; static Luna<Account>::PropertyType properties[]; }; const char Account::className[] = "Account"; Luna<Account>::FunctionType Account::methods[] = { { "deposit" , LunaWrapFunc( &Account::deposit ) }, { "withdraw" , LunaWrapFunc( &Account::withdraw ) } }; Luna<Account>::PropertyType Account::properties[] = { { "balance", LunaWrapFunc( &Account::balance ) , 0 } // Readonly property };
如果您确实有一个“代理” 类,也就是说,您通过 Luna 注册的类,它实际上只是对您向 lua 提供的 C++ 类的引用,那么仍然可以使用 LunaWrapFunc?:您只需要在代理类中提供一个到实际类的强制转换运算符。由于这听起来比实际情况要复杂得多,让我们也举一个例子。
#include "Luna.h" #include "LunaWrapFunc.h" class StringRef : public std::shared_ptr<std::string> { public: // Cast-operator to the string object this class "proxies" operator string&(){ return *(*this) ); } //! Lua!// static const char className[]; static Luna<Account>::FunctionType methods[]; static Luna<Account>::PropertyType properties[]; }; const char StringRef::className[] = "StringRef"; Luna<StringRef>::FunctionType StringRef::methods[] = { { "front" , LunaWrapFunc( (char&(string::*)()) &string::front , StringRef ) }, // The cast is needed to disambiguate the const-version front() from the non-const version { "back" , LunaWrapFunc( (char&(string::*)()) &string::back , StringRef ) }, // Same here { "push_back" , LunaWrapFunc( (char&(string::*)()) &string::back , StringRef ) } }; Luna<StringRef>::PropertyType StringRef::properties[] = { { "length" , LunaWrapFunc( &string::length , StringRef ) , 0 } // Readonly property };