122 lines
3.2 KiB
D
122 lines
3.2 KiB
D
import std.stdio;
|
|
import std.conv;
|
|
import std.container;
|
|
import std.traits;
|
|
import std.string;
|
|
import dothersideinterface;
|
|
import dslot;
|
|
import dsignal;
|
|
|
|
|
|
void NoConversionAssign(T)(void* lValue, void* rValue)
|
|
{
|
|
*(cast(T*)lValue) = *(cast(T*)rValue);
|
|
}
|
|
|
|
void SafeAssignCpp(int metaType, void* lValue, void* rValue)
|
|
{
|
|
if (metaType == 2) NoConversionAssign!int(lValue, rValue);
|
|
}
|
|
|
|
void SafeAssignD(int metaType, void* lValue, void* rValue)
|
|
{
|
|
if (metaType == 2) NoConversionAssign!int(lValue, rValue);
|
|
}
|
|
|
|
void* Allocate(int metaType)
|
|
{
|
|
if (metaType == 2) { int* result = new int(); *result = 0; return result; }
|
|
assert(false);
|
|
}
|
|
|
|
|
|
public class DObject
|
|
{
|
|
this()
|
|
{
|
|
dos_qobject_create(this.data, cast (void*) this, &staticSlotCallback);
|
|
}
|
|
|
|
~this()
|
|
{
|
|
dos_qobject_delete(this.data);
|
|
}
|
|
|
|
extern (C) static void staticSlotCallback(void* dobject, int slotIndex, int numMetaTypes, int* metaTypes, int numParameters, ref void** parameters)
|
|
{
|
|
DObject dObject = cast(DObject) dobject;
|
|
|
|
writeln("D: Received ", numMetaTypes, " metaTypes for ", numParameters, " parameters" );
|
|
|
|
// Given the MetaType arguments construct a void*[] array with good D type for the arguments
|
|
// without the return value. So we start from 1
|
|
void*[] args = new void*[numParameters];
|
|
|
|
for (int i = 1; i < numMetaTypes; ++i)
|
|
{
|
|
int metaType = metaTypes[i];
|
|
args[i] = Allocate(metaType);
|
|
SafeAssignD(metaType, args[i], parameters[i]);
|
|
}
|
|
|
|
// Retrieve the slot an call it
|
|
ISlot slot = dObject._slotsByIndex[slotIndex];
|
|
slot.Execute(args);
|
|
|
|
// Adapt the return type for being a good c++ value
|
|
SafeAssignCpp(metaTypes[0], parameters[0] , args[0]);
|
|
}
|
|
|
|
protected auto registerSlot(T)(string name, T t) {
|
|
debug writeln("D: Registering Slot \"", name, "\" of type \"", T.stringof, "\"");
|
|
auto slot = CreateDSlot(t);
|
|
auto rawName = name.toStringz();
|
|
int slotIndex = -1;
|
|
int[] parameterMetaTypes = slot.GetParameterMetaTypes();
|
|
int numArgs = cast(int)parameterMetaTypes.length;
|
|
dos_qobject_slot_create(data, rawName, numArgs, parameterMetaTypes.ptr, slotIndex);
|
|
writeln("D: Registered Slot has index ", slotIndex);
|
|
_slotsByName[name] = slot;
|
|
_slotsByIndex[slotIndex] = slot;
|
|
return slot;
|
|
}
|
|
|
|
protected auto registerSignal(Args...)(string name) {
|
|
debug writeln("D: Registering Signal \"", name, "\" of type \"", Args.stringof, "\"");
|
|
auto signal = CreateDSignal!(Args)();
|
|
_signals[name] = signal;
|
|
return signal;
|
|
}
|
|
|
|
public void* data;
|
|
private ISlot[string] _slotsByName;
|
|
private ISlot[int] _slotsByIndex;
|
|
private ISignal[string] _signals;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
auto test = new class DObject {
|
|
this()
|
|
{
|
|
foo = registerSlot("foo", &_foo);
|
|
bar = registerSlot("bar", &_bar);
|
|
fooSignal = registerSignal!()("fooSignal");
|
|
barSignal = registerSignal!(int)("barSignal");
|
|
}
|
|
|
|
DSlot!(void delegate()) foo;
|
|
void _foo() { writeln("D: Called slot \"_foo\"");}
|
|
|
|
DSlot!(void delegate(int)) bar;
|
|
void _bar(int arg) { writeln("D: Calling slot \"_bar\" with arg \"", arg, "\""); }
|
|
|
|
DSignal!() fooSignal;
|
|
DSignal!int barSignal;
|
|
};
|
|
|
|
test.foo();
|
|
test.bar(10);
|
|
test.fooSignal();
|
|
test.barSignal(10);
|
|
} |