Luna Wrap

lua-users home
wiki

This piece of code is intended to massively simplify interactions with C++ and Lua. That is, it provides:

Download

LunaWrap comes with 5 files, that's why it's been packed into ZIP-Archive: [LunaWrap.zip] Note: I have copied all files out of my own project, that means I have not tested them standalone. That in turn means that it might not compile yet, but I will test and possibly fix all files ASAP.

Usage of check<T>, lightcheck<T>, is_a<T> and push

LunaWrap::check( lua_State* state , int index ) behaves just like luaL_check* on an arbitrary type T. LunaWrap::lightcheck<T>( lua_State* state , int index , T fallback = T() ) checks whether the necessary value is at the stack position and returns it. If not, it returns the third parameter that specifies the fallback. LunaWrap::is_a<T>( lua_State* state , int index ) returns true, if the value at the supplied stack position is a T, false otherwise. By using LunaWrap::push( lua_State* state , ... ) you can push as many C++ types as you want through ..., while push() will always return the number of lua-values, that it pushed onto the stack. That way, you can easily do

int foo( lua_State* state ){ return LunaWrap::push( state , 5 , std::string("Hello World") , std::map<int,int>() ); 

Usage of the LunaWrapFunc?()-Macro

The following example features the well-known Account-class. Notice how you don't have to write the Lua-"proxy"-functions anymore, since they are being generated for you by LunaWrap. By "proxy"-functions I mean the ones that take a lua_State*, read all the arguments for the C++ function off the lua-stack, call the actual C++-function and return the number of the values it returned (usually 1). You can really start using your C++ classes right away in Lua!


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

If you really have a "proxy"-class, that is, the one you register through Luna and which actually only is a reference to the C++ Class your making available to lua, it's still possible to use LunaWrapFunc?: You only have to provide a cast-operator within proxy class to the actual class. Since that sounds way more diffuse than it is, let's have an example of that, too.

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

RecentChanges · preferences
edit · history
Last edited August 6, 2016 10:16 am GMT (diff)