1 module dqml.qmetaobject; 2 3 import dqml.dothersideinterface; 4 import dqml.qmetatype; 5 import std.string; 6 import core.stdc.stdlib; 7 8 T* mallocArray(T)(int size) 9 { 10 if (size == 0) 11 return null; 12 return cast(T*) malloc(T.sizeof * size); 13 } 14 15 public struct ParameterDefinition 16 { 17 this(string name, QMetaType metaType) 18 { 19 this.name = name; 20 this.metaType = metaType; 21 } 22 23 string name; 24 QMetaType metaType; 25 } 26 27 public struct SignalDefinition 28 { 29 this(string name, string[] parametersNames, QMetaType[] parametersTypes) 30 { 31 this.name = name; 32 for (int i = 0; i < parametersNames.length; ++i) 33 parameters ~= ParameterDefinition(parametersNames[i], parametersTypes[i]); 34 } 35 36 string name; 37 ParameterDefinition[] parameters; 38 } 39 40 public struct SlotDefinition 41 { 42 this(string name, QMetaType returnType, string[] parametersNames, QMetaType[] parametersTypes) 43 { 44 this.name = name; 45 this.returnType = returnType; 46 for (int i = 0; i < parametersNames.length; ++i) 47 parameters ~= ParameterDefinition(parametersNames[i], parametersTypes[i]); 48 } 49 50 string name; 51 QMetaType returnType; 52 ParameterDefinition[] parameters; 53 } 54 55 public struct PropertyDefinition 56 { 57 this(string name, QMetaType type, string readSlot, string writeSlot, string notifySignal) 58 { 59 this.name = name; 60 this.type = type; 61 this.readSlot = readSlot; 62 this.writeSlot = writeSlot; 63 this.notifySignal = notifySignal; 64 } 65 66 string name; 67 QMetaType type; 68 string readSlot; 69 string writeSlot; 70 string notifySignal; 71 } 72 73 public class QMetaObject 74 { 75 public this(void* vptr) 76 { 77 this.vptr = vptr; 78 } 79 80 public this(QMetaObject superClass, 81 string className, 82 SignalDefinition[] signalDefinitions, 83 SlotDefinition[] slotDefinitions, 84 PropertyDefinition[] propertyDefinitions) 85 { 86 this.signalDefinitions = signalDefinitions; 87 this.slotDefinitions = slotDefinitions; 88 this.propertyDefinitions = propertyDefinitions; 89 90 auto dosSignalDefinitions = mallocDefinitions(signalDefinitions); 91 scope(exit) freeDefinitions(dosSignalDefinitions); 92 93 auto dosSlotDefinitions = mallocDefinitions(slotDefinitions); 94 scope(exit) freeDefinitions(dosSlotDefinitions); 95 96 auto dosPropertyDefinitions = mallocDefinitions(propertyDefinitions); 97 scope(exit) freeDefinitions(dosPropertyDefinitions); 98 99 this.vptr = dos_qmetaobject_create(superClass.vptr, 100 className.toStringz(), 101 dosSignalDefinitions, 102 dosSlotDefinitions, 103 dosPropertyDefinitions); 104 } 105 106 public ~this() 107 { 108 dos_qmetaobject_delete(this.vptr); 109 } 110 111 @property SignalDefinition[] signals() { return signalDefinitions; } 112 @property SlotDefinition[] slots() { return slotDefinitions; } 113 @property PropertyDefinition[] properties() { return propertyDefinitions; } 114 115 public void* voidPointer() 116 { 117 return this.vptr; 118 } 119 120 private DosSignalDefinitions mallocDefinitions(SignalDefinition[] definitions) 121 { 122 DosSignalDefinitions result; 123 result.count = cast(int)definitions.length; 124 result.definitions = mallocArray!DosSignalDefinition(result.count); 125 126 for (int i = 0; i < result.count; ++i) 127 { 128 SignalDefinition signalProto = definitions[i]; 129 DosSignalDefinition* signalDef = result.definitions + i; 130 signalDef.name = toStringz(signalProto.name); 131 signalDef.parametersCount = cast(int)signalProto.parameters.length; 132 signalDef.parameters = mallocArray!DosParameterDefinition(signalDef.parametersCount); 133 for (int j = 0; j < signalDef.parametersCount; ++j) 134 { 135 ParameterDefinition parameterProto = signalProto.parameters[j]; 136 DosParameterDefinition* parameterDef = signalDef.parameters + j; 137 parameterDef.name = toStringz(parameterProto.name); 138 parameterDef.metaType = parameterProto.metaType; 139 } 140 } 141 142 return result; 143 } 144 145 private void freeDefinitions(DosSignalDefinitions definitions) 146 { 147 for (int i = 0; i < definitions.count; ++i) 148 free((definitions.definitions + i).parameters); 149 free(definitions.definitions); 150 } 151 152 private DosSlotDefinitions mallocDefinitions(SlotDefinition[] definitions) 153 { 154 DosSlotDefinitions result; 155 result.count = cast(int)definitions.length; 156 result.definitions = mallocArray!DosSlotDefinition(result.count); 157 158 for (int i = 0; i < result.count; ++i) 159 { 160 SlotDefinition slotProto = definitions[i]; 161 DosSlotDefinition* slotDef = result.definitions + i; 162 slotDef.name = toStringz(slotProto.name); 163 slotDef.returnType = slotProto.returnType; 164 slotDef.parametersCount = cast(int)slotProto.parameters.length; 165 slotDef.parameters = mallocArray!DosParameterDefinition(slotDef.parametersCount); 166 for (int j = 0; j < slotDef.parametersCount; ++j) 167 { 168 ParameterDefinition parameterProto = slotProto.parameters[j]; 169 DosParameterDefinition* parameterDef = slotDef.parameters + j; 170 parameterDef.name = toStringz(parameterProto.name); 171 parameterDef.metaType = parameterProto.metaType; 172 } 173 } 174 175 return result; 176 } 177 178 private void freeDefinitions(DosSlotDefinitions definitions) 179 { 180 for (int i = 0; i < definitions.count; ++i) 181 free((definitions.definitions + i).parameters); 182 free(definitions.definitions); 183 } 184 185 private DosPropertyDefinitions mallocDefinitions(PropertyDefinition[] definitions) 186 { 187 DosPropertyDefinitions result; 188 result.count = cast(int)definitions.length; 189 result.definitions = mallocArray!DosPropertyDefinition(result.count); 190 for (int i = 0; i < result.count; ++i) 191 { 192 PropertyDefinition proto = definitions[i]; 193 DosPropertyDefinition* def = result.definitions + i; 194 def.name = toStringz(proto.name); 195 def.type = proto.type; 196 def.readSlot = toStringz(proto.readSlot); 197 def.writeSlot = toStringz(proto.writeSlot); 198 def.notifySignal = toStringz(proto.notifySignal); 199 } 200 return result; 201 } 202 203 private void freeDefinitions(DosPropertyDefinitions definitions) 204 { 205 free(definitions.definitions); 206 } 207 208 private void* vptr; 209 private PropertyDefinition[] propertyDefinitions; 210 private SignalDefinition[] signalDefinitions; 211 private SlotDefinition[] slotDefinitions; 212 }