1 module dqml.qobject; 2 3 import dqml.global; 4 import std.stdio; 5 import std.format; 6 import std.conv; 7 import std.container; 8 import std.traits; 9 import std.string; 10 import std.algorithm; 11 import dqml.qmetaobject; 12 import dqml.qobjectgenerators; 13 import dqml.dothersideinterface; 14 import dqml.qmetatype; 15 import dqml.qvariant; 16 import core.memory; 17 18 public class QObject 19 { 20 shared static this() 21 { 22 m_staticMetaObject = new QMetaObject(dos_qobject_qmetaobject()); 23 } 24 25 public this(bool disableDosCalls = false) 26 { 27 this.disableDosCalls = disableDosCalls; 28 if (!this.disableDosCalls) 29 { 30 GC.setAttr(cast(void*)this, GC.BlkAttr.NO_MOVE); 31 this.vptr = dos_qobject_create(cast(void*)this, 32 metaObject().voidPointer(), 33 &staticSlotCallback); 34 } 35 } 36 37 ~this() 38 { 39 if (!this.disableDosCalls) 40 { 41 dos_qobject_delete(this.vptr); 42 this.vptr = null; 43 } 44 } 45 46 public void* voidPointer() 47 { 48 return this.vptr; 49 } 50 51 public void setVoidPointer(void* vptr) 52 { 53 this.vptr = vptr; 54 } 55 56 public void setDisableDosCalls(bool value) 57 { 58 this.disableDosCalls = value; 59 } 60 61 @property public string objectName() 62 { 63 char* array = dos_qobject_objectName(this.vptr); 64 string result = fromStringz(array).dup; 65 dos_chararray_delete(array); 66 return result; 67 } 68 69 public static QMetaObject staticMetaObject() 70 { 71 return m_staticMetaObject; 72 } 73 74 public QMetaObject metaObject() 75 { 76 return staticMetaObject(); 77 } 78 79 protected void onSlotCalled(QVariant slotName, QVariant[] parameters) 80 { 81 } 82 83 protected bool connect(QObject sender, 84 string signal, 85 string method, 86 ConnectionType type = ConnectionType.Auto) 87 { 88 return QObject.connect(sender, signal, this, method, type); 89 } 90 91 protected bool disconnect(QObject sender, 92 string signal, 93 string method) 94 { 95 return QObject.disconnect(sender, signal, this, method); 96 } 97 98 protected void emit(T)(string signalName, T t) 99 { 100 emit(signalName, new QVariant(t)); 101 } 102 103 protected void emit(string signalName, QVariant value) 104 { 105 QVariant[] array = [value]; 106 emit(signalName, array); 107 } 108 109 protected void emit(string signalName, QVariant[] arguments = null) 110 { 111 int length = cast(int)arguments.length; 112 void*[] array = null; 113 if (length > 0) { 114 array = new void*[length]; 115 foreach (int i, QVariant v; arguments) 116 array[i] = v.voidPointer(); 117 } 118 dos_qobject_signal_emit(this.vptr, 119 signalName.toStringz(), 120 length, 121 array.ptr); 122 } 123 124 protected extern (C) static void staticSlotCallback(void* qObjectPtr, 125 void* rawSlotName, 126 int numParameters, 127 void** parametersArray) 128 { 129 QVariant[] parameters = new QVariant[numParameters]; 130 for (int i = 0; i < numParameters; ++i) 131 parameters[i] = new QVariant(parametersArray[i], Ownership.Clone); 132 QObject qObject = cast(QObject) qObjectPtr; 133 QVariant slotName = new QVariant(rawSlotName, Ownership.Clone); 134 qObject.onSlotCalled(slotName, parameters); 135 dos_qvariant_assign(parametersArray[0], parameters[0].voidPointer()); 136 } 137 138 protected static bool connect(QObject sender, 139 string signal, 140 QObject receiver, 141 string method, 142 ConnectionType type = ConnectionType.Auto) 143 { 144 return dos_qobject_signal_connect(sender.voidPointer, 145 signal.toStringz, 146 receiver.voidPointer, 147 method.toStringz, 148 type); 149 150 } 151 152 protected static bool disconnect(QObject sender, 153 string signal, 154 QObject receiver, 155 string method) 156 { 157 return dos_qobject_signal_disconnect(sender.voidPointer, 158 signal.toStringz, 159 receiver.voidPointer, 160 method.toStringz); 161 } 162 163 template connect(alias slot) 164 { 165 protected static bool connect(QObject sender, 166 string signalName, 167 QObject receiver, 168 ConnectionType type = ConnectionType.Auto) 169 { 170 return connect(sender, 171 SIGNAL!slot(signalName), 172 receiver, 173 SLOT!slot); 174 } 175 176 protected bool connect(QObject sender, 177 string signalName, 178 ConnectionType type = ConnectionType.Auto) 179 { 180 return connect!slot(sender, signalName, this); 181 } 182 } 183 184 template disconnect(alias slot) 185 { 186 protected static bool disconnect(QObject sender, 187 string signalName, 188 QObject receiver) 189 { 190 return disconnect(sender, 191 SIGNAL!slot(signalName), 192 receiver, 193 SLOT!slot); 194 } 195 196 protected bool disconnect(QObject sender, 197 string signalName) 198 { 199 return disconnect!slot(sender, signalName, this); 200 } 201 } 202 203 protected void* vptr; 204 protected bool disableDosCalls; 205 private static QMetaObject m_staticMetaObject; 206 } 207 208 enum FindChildOptions : int 209 { 210 DirectOnly = 0, 211 Recursively 212 } 213 214 enum ConnectionType : int 215 { 216 Auto = 0, 217 Direct, 218 Queued, 219 BlockingQueued, 220 221 Unique = 0x80 222 } 223 224 template SIGNAL(alias slot) 225 { 226 string SIGNAL(string signalName) 227 { 228 return "2" ~ signalName ~ QObjectSignalParameters!slot; 229 } 230 } 231 232 template SLOT(alias slot) 233 { 234 enum string SLOT = "1" ~ __traits(identifier, slot) ~ QObjectSignalParameters!slot; 235 } 236 237 template QObjectSignalParameters(alias slot) 238 { 239 enum string QObjectSignalParameters = (Parameters!slot).stringof.replace("string", "QString"); 240 }