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
};