[DQml] Started the automatic generation of the code for handling the slot and signals
This commit is contained in:
parent
2f2d8d1b59
commit
6c368e70fc
|
@ -119,5 +119,5 @@ public class QObject
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void* vptr;
|
protected void* vptr;
|
||||||
private bool disableDosCalls;
|
protected bool disableDosCalls;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,148 @@
|
||||||
import dqml;
|
import dqml;
|
||||||
|
import std.traits;
|
||||||
|
import std.algorithm;
|
||||||
|
import std.string;
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
struct Slot {};
|
||||||
|
struct Signal {};
|
||||||
|
|
||||||
|
string GenerateVariantConversionCall(string typeName)
|
||||||
|
{
|
||||||
|
switch (typeName)
|
||||||
|
{
|
||||||
|
case "string":
|
||||||
|
return "toString()";
|
||||||
|
case "int":
|
||||||
|
return "toInt()";
|
||||||
|
default:
|
||||||
|
throw new Exception("error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateArgumentList(string[] typeNames)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
for (int i = 0; i < typeNames.length; ++i)
|
||||||
|
{
|
||||||
|
auto typeName = typeNames[i];
|
||||||
|
auto variantCall = GenerateVariantConversionCall(typeName);
|
||||||
|
result ~= i > 0 ? "," : "";
|
||||||
|
result ~= format("arguments[%d].%s", i+1, variantCall);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateSlotCall(SlotInfo info)
|
||||||
|
{
|
||||||
|
auto args = GenerateArgumentList(info.parameterTypes);
|
||||||
|
auto call = format("%s(%s)", info.name, args);
|
||||||
|
auto formatStr = info.returnType != "void" ? "arguments[0].setValue(%s)" : "%s";
|
||||||
|
return format(formatStr, call);
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateCaseBlock(SlotInfo info)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
result ~= format("case \"%s\":\n", info.name);
|
||||||
|
result ~= format("%s;\n", GenerateSlotCall(info));
|
||||||
|
result ~= "break;\n";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateOnSlotCalled(T)()
|
||||||
|
{
|
||||||
|
string result = "protected override void onSlotCalled(QVariant slotName, QVariant[] arguments)\n";
|
||||||
|
result ~= "{\n";
|
||||||
|
result ~= "switch(slotName.toString())\n";
|
||||||
|
result ~= "{\n";
|
||||||
|
foreach (info; IterateUDA!(T)())
|
||||||
|
result ~= GenerateCaseBlock(info);
|
||||||
|
result ~= "default: break;\n";
|
||||||
|
result ~= "}\n"; //
|
||||||
|
result ~= "}";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateMetaType(string typeName)
|
||||||
|
{
|
||||||
|
switch(typeName)
|
||||||
|
{
|
||||||
|
case "void":
|
||||||
|
return "QMetaType.Void";
|
||||||
|
case "int":
|
||||||
|
return "QMetaType.Int";
|
||||||
|
case "string":
|
||||||
|
return "QMetaType.String";
|
||||||
|
default:
|
||||||
|
throw new Exception(format("Unknown conversion from %s to QMetaType", typeName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateMetaTypesList(SlotInfo info)
|
||||||
|
{
|
||||||
|
string result = GenerateMetaType(info.returnType);
|
||||||
|
foreach (typeName; info.parameterTypes)
|
||||||
|
result ~= format(", %s", GenerateMetaType(typeName));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateQObjectInit(T)()
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
result ~= "protected void qobjectInit()\n";
|
||||||
|
result ~= "{\n";
|
||||||
|
|
||||||
|
foreach (info; IterateUDA!(T)())
|
||||||
|
{
|
||||||
|
auto metaTypes = GenerateMetaTypesList(info);
|
||||||
|
result ~= format("registerSlot(\"%s\", [%s]);\n", info.name, metaTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
result ~= "}";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SlotInfo
|
||||||
|
{
|
||||||
|
string name;
|
||||||
|
string returnType;
|
||||||
|
string[] parameterTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
SlotInfo[] IterateUDA(T)()
|
||||||
|
{
|
||||||
|
SlotInfo[] result;
|
||||||
|
|
||||||
|
foreach (member; __traits(allMembers, T))
|
||||||
|
{
|
||||||
|
static if (isSomeFunction!(__traits(getMember, T, member)))
|
||||||
|
{
|
||||||
|
// Retrieve the UDA
|
||||||
|
auto attributes = __traits(getAttributes, __traits(getMember, T, member));
|
||||||
|
|
||||||
|
// Turn the tuple in an array of strings
|
||||||
|
string[] attributeNames;
|
||||||
|
foreach (attribute; attributes)
|
||||||
|
attributeNames ~= typeof(attribute).stringof;
|
||||||
|
|
||||||
|
// Extract the Function Return Type and Arguments
|
||||||
|
if (attributeNames.canFind("Slot"))
|
||||||
|
{
|
||||||
|
SlotInfo slotInfo;
|
||||||
|
slotInfo.name = member;
|
||||||
|
slotInfo.returnType = ReturnType!(__traits(getMember, T, member)).stringof;
|
||||||
|
|
||||||
|
foreach (param; ParameterTypeTuple!(__traits(getMember, T, member)))
|
||||||
|
slotInfo.parameterTypes ~= param.stringof;
|
||||||
|
|
||||||
|
result ~= slotInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
class Contact : QObject
|
class Contact : QObject
|
||||||
{
|
{
|
||||||
|
@ -8,16 +152,20 @@ class Contact : QObject
|
||||||
registerSlot("setName", [QMetaType.Void, QMetaType.String]);
|
registerSlot("setName", [QMetaType.Void, QMetaType.String]);
|
||||||
registerSignal("nameChanged", [QMetaType.String]);
|
registerSignal("nameChanged", [QMetaType.String]);
|
||||||
registerProperty("name", QMetaType.String, "getName", "setName", "nameChanged");
|
registerProperty("name", QMetaType.String, "getName", "setName", "nameChanged");
|
||||||
|
|
||||||
|
writeln(GenerateOnSlotCalled!(Contact));
|
||||||
|
writeln(GenerateQObjectInit!(Contact));
|
||||||
}
|
}
|
||||||
|
|
||||||
~this() {}
|
~this() {}
|
||||||
|
|
||||||
|
@Slot()
|
||||||
public string getName()
|
public string getName()
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Slot()
|
||||||
public void setName(string name)
|
public void setName(string name)
|
||||||
{
|
{
|
||||||
if (m_name != name)
|
if (m_name != name)
|
||||||
|
@ -27,20 +175,8 @@ class Contact : QObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void onSlotCalled(QVariant slotName, QVariant[] arguments)
|
mixin(GenerateOnSlotCalled!(Contact));
|
||||||
{
|
mixin(GenerateQObjectInit!(Contact));
|
||||||
switch (slotName.toString())
|
|
||||||
{
|
|
||||||
case "getName":
|
|
||||||
arguments[0].setValue(getName());
|
|
||||||
break;
|
|
||||||
case "setName":
|
|
||||||
setName(arguments[1].toString());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string m_name;
|
private string m_name;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue