Removed the fact that slots are called by index

The reason is that the index could change during insertion of new method or signal
This commit is contained in:
Filippo Cucchetto 2014-08-30 21:11:09 +02:00
parent 30fc908aa3
commit aaf62ce426
8 changed files with 37 additions and 144 deletions

View File

@ -13,8 +13,10 @@ Rectangle
}
Component.onCompleted: {
var result = myObject.tor("sfsdk");
console.log("From qml received value:", result)
var result1 = myObject.bar(1);
var result2 = myObject.foo(2);
var result3 = myObject.tor("3")
console.log("From qml received values:", result1, result2, result3)
}
Connections

View File

@ -20,13 +20,14 @@ public class DObject
dos_qobject_delete(this.data);
}
private extern (C) static void staticSlotCallback(void* dobject, int slotIndex, int numParameters, void** parameters)
private extern (C) static void staticSlotCallback(void* dobject, void* slotName, int numParameters, void** parameters)
{
QVariant[] arguments = new QVariant[numParameters];
for (int i = 0; i < numParameters; ++i)
arguments[i] = new QVariant(parameters[i]);
DObject dObject = cast(DObject) dobject;
ISlot slot = dObject._slotsByIndex[slotIndex];
QVariant name = new QVariant(slotName);
ISlot slot = dObject._slotsByName[name.toString()];
slot.Execute(arguments);
}
@ -40,7 +41,6 @@ public class DObject
dos_qobject_slot_create(data, rawName, numArgs, parameterMetaTypes.ptr, slotIndex);
debug writefln("D: Registered Slot has index %d", slotIndex);
_slotsByName[name] = slot;
_slotsByIndex[slotIndex] = slot;
return slot;
}
@ -53,15 +53,12 @@ public class DObject
int numArgs = cast(int)parameterMetaTypes.length;
dos_qobject_signal_create(data, rawName, numArgs, parameterMetaTypes.ptr, index);
_signalsByName[name] = signal;
_signalsByIndex[index] = signal;
return signal;
}
public void* data;
private ISlot[string] _slotsByName;
private ISlot[int] _slotsByIndex;
private ISignal[string] _signalsByName;
private ISignal[int] _signalsByIndex;
}
unittest

View File

@ -72,8 +72,6 @@ class GuiApplication
class QuickView
{
void* data;
this()
{
dos_quickview_create(data);
@ -108,12 +106,12 @@ class QuickView
immutable(char)* filenameAsCString = filename.toStringz();
dos_quickview_set_source(data, filenameAsCString);
}
private void* data;
}
class QQmlContext
{
void* data;
string baseUrl()
{
auto array = new CharArray();
@ -125,13 +123,12 @@ class QQmlContext
{
dos_qmlcontext_setcontextproperty(data, name.ptr, value.data);
}
private void* data;
}
class QVariant
{
private void* data;
private bool deleteLater = true;
this()
{
dos_qvariant_create(this.data);
@ -231,13 +228,13 @@ class QVariant
dos_qvariant_toString(this.data, array.dataRef(), array.sizeRef());
return to!(string)(array.data());
}
private void* data;
private bool deleteLater = true;
}
class CharArray
{
char* _data;
int _size;
{
this()
{
_size = 0;
@ -280,95 +277,7 @@ class CharArray
{
return _size;
}
}
/*
class QSlot
{
alias Callback = void function();
void* data;
Callback callback;
extern (C) static void staticCallback(void* dobject)
{
QSlot slot = cast(QSlot) dobject;
Callback callback = slot.getCallback();
callback();
}
this()
{
dos_qslot_create(this.data);
}
~this()
{
dos_qslot_delete(this.data);
}
Callback getCallback()
{
return this.callback;
}
void setCallback(Callback callback)
{
this.callback = callback;
dos_qslot_setcallback(this.data, cast (void*) this, &staticCallback);
}
}
class QSlot2(T)
{
void* data;
int numberOfArguments;
T* callback;
alias ReturnType!T SlotReturnType;
alias ParameterTypeTuple!T SlotArgumentsType;
extern (C) static void staticCallback(void* dobject, int numArgs, ...)
{
auto arguments = Tuple!SlotArgumentsType();
va_list ap;
version (X86_64)
va_start(ap, __va_argsave);
else version (X86)
va_start(ap, numArgs);
foreach (i, argument; arguments) {
writefln("%s: %s", i, arguments);
va_arg(ap, arguments[i]);
}
va_end(ap);
QSlot2 slot = cast(QSlot2) dobject;
T* callback = slot.getCallback();
callback(arguments.expand);
}
this(T* t)
{
this.numberOfArguments = arity!t;
this.callback = t;
dos_qslot_create(this.data);
dos_qslot_setcallback2(this.data, cast (void*) this, &staticCallback);
}
~this()
{
dos_qslot_delete(this.data);
}
T* getCallback()
{
return this.callback;
}
int getNumberOfArguments()
{
return this.numberOfArguments;
}
}
*/
private char* _data;
private int _size;
}

View File

@ -33,7 +33,7 @@ void dos_qvariant_setString(void*, immutable(char)*);
void dos_qvariant_isnull(void*, ref bool result);
void dos_qvariant_delete(void*);
void dos_qobject_create(ref void*, void* dobject, void function (void*, int, int , void**));
void dos_qobject_create(ref void*, void* dobject, void function (void*, void*, int , void**));
void dos_qobject_slot_create(void*, immutable (char)* name, int, int*, ref int);
void dos_qobject_signal_create(void*, immutable(char)* name, int, int*, ref int);
void dos_qobject_signal_emit(void*, immutable(char)* name, int, void**);

View File

@ -17,7 +17,6 @@ class MyObject : DObject
foo = registerSlot("foo", &_foo);
bar = registerSlot("bar", &_bar);
tor = registerSlot("tor", &_tor);
//complexChanged = registerSignal!(string, int, bool)("complexChanged");
}
DSlot!(void delegate(int)) foo;

View File

@ -8,7 +8,7 @@ extern "C"
typedef char* CharPtr;
typedef void(*Function)(void*);
typedef void(*DObjectCallback)(void*, int, int, void**);
typedef void(*DObjectCallback)(void*, void*, int, void**);
void dos_guiapplication_create();
void dos_guiapplication_exec();

View File

@ -134,54 +134,40 @@ int DynamicQObject::qt_metacall(QMetaObject::Call callType, int index, void** a
{
QMetaMethod method = m_metaObject->method(index);
if (!method.isValid()) return -1;
if (!method.isValid())
return -1;
DynamicSlot slot = m_slotsBySignature[method.methodSignature()];
qDebug() << "Slot" << slot.name();
if (!slot.isValid()) return -1;
int slotIndex = m_metaObject->indexOfSlot(QMetaObject::normalizedSignature(slot.signature()));
if (!slot.isValid())
return -1;
int numParametersPlusReturn = method.parameterCount() + 1;
/*
* TODO: ALLOCATE ON THE STACK AN ARRAY OF VOID* EACH ONE IS
* A POINTER TO A QVARIANT INITIALIZED WITH THE VALUE RECEIVED IN THIS METACALL.
* THEN FORWARD IT TO D.
* D THEN CAN SIMPLY CREATE SOME QVARIANT FOR THE VOID POINTERS AND USE
* THE API FOR QVARIANTS.
* THIS SOLUTION ALLOW ALSO THE D TO SET THE RETURN VALUE TO THE FIRST QVARIANT
* AND THEN WE CAN SAFELY COPY ITS VALUE THE FIRST ARGS HERE.
*
* CHANGE ALSO THE CALLBACK OF D. INFACT WE DON'T NEED ANYMORE THE METATYPES.
* BECAUSE THIS INFORMATION CAN BE DISCOVERED FROM THE QVARIANT API
*/
// Pack the slot name
QVariant slotName(slot.name());
// Pack the arguments to QVariants
std::vector<QVariant> argumentsAsVariants(numParametersPlusReturn);
std::vector<void*> argumentsAsVoidPointers(numParametersPlusReturn);
for (int i = 0; i < numParametersPlusReturn; ++i) {
int parameterType = i == 0 ? method.returnType() : method.parameterType(i - 1);
qDebug() << "C++: parameter metatype " << parameterType;
QVariant variant(parameterType, args[i]);
qDebug() << "C++ parameter value as variant " << variant.toString();
argumentsAsVariants[i] = variant;
argumentsAsVariants[i] = parameterType != QMetaType::Void ? QVariant(parameterType, args[i]) : QVariant();
argumentsAsVoidPointers[i] = &argumentsAsVariants[i];
}
// Forward values and types to D
if (m_dObjectCallback && m_dObjectPointer)
m_dObjectCallback(m_dObjectPointer, slotIndex, numParametersPlusReturn, &argumentsAsVoidPointers[0]);
m_dObjectCallback(m_dObjectPointer, &slotName, numParametersPlusReturn, &argumentsAsVoidPointers[0]);
const void* temp = argumentsAsVariants.front().constData();
QVariant temp2(method.returnType(), temp);
qDebug() << "C++: " << temp << temp2.toString();
QMetaType metatype(method.returnType());
metatype.construct(args[0], temp);
// Update the return value
if (method.returnType() != QMetaType::Void)
{
const void* returnValue = argumentsAsVariants.front().constData();
QMetaType metatype(method.returnType());
metatype.construct(args[0], returnValue);
}
return 1;
}

View File

@ -11,7 +11,7 @@ class QMetaObject;
class DynamicQObject : public QObject
{
typedef void (*Callback)(void*, int, int, void **);
typedef void (*Callback)(void*, void*, int, void **);
public:
DynamicQObject(QObject* parent = 0);