Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

An example for wrapping of classes

module test;

import lua.all;

version (Tango)
{
	import tango.io.Stdout;
	import tango.text.convert.Integer : parseInt = toString;
}
else
{
	import std.stdio;
	import std.string : parseInt = toString;
}

class Integer
{
	private int data_;

	public this (LuaState L)
	{
		data_ = L.checkInteger(1);
	}

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

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

	public int lua_get_data (LuaState 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_ = L.checkInteger (1);
		return 0;
	}

	public int lua_tostring (LuaState L)
	{
				L.pushString (parseInt(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)
{
	writefln("lua_set_data called with: %s", new LuaStackTrace (L));

	return 0;
}

version(D_Version2) mixin("alias const(char) cchar;"); else alias char cchar;
int main (string[] args)
{
	char[] stdout;
	void writer (cchar[] data)
	{
		stdout ~= data;
	}

	auto L = new LuaState (&writer);

	// register the function
	mixin (mixinLuaRegisterFunction ("L", "simpleFunction", "mylib.func")); // full typeid string isn't required for functions
	mixin (mixinLuaRegisterFunction ("L", "test.Integer.lua_static", "mylib.static"));

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

	// register the methods in this state
	mixin (mixinLuaRegisterMethod ("L", "test.Integer.lua_get_data", "get")); // full typeid string is required for class stuff
	mixin (mixinLuaRegisterMethod ("L", "test.Integer.lua_set_data", "set"));
	mixin (mixinLuaRegisterMethod ("L", "test.Integer.lua_tostring", "__tostring"));

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

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

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

	L.pushNil ();
  	L.pushNumber (2.0);
   	L.pushInteger (3);

   	writefln ("%s %s %s", L.getObject (-1).toString, L.getObject (-2).toString, L.getObject (-3).toString);

	
	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");

	string 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());
				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");

	writef("Output:\n----------\n" ~ stdout ~ "\n-----------\n");

	return 0;
}

Authors: Matthias Walter | Trass3r