An example for wrapping of classes

import lua.all;

import tango.io.Stdout;
import Int = tango.text.convert.Integer;

class Integer
{
    private int data_;

    public this (LuaState L)
    {

    }

    public this ()
    {
        this.data = 1;
    }

    public int data ()
    {
        return this.data_;
    }

    public int lua_get_data (LuaState L)
    {
                //      Stdout.formatln ("lua_get_data called with: {}", new LuaStack (L));                                                                                                                        

                L.pushNumber (this.data);
        return 1;
    }

    public int data (int value)
    {
        return this.data_ = value;
    }

    public int lua_set_data (LuaState L)
    {
        this.data_ = cast (int) L.checkNumber (1);
        return 0;
    }

    public int lua_tostring (LuaState L)
    {
                L.pushString (Int.toString (data_));
                return 1;
    }

    public static int lua_static (LuaState L)
    {
                L.pushString ("Hello world!");

                return 1;
    }
}

class Base
{
    private Integer data_;

    this ()
    {
        this.data_ = new Integer;
    }

    public Integer data ()
    {
        return this.data_;
    }

    public int lua_get_data (LuaState L)
    {
                L.wrapClass (data_);
                return 1;
    }

    public int lua_set_data (LuaState L)
    {
                data_ = L.unwrapClass !(Integer) (1);

                return 0;
    }
}

class Derived : Base
{
    public int lua_get_one (LuaState L)
    {
                L.pushNumber (1);
                return 1;
    }
}

int simpleFunction (LuaState L)
{
    Stdout.format ("simpleFunction got {} arguments!", L.top).newline;

    return 0;
}

int main (char[][] args)
{
    char[] stdout;
    void writer (char[] data)
    {
        stdout ~= data;
    }

    auto L = new LuaState (&writer);

    // register the function                                                                                                                                                                                       
    mixin (mixinLuaRegisterFunction ("L", "ClassTest.simpleFunction", "mylib.func"));
    mixin (mixinLuaRegisterFunction ("L", "ClassTest.Integer.lua_static", "mylib.static"));

    // register the constructor                                                                                                                                                                                    
    mixin (mixinLuaRegisterConstructor ("L", "ClassTest.Integer", "mylib.newint"));

    // register the methods in this state                                                                                                                                                                          
    mixin (mixinLuaRegisterMethod ("L", "ClassTest.Integer.lua_get_data", "get"));
    mixin (mixinLuaRegisterMethod ("L", "ClassTest.Integer.lua_set_data", "set"));
    mixin (mixinLuaRegisterMethod ("L", "ClassTest.Integer.lua_tostring", "__tostring"));

    mixin (mixinLuaRegisterMethod ("L", "ClassTest.Base.lua_get_data", "get"));

    mixin (mixinLuaRegisterMethod ("L", "ClassTest.Base.lua_set_data", "set"));

    mixin (mixinLuaRegisterMethod ("L", "ClassTest.Derived.lua_get_data", "get"));
    mixin (mixinLuaRegisterMethod ("L", "ClassTest.Derived.lua_set_data", "set"));
    mixin (mixinLuaRegisterMethod ("L", "ClassTest.Derived.lua_get_one", "one"));

    auto b = new Base ();
    auto d = new Derived ();

    // push a wrapper for b                                                                                                                                                                                        
    L.wrapClass (b);

    // make it a global var                                                                                                                                                                                        
    L.setGlobal ("base");

    // also possible for properties, returning classes                                                                                                                                                             
    L.wrapClass (b.data).setGlobal ("i");

    L.wrapClass (d).setGlobal ("d");

    char[] code = `                                                                                                                                                                                                
        print (mylib.static ());                                                                                                                                                                                   
                direct = base:get ();                                                                                                                                                                              
                indirect = i;                                                                                                                                                                                      
                idirect = base:get():get();                                                                                                                                                                        
                iindirect = i:get();                                                                                                                                                                               
                print (i:get());                                                                                                                                                                                   
        i:set(10);                                                                                                                                                                                                 
        base:set(i);                                                                                                                                                                                               
        print (base:get():get(20));                                                                                                                                                                                
                print (direct:get(), indirect:get(), idirect, iindirect);                                                                                                                                          
                mylib.func ('abc', 1, 2, 3);                                                                                                                                                                       
                bar = mylib.newint (100);                                                                                                                                                                          
                print (bar:get());                                                                                                                                                                                 
                print (d:one());                                                                                                                                                                                   
                d:set( mylib.newint (13) );                                                                                                                                                                        
                print (d:get ());`;

    L.doString (true, code, "Foo");

    Stdout ("Output:\n----------\n") (stdout) ("\n-----------\n") ();

    return 0;
}


Author: Matthias Walter