Esempio n. 1
0
static mrb_value mrb_js_obj_method_missing(mrb_state *mrb, mrb_value self)
{
    NPP npp = MRB_UD_NPP(mrb);

    mrb_value name_sym, *args;
    int len;
    mrb_get_args(mrb, "o*", &name_sym, &args, &len);
    if (mrb_type(name_sym) != MRB_TT_SYMBOL){
        return mrb_nil_value();
    }

    bool success = true;
    NPVariant empty;
    NULL_TO_NPVARIANT(empty);
    std::vector< NPVariant > var_args(len, empty);
    for (int i=0; i<len; i++){
        if (!convert_mrb_to_js(mrb, args[i], npp, &var_args[i])){
            success = false;
            break;
        }
    }

    mrb_value ret = mrb_nil_value();
    if (success){
        int name_len;
        const char *name_char = mrb_sym2name_len(mrb, SYM2ID(name_sym), &name_len);
        std::string name(name_char, name_len);
        NPIdentifier name_id = NPN_GetStringIdentifier(name.c_str());

        NPObject *obj = (NPObject *)DATA_PTR(self);
        if (NPN_HasMethod(npp, obj, name_id)){
            NPVariant result;
            NPN_Invoke(npp, obj, name_id, &var_args[0], len, &result);
            convert_js_to_mrb(npp, result, mrb, &ret);
        }else if (NPN_HasProperty(npp, obj, name_id)){
            NPVariant result;
            NPN_GetProperty(npp, obj, name_id, &result);
            convert_js_to_mrb(npp, result, mrb, &ret);
        }else if (name.size() > 1 && name[name.size() - 1] == '=' && var_args.size() == 1){
            name.resize(name.size() - 1);
            name_id = NPN_GetStringIdentifier(name.c_str());
            if (NPN_HasProperty(npp, obj, name_id)){
                NPN_SetProperty(npp, obj, name_id, &var_args[0]);
            }
        }
    }

    for (int i=0; i<len; i++){
        NPN_ReleaseVariantValue(&var_args[i]);
    }

    return ret;
}
int QtSignalForwarder::qt_metacall(QMetaObject::Call call, int index, void **args)
{
    // no support for QObject method/properties etc!
    if (!This || !This->npp || call != QMetaObject::InvokeMetaMethod
        || !This->qt.object)
        return index;

    switch (index) {
    case -1:
        {
            QString msg = *(QString*)args[1];
            NPN_Status(This->npp, msg.toLocal8Bit().constData());
        }
        break;
    default:
        {
            QObject *qobject = This->qt.object;
            if (!domNode)
                NPN_GetValue(This->npp, NPNVPluginElementNPObject, &domNode);
            if (!domNode)
                break;
            const QMetaObject *metaObject = qobject->metaObject();
            if (index < metaOffset(metaObject, MetaMethod))
                break;

            const QMetaMethod method = metaObject->method(index);
            Q_ASSERT(method.methodType() == QMetaMethod::Signal);

            QByteArray signalSignature = method.signature();
            QByteArray scriptFunction = signalSignature.left(signalSignature.indexOf('('));
            NPIdentifier id = NPN_GetStringIdentifier(scriptFunction.constData());
            if (NPN_HasMethod(This->npp, domNode, id)) {
                QList<QByteArray> parameterTypes = method.parameterTypes();
                QVector<NPVariant> parameters;
                NPVariant result;
                bool error = false;
                for (int p = 0; p < parameterTypes.count(); ++p) {
                    QVariant::Type type = QVariant::nameToType(parameterTypes.at(p));
                    if (type == QVariant::Invalid) {
                        NPN_SetException(domNode, QByteArray("Unsupported parameter type in ") + scriptFunction);
                        error = true;
                        break;
                    }
                    QVariant qvar(type, args[p + 1]);
                    NPVariant npvar = NPVariant::fromQVariant(This, qvar);
                    if (npvar.type == NPVariant::Null || npvar.type == NPVariant::Void) {
                        NPN_SetException(domNode, QByteArray("Unsupported parameter value in ") + scriptFunction);
                        error =true;
                        break;
                    }
                    parameters += npvar;
                }
                if (error)
                    break;

                NPError nperror = NPN_Invoke(This->npp, domNode, id, parameters.constData(), parameters.count(), &result);
                if (nperror != NPERR_NO_ERROR && false) { // disabled, as NPN_Invoke seems to always return GENERICERROR
                    NPN_SetException(domNode, QByteArray("Error invoking event handler ") + scriptFunction);
                }
                // ### TODO: update return value (args[0]) (out-parameters not supported anyway)
                NPN_ReleaseVariantValue(&result);
            }
        }
        break;
    }

    return index;
}