Beispiel #1
0
QVariantList_ *newVariantList(DataValue *list, int len)
{
    QVariantList *vlist = new QVariantList();
    vlist->reserve(len);
    for (int i = 0; i < len; i++) {
        QVariant var;
        unpackDataValue(&list[i], &var);
        vlist->append(var);
    }
    return vlist;
}
Beispiel #2
0
error *objectInvoke(QObject_ *object, const char *method, int methodLen, DataValue *resultdv, DataValue *paramsdv, int paramsLen)
{
    QObject *qobject = reinterpret_cast<QObject *>(object);

    QVariant result;
    QVariant param[MaxParams];
    QGenericArgument arg[MaxParams];
    for (int i = 0; i < paramsLen; i++) {
        unpackDataValue(&paramsdv[i], &param[i]);
        arg[i] = Q_ARG(QVariant, param[i]);
    }
    if (paramsLen > 10) {
        panicf("fix the parameter dispatching");
    }

    const QMetaObject *metaObject = qobject->metaObject();
    // Walk backwards so descendants have priority.
    for (int i = metaObject->methodCount()-1; i >= 0; i--) {
        QMetaMethod metaMethod = metaObject->method(i);
        QMetaMethod::MethodType methodType = metaMethod.methodType();
        if (methodType == QMetaMethod::Method || methodType == QMetaMethod::Slot) {
            QByteArray name = metaMethod.name();
            if (name.length() == methodLen && qstrncmp(name.constData(), method, methodLen) == 0) {
                if (metaMethod.parameterCount() < paramsLen) {
                    // TODO Might continue looking to see if a different signal has the same name and enough arguments.
                    return errorf("method \"%s\" has too few parameters for provided arguments", method);
                }

                bool ok;
                if (metaMethod.returnType() == QMetaType::Void) {
                    ok = metaMethod.invoke(qobject, Qt::DirectConnection, 
                        arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]);
                } else {
                    ok = metaMethod.invoke(qobject, Qt::DirectConnection, Q_RETURN_ARG(QVariant, result),
                        arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]);
                }
                if (!ok) {
                    return errorf("invalid parameters to method \"%s\"", method);
                }

                packDataValue(&result, resultdv);
                return 0;
            }
        }
    }

    return errorf("object does not expose a method \"%s\"", method);
}
Beispiel #3
0
error *objectSetProperty(QObject_ *object, const char *name, DataValue *value)
{
    QObject *qobject = reinterpret_cast<QObject *>(object);
    QVariant var;
    unpackDataValue(value, &var);

    // Give qvalue an engine reference if it doesn't yet have one.
    QObject *obj = var.value<QObject *>();
    if (obj && !qmlEngine(obj)) {
        QQmlContext *context = qmlContext(qobject);
        if (context) {
            QQmlEngine::setContextForObject(obj, context);
        }
    }

    // Check that the types are compatible. There's probably more to be done here.
    const QMetaObject *metaObject = qobject->metaObject();
    int propIndex = metaObject->indexOfProperty(name);
    if (propIndex == -1) {
            return errorf("cannot set non-existent property \"%s\" on type %s", name, qobject->metaObject()->className());
    }

    QMetaProperty prop = metaObject->property(propIndex);
    int propType = prop.userType();
    void *valueArg;
    if (propType == QMetaType::QVariant) {
        valueArg = (void *)&var;
    } else {
        int varType = var.userType();
        QVariant saved = var;
        if (propType != varType && !var.convert(propType)) {
            if (varType == QMetaType::QObjectStar) {
                return errorf("cannot set property \"%s\" with type %s to value of %s*",
                        name, QMetaType::typeName(propType), saved.value<QObject*>()->metaObject()->className());
            } else {
                return errorf("cannot set property \"%s\" with type %s to value of %s",
                        name, QMetaType::typeName(propType), QMetaType::typeName(varType));
            }
        }
        valueArg = (void *)var.constData();
    }

    int status = -1;
    int flags = 0;
    void *args[] = {valueArg, 0, &status, &flags};
    QMetaObject::metacall(qobject, QMetaObject::WriteProperty, propIndex, args);
    return 0;
}
Beispiel #4
0
void contextSetProperty(QQmlContext_ *context, QString_ *name, DataValue *value)
{
    const QString *qname = reinterpret_cast<QString *>(name);
    QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);

    QVariant var;
    unpackDataValue(value, &var);

    // Give qvalue an engine reference if it doesn't yet have one .
    QObject *obj = var.value<QObject *>();
    if (obj && !qmlEngine(obj)) {
        QQmlEngine::setContextForObject(obj, qcontext);
    }

    qcontext->setContextProperty(*qname, var);
}
Beispiel #5
0
void objectSetProperty(QObject_ *object, const char *name, DataValue *value)
{
    QObject *qobject = reinterpret_cast<QObject *>(object);
    QVariant var;
    unpackDataValue(value, &var);

    // Give qvalue an engine reference if it doesn't yet have one.
    QObject *obj = var.value<QObject *>();
    if (obj && !qmlEngine(obj)) {
        QQmlContext *context = qmlContext(qobject);
        if (context) {
            QQmlEngine::setContextForObject(obj, context);
        }
    }

    qobject->setProperty(name, var);
}
Beispiel #6
0
int GoValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
{
    //qWarning() << "GoValueMetaObject::metaCall" << c << idx;
    switch (c) {
    case QMetaObject::ReadProperty:
    case QMetaObject::WriteProperty:
        {
            // TODO Cache propertyOffset, methodOffset (and maybe qmlEngine)
            int propOffset = propertyOffset();
            if (idx < propOffset) {
                return value->qt_metacall(c, idx, a);
            }
            GoMemberInfo *memberInfo = typeInfo->fields;
            for (int i = 0; i < typeInfo->fieldsLen; i++) {
                if (memberInfo->metaIndex == idx) {
                    if (c == QMetaObject::ReadProperty) {
                        DataValue result;
                        hookGoValueReadField(qmlEngine(value), ref, memberInfo->reflectIndex, memberInfo->reflectGetIndex, memberInfo->reflectSetIndex, &result);
                        if (memberInfo->memberType == DTListProperty) {
                            if (result.dataType != DTListProperty) {
                                panicf("reading DTListProperty field returned non-DTListProperty result");
                            }
                            QQmlListProperty<QObject> *in = *reinterpret_cast<QQmlListProperty<QObject> **>(result.data);
                            QQmlListProperty<QObject> *out = reinterpret_cast<QQmlListProperty<QObject> *>(a[0]);
                            *out = *in;
                            // TODO Could provide a single variable in the stack to ReadField instead.
                            delete in;
                        } else {
                            QVariant *out = reinterpret_cast<QVariant *>(a[0]);
                            unpackDataValue(&result, out);
                        }
                    } else {
                        DataValue assign;
                        QVariant *in = reinterpret_cast<QVariant *>(a[0]);
                        packDataValue(in, &assign);
                        hookGoValueWriteField(qmlEngine(value), ref, memberInfo->reflectIndex, memberInfo->reflectSetIndex, &assign);
                        activate(value, methodOffset() + (idx - propOffset), 0);
                    }
                    return -1;
                }
                memberInfo++;
            }
            QMetaProperty prop = property(idx);
            qWarning() << "Property" << prop.name() << "not found!?";
            break;
        }
    case QMetaObject::InvokeMetaMethod:
        {
            if (idx < methodOffset()) {
                return value->qt_metacall(c, idx, a);
            }
            GoMemberInfo *memberInfo = typeInfo->methods;
            for (int i = 0; i < typeInfo->methodsLen; i++) {
                if (memberInfo->metaIndex == idx) {
                    // args[0] is the result if any.
                    DataValue args[1 + MaxParams];
                    for (int i = 1; i < memberInfo->numIn+1; i++) {
                        packDataValue(reinterpret_cast<QVariant *>(a[i]), &args[i]);
                    }
                    hookGoValueCallMethod(qmlEngine(value), ref, memberInfo->reflectIndex, args);
                    if (memberInfo->numOut > 0) {
                        unpackDataValue(&args[0], reinterpret_cast<QVariant *>(a[0]));
                    }
                    return -1;
                }
                memberInfo++;
            }
            QMetaMethod m = method(idx);
            qWarning() << "Method" << m.name() << "not found!?";
            break;
        }
    default:
        break; // Unhandled.
    }
    return -1;
}
Beispiel #7
0
int GoValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
{
    switch (c) {
    case QMetaObject::ReadProperty:
    case QMetaObject::WriteProperty:
        {
            // TODO Cache propertyOffset, methodOffset, and qmlEngine results?
            if (idx < propertyOffset()) {
                return value->qt_metacall(c, idx, a);
            }
            GoMemberInfo *memberInfo = valuePriv->typeInfo->fields;
            for (int i = 0; i < valuePriv->typeInfo->fieldsLen; i++) {
                if (memberInfo->metaIndex == idx) {
                    if (c == QMetaObject::ReadProperty) {
                        DataValue result;
                        hookGoValueReadField(qmlEngine(value), valuePriv->addr, memberInfo->reflectIndex, &result);
                        QVariant *out = reinterpret_cast<QVariant *>(a[0]);
                        unpackDataValue(&result, out);
                    } else {
                        DataValue assign;
                        QVariant *in = reinterpret_cast<QVariant *>(a[0]);
                        packDataValue(in, &assign);
                        hookGoValueWriteField(qmlEngine(value), valuePriv->addr, memberInfo->reflectIndex, &assign);
                    }
                    return -1;
                }
                memberInfo++;
            }
            QMetaProperty prop = property(idx);
            qWarning() << "Property" << prop.name() << "not found!?";
            break;
        }
    case QMetaObject::InvokeMetaMethod:
        {
            if (idx < methodOffset()) {
                return value->qt_metacall(c, idx, a);
            }
            GoMemberInfo *memberInfo = valuePriv->typeInfo->methods;
            for (int i = 0; i < valuePriv->typeInfo->methodsLen; i++) {
                if (memberInfo->metaIndex == idx) {
                    // args[0] is the result if any.
                    DataValue args[1 + MaxParams];
                    for (int i = 1; i < memberInfo->numIn+1; i++) {
                        packDataValue(reinterpret_cast<QVariant *>(a[i]), &args[i]);
                    }
                    hookGoValueCallMethod(qmlEngine(value), valuePriv->addr, memberInfo->reflectIndex, args);
                    if (memberInfo->numOut > 0) {
                        unpackDataValue(&args[0], reinterpret_cast<QVariant *>(a[0]));
                    }
                    return -1;
                }
                memberInfo++;
            }
            QMetaMethod m = method(idx);
            qWarning() << "Method" << m.name() << "not found!?";
            break;
        }
    default:
        break; // Unhandled.
    }
    return -1;
}