Exemplo n.º 1
0
void contextGetProperty(QQmlContext_ *context, QString_ *name, DataValue *result)
{
    QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
    const QString *qname = reinterpret_cast<QString *>(name);

    QVariant var = qcontext->contextProperty(*qname);
    packDataValue(&var, result);
}
Exemplo n.º 2
0
void objectFindChild(QObject_ *object, QString_ *name, DataValue *resultdv)
{
    QObject *qobject = reinterpret_cast<QObject *>(object);
    QString *qname = reinterpret_cast<QString *>(name);
    
    QVariant var;
    QObject *result = qobject->findChild<QObject *>(*qname);
    if (result) {
        var.setValue(result);
    }
    packDataValue(&var, resultdv);
}
Exemplo n.º 3
0
int objectGetProperty(QObject_ *object, const char *name, DataValue *result)
{
    QObject *qobject = reinterpret_cast<QObject *>(object);
    
    QVariant var = qobject->property(name);
    packDataValue(&var, result);

    if (!var.isValid() && qobject->metaObject()->indexOfProperty(name) == -1) {
            // TODO May have to check the dynamic property names too.
            return 0;
    }
    return 1;
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
void packDataValue(QVariant_ *var, DataValue *value)
{
    QVariant *qvar = reinterpret_cast<QVariant *>(var);

    // Some assumptions are made below regarding the size of types.
    // There's apparently no better way to handle this since that's
    // how the types with well defined sizes (qint64) are mapped to
    // meta-types (QMetaType::LongLong).
    switch ((int)qvar->type()) {
    case QVariant::Invalid:
        value->dataType = DTInvalid;
        break;
    case QMetaType::QUrl:
        *qvar = qvar->value<QUrl>().toString();
        // fallthrough
    case QMetaType::QString:
        {
            value->dataType = DTString;
            QByteArray ba = qvar->toByteArray();
            *(char**)(value->data) = local_strdup(ba.constData());
            value->len = ba.size();
            break;
        }
    case QMetaType::Bool:
        value->dataType = DTBool;
        *(qint8*)(value->data) = (qint8)qvar->toInt();
        break;
    case QMetaType::LongLong:
        // Some of these entries will have to be fixed when handling platforms
        // where sizeof(long long) != 8 or sizeof(int) != 4.
        value->dataType = DTInt64;
        *(qint64*)(value->data) = qvar->toLongLong();
        break;
    case QMetaType::ULongLong:
        value->dataType = DTUint64;
        *(quint64*)(value->data) = qvar->toLongLong();
        break;
    case QMetaType::Int:
        value->dataType = DTInt32;
        *(qint32*)(value->data) = qvar->toInt();
        break;
    case QMetaType::UInt:
        value->dataType = DTUint32;
        *(quint32*)(value->data) = qvar->toUInt();
        break;
    case QMetaType::VoidStar:
        value->dataType = DTUintptr;
        *(uintptr_t*)(value->data) = (uintptr_t)qvar->value<void *>();
        break;
    case QMetaType::Double:
        value->dataType = DTFloat64;
        *(double*)(value->data) = qvar->toDouble();
        break;
    case QMetaType::Float:
        value->dataType = DTFloat32;
        *(float*)(value->data) = qvar->toFloat();
        break;
    case QMetaType::QColor:
        value->dataType = DTColor;
        *(unsigned int*)(value->data) = qvar->value<QColor>().rgba();
        break;
    case QMetaType::QVariantList:
        {
            QVariantList varlist = qvar->toList();
            int len = varlist.size();
            DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
            for (int i = 0; i < len; i++) {
                packDataValue((void*)&varlist.at(i), &dvlist[i]);
            }
            value->dataType = DTValueList;
            value->len = len;
            *(DataValue**)(value->data) = dvlist;
        }
        break;
    case QMetaType::QVariantMap:
        {
            QVariantMap varmap = qvar->toMap();
            int len = varmap.size() * 2;
            DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
            QMapIterator<QString, QVariant> it(varmap);
            for (int i = 0; i < len; i += 2) {
                if (!it.hasNext()) {
                    panicf("QVariantMap mutated during iteration");
                }
                it.next();
                QVariant key = it.key();
                QVariant val = it.value();
                packDataValue((void*)&key, &dvlist[i]);
                packDataValue((void*)&val, &dvlist[i+1]);
            }
            value->dataType = DTValueMap;
            value->len = len;
            *(DataValue**)(value->data) = dvlist;
        }
        break;
    default:
        if (qvar->type() == (int)QMetaType::QObjectStar || qvar->canConvert<QObject *>()) {
            QObject *qobject = qvar->value<QObject *>();
            GoValue *goValue = dynamic_cast<GoValue *>(qobject);
            if (goValue) {
                value->dataType = DTGoAddr;
                *(void **)(value->data) = goValue->addr;
                break;
            }
            GoPaintedValue *goPaintedValue = dynamic_cast<GoPaintedValue *>(qobject);
            if (goPaintedValue) {
                value->dataType = DTGoAddr;
                *(void **)(value->data) = goPaintedValue->addr;
                break;
            }
            value->dataType = DTObject;
            *(void **)(value->data) = qobject;
            break;
        }
        {
            QQmlListReference ref = qvar->value<QQmlListReference>();
            if (ref.isValid() && ref.canCount() && ref.canAt()) {
                int len = ref.count();
                DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
                QVariant elem;
                for (int i = 0; i < len; i++) {
                    elem.setValue(ref.at(i));
                    packDataValue(&elem, &dvlist[i]);
                }
                value->dataType = DTValueList;
                value->len = len;
                *(DataValue**)(value->data) = dvlist;
                break;
            }
        }
        if (qstrncmp(qvar->typeName(), "QQmlListProperty<", 17) == 0) {
            QQmlListProperty<QObject> *list = reinterpret_cast<QQmlListProperty<QObject>*>(qvar->data());
            if (list->count && list->at) {
                int len = list->count(list);
                DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
                QVariant elem;
                for (int i = 0; i < len; i++) {
                    elem.setValue(list->at(list, i));
                    packDataValue(&elem, &dvlist[i]);
                }
                value->dataType = DTValueList;
                value->len = len;
                *(DataValue**)(value->data) = dvlist;
                break;
            }
        }
        panicf("unsupported variant type: %d (%s)", qvar->type(), qvar->typeName());
        break;
    }
}
Exemplo n.º 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;
}
Exemplo n.º 8
0
Arquivo: capi.cpp Projeto: ntcong/qml
void packDataValue(QVariant_ *var, DataValue *value)
{
    QVariant *qvar = reinterpret_cast<QVariant *>(var);

    // Some assumptions are made below regarding the size of types.
    // There's apparently no better way to handle this since that's
    // how the types with well defined sizes (qint64) are mapped to
    // meta-types (QMetaType::LongLong).
    switch ((int)qvar->type()) {
    case QVariant::Invalid:
        value->dataType = DTInvalid;
        break;
    case QMetaType::QUrl:
        *qvar = qvar->value<QUrl>().toString();
        // fallthrough
    case QMetaType::QString:
        {
            value->dataType = DTString;
            QByteArray ba = qvar->toByteArray();
            *(char**)(value->data) = local_strdup(ba.constData());
            value->len = ba.size();
            break;
        }
    case QMetaType::Bool:
        value->dataType = DTBool;
        *(qint8*)(value->data) = (qint8)qvar->toInt();
        break;
    case QMetaType::LongLong:
        value->dataType = DTInt64;
        *(qint64*)(value->data) = qvar->toLongLong();
        break;
    case QMetaType::Int:
        value->dataType = DTInt32;
        *(qint32*)(value->data) = qvar->toInt();
        break;
    case QMetaType::Double:
        value->dataType = DTFloat64;
        *(double*)(value->data) = qvar->toDouble();
        break;
    case QMetaType::Float:
        value->dataType = DTFloat32;
        *(float*)(value->data) = qvar->toFloat();
        break;
    case QMetaType::QColor:
        value->dataType = DTColor;
        *(unsigned int*)(value->data) = qvar->value<QColor>().rgba();
        break;
    case QMetaType::QVariantList:
        {
            QVariantList varlist = qvar->toList();
            int len = varlist.size();
            DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
            for (int i = 0; i < len; i++) {
                packDataValue((void*)&varlist.at(i), &dvlist[i]);
            }
            value->dataType = DTList;
            value->len = len;
            *(DataValue**)(value->data) = dvlist;
        }
        break;
    default:
        if (qvar->type() == (int)QMetaType::QObjectStar || qvar->canConvert<QObject *>()) {
            QObject *qobject = qvar->value<QObject *>();
            GoValue *govalue = dynamic_cast<GoValue *>(qobject);
            if (govalue) {
                value->dataType = DTGoAddr;
                *(void **)(value->data) = govalue->addr;
            } else {
                value->dataType = DTObject;
                *(void **)(value->data) = qobject;
            }
            break;
        }

        if (qstrncmp(qvar->typeName(), "QQmlListProperty<", 17) == 0) {
            QQmlListProperty<QObject> *list = reinterpret_cast<QQmlListProperty<QObject>*>(qvar->data());
            if (list->count && list->at) {
                int len = list->count(list);
                DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
                QVariant elem;
                for (int i = 0; i < len; i++) {
                    elem.setValue(list->at(list, i));
                    packDataValue(&elem, &dvlist[i]);
                }
                value->dataType = DTList;
                value->len = len;
                *(DataValue**)(value->data) = dvlist;
                break;
            }
        }
        panicf("unsupported variant type: %d (%s)", qvar->type(), qvar->typeName());
        break;
    }
}