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 ) 如果提供的堆栈位置上的值为 T,则返回 true,否则返回 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
};