Thread overview
How can I get the "owner" of a method?
Sep 30, 2022
solidstate1991
Sep 30, 2022
Salih Dincer
Oct 01, 2022
solidstate1991
Oct 01, 2022
Ali Çehreli
September 30, 2022

Let's say I have a class or an interface with a function, and I want to pass that to a template to generate another function (in this case one that passes it to a scripting engine, and allows it to be called from there).

Currently I have the following issues:

  1. I have to pass the class/interface type to the template, and I cannot find anything about how to solve this issue.
  2. It also doesn't work at the moment, as it wants to call the member Func (name of the template argument) rather than the Function described as such. (There's also probably in std.functional I don't know about)

Code:

extern (C) public int registerDDelegate(alias Func, ClassType)(lua_State* state) nothrow
		if(isSomeFunction!(Func)) {
	import std.traits:Parameters, ReturnType;
	
	Parameters!Func params;
	int stackCounter = 0;
	stackCounter--;
	ClassType c = luaGetFromIndex!ClassType(state, stackCounter);
	try {
		foreach_reverse(ref param; params) {
			stackCounter--;
			param = luaGetFromIndex!(typeof(param))(state, stackCounter);
		}
	} catch (Exception e) {
		luaL_error(state, "Argument type mismatch with D functions!");
	}
	
	try {
		static if(is(ReturnType!Func == void)) {
			c.Func(params);
			return 0;
		} else static if(is(ReturnType!Func == struct)) {
			auto retVal = c.Func(params);
			static foreach (key ; retVal.tupleof) {
				LuaVar(key).pushToLuaState(state);
			}
			return cast(int)retVal.tupleof.length;
		} else {
			LuaVar(c.Func(params)).pushToLuaState(state);
			return 1;
		}
	} catch (Exception e) {
		//luaPushVar(L, null);
		lastLuaToDException = e;
		try {
			luaL_error(state, ("A D function threw: "~e.toString~"!\0").ptr);
		} catch(Exception e) {
			luaL_error(state, "D threw when stringifying exception!");
		}
		return 1;
	}
}
September 30, 2022

On Friday, 30 September 2022 at 21:11:48 UTC, solidstate1991 wrote:

>

Let's say I have a class or an interface with a function, and I want to pass that to a template to generate another function (in this case one that passes it to a scripting engine, and allows it to be called from there).

Maybe this will help you:

template Bar(T)
{
  void fun() {}
}

class Foo(T)
{
  mixin Bar!T b;
  alias fun = b.fun;

  void test()
  {
    fun();
  }
}

SDB@79

September 30, 2022
On 9/30/22 14:11, solidstate1991 wrote:

> extern (C) public int registerDDelegate(alias Func,

That can be a lambda that takes ClassType. I wrote the following along with place holder as I assumed them to be:

class C {
    string s;

    void foo() {
        import std.stdio : writeln;
        writeln("Look ma: It was ", s, " but I am using it in D!");
    }
}

auto luaGetFromIndex(C)() {
    auto c = new C();
    c.s = "created in Lua";
    return c;
}

extern (C)
int registerDDelegate(alias Func)() {
    import std.traits : Parameters;
    alias ClassType = Parameters!Func[0];
    auto c = luaGetFromIndex!ClassType();

    Func(c);
    return 0;
}

void main() {
    // Here: The lambda takes a C:
    registerDDelegate!((C c) => c.foo);
}

Ali


October 01, 2022

On Friday, 30 September 2022 at 22:20:06 UTC, Salih Dincer wrote:

>

Maybe this will help you:

template Bar(T)
{
  void fun() {}
}

class Foo(T)
{
  mixin Bar!T b;
  alias fun = b.fun;

  void test()
  {
    fun();
  }
}

SDB@79

The issue with that is in that case is instead of writing boilerplate I'll have to rewrite already existing functions.

Currently, to make objects compatible with Lua in some way, I have to write functions like this:

package void scrollLayer(void* target, int x, int y) {
	Layer l = cast(Layer)target;
	l.scroll(x, y);
}

This is very time consuming, and some automated method would be preferred where it can be done (some manual stuff will be done of course), then I can further automate it by using user attributes.