Ejemplo n.º 1
0
void marshal_from_sexp<SmokeClassWrapper>(MethodCall *m)
{
  SEXP v = m->sexp();
  SmokeType type = m->type();
  SmokeObject *o = NULL /*, *coerced = NULL */;

  /* Not clear if we want to (partially) support this complicated C++ feature
  if (v != R_NilValue) {
    o = SmokeObject::fromSexp(v);
    if (!o->instanceOf(type.className())) {
      // attempt implicit conversion
      coerced = o->convertImplicitly(type);
      if (coerced)
        o = coerced;
      else error("Failed to coerce an instance of type '%s' to '%s'",
                 o->className(), type.className());
    }
  }
  */
  
  o = from_sexp<SmokeObject *>(v, type);
  void *ptr = o ? o->castPtr(type.className(),
                             m->returning() && !type.fitsStack()) : NULL;
  setItemValue(m, ptr);

  /*
  m->marshal();

  if (coerced)
    delete coerced;
  */
  
  return;
}
Ejemplo n.º 2
0
void *_unwrapSmoke(SEXP x, const char *type) {
  void *ans = NULL;
  if (!isNull(x)) {
    SmokeObject *so = SmokeObject::fromSexp(x);
    if (so)
      ans = so->castPtr(type);
  }
  return ans;
}
Ejemplo n.º 3
0
extern "C" SEXP qt_qmetaInvoke(SEXP x, SEXP s_id, SEXP s_args) {
  SmokeObject *so = SmokeObject::fromSexp(x);
  int id = from_sexp<int>(s_id);
  QObject * qobj = reinterpret_cast<QObject *>(so->castPtr("QObject"));
  MocMethod method(so->smoke(), qobj->metaObject(), id);
  SEXP ret = method.invoke(x, s_args);
  if (method.lastError() > Method::NoError)
    error("Meta method invocation failed for: '%s::%s'", so->klass()->name(),
          method.name());
  return ret;
}
Ejemplo n.º 4
0
/* We catch all qt_metacall invocations */
extern "C" SEXP qt_qmetacall(SEXP x, SEXP s_call, SEXP s_id, SEXP s_args)
{
  SmokeObject *so = SmokeObject::fromSexp(x);
  QMetaObject::Call call =
    enum_from_sexp<QMetaObject::Call>(s_call, SmokeType());
  int id = from_sexp<int>(s_id);
  void **args = reinterpret_cast<void **>(from_sexp<void *>(s_args));
  
  // Assume the target slot is a C++ one
  Smoke::StackItem i[4];
  i[1].s_enum = call;
  i[2].s_int = id;
  i[3].s_voidp = args;
  so->invokeMethod("qt_metacall$$?", i);
  int ret = i[0].s_int;
  if (ret < 0) {
    return ScalarInteger(ret);
  }

  if (call != QMetaObject::InvokeMetaMethod)
    return ScalarInteger(id);

  QObject * qobj = reinterpret_cast<QObject *>(so->castPtr("QObject"));
  // get obj metaobject with a virtual call
  const QMetaObject *metaobject = qobj->metaObject();
  
  // get method count
  int count = metaobject->methodCount();
  
  QMetaMethod method = metaobject->method(id);
  if (method.methodType() == QMetaMethod::Signal) {
    // FIXME: this override of 'activate' is obsolete
    metaobject->activate(qobj, id, (void**) args);
    return ScalarInteger(id - count);
  }
  DynamicBinding binding(MocMethod(so->smoke(), metaobject, id));
  QVector<SmokeType> stackTypes = binding.types();
  MocStack mocStack = MocStack(args, stackTypes.size());
  SmokeStack smokeStack = mocStack.toSmoke(stackTypes);
  binding.invoke(so, smokeStack.items());
  mocStack.returnFromSmoke(smokeStack, stackTypes[0]);
  if (binding.lastError() == Method::NoError)
    warning("Slot invocation failed for %s::%s", so->klass()->name(),
            binding.name());
  
  return ScalarInteger(id - count);
}
Ejemplo n.º 5
0
Method*
MocClass::findMethod(const MethodCall& call) const {
  Method *method = _delegate->findMethod(call);
  if (method)
    return(method);
  SmokeObject *o = call.target();
  /* only QObjects have meta methods */
  if (o && o->ptr() && o->instanceOf("QObject") && o->klass() == this) {
    /* unwrap the call */
    QObject * qobject = reinterpret_cast<QObject *>(o->castPtr("QObject"));
    const QMetaObject * meta = qobject->metaObject();
    /* get the method id */
    int id = findMethodId(o->smoke(), meta, call.method()->name(), call.args());
    if (id >= 0)
      method = new MocMethod(o->smoke(), meta, id);
  }
  return method;
}
Ejemplo n.º 6
0
QVariant qvariant_from_sexp(SEXP rvalue, int index) {
  QVariant variant;
  if (index == -1) {
    /* If a particular element is not selected, then non-lists of
       length one are considered scalars. Otherwise, collections.
       Except for raw vectors, which are naturally QByteArrays.
    */
    if (TYPEOF(rvalue) == RAWSXP)
      return QVariant(from_sexp<QByteArray>(rvalue));
    else if (TYPEOF(rvalue) == VECSXP || length(rvalue) > 1) {
      SEXP rlist = coerceVector(rvalue, VECSXP);
      if (getAttrib(rvalue, R_NamesSymbol) != R_NilValue)
        variant = asQVariantOfType(rlist, QMetaType::QVariantMap);
      else variant = asQVariantOfType(rlist, QMetaType::QVariantList);
      return variant;
    }
    index = 0;
  }
  switch(TYPEOF(rvalue)) {
  case RAWSXP:
    variant = qVariantFromValue(RAW(rvalue)[index]);
    break;
  case LGLSXP:
    // Rprintf("Logical\n");
    // FIXME: by converting to 'bool' all NA become TRUE
    variant = QVariant((bool)LOGICAL(rvalue)[index]);
    break;
  case REALSXP:
    // Rprintf("Real\n");
    variant = QVariant(REAL(rvalue)[index]);
    break;
  case INTSXP:
    // Rprintf("Integer\n");
    {
      SEXP levels;
      if ((levels = getAttrib(rvalue, R_LevelsSymbol)) != R_NilValue) {
        int level = INTEGER(rvalue)[index];
        SEXP level_str = NA_STRING;
        /*Rprintf("getting level: %d\n", level);*/
        if (level != NA_INTEGER)
          level_str = STRING_ELT(levels, level - 1);
        variant = QVariant(sexp2qstring(level_str));
      } else variant = QVariant(INTEGER(rvalue)[index]);
      break;
    }
  case STRSXP:
    // Rprintf("String\n");
    variant = QVariant(sexp2qstring(STRING_ELT(rvalue, index)));
    break;
  case EXTPTRSXP:
    // Rprintf("External pointer\n");
    variant = qVariantFromValue(unwrapPointer(rvalue, void));
    break;
  case VECSXP:
    variant = from_sexp<QVariant>(VECTOR_ELT(rvalue, index));
    break;
  case ENVSXP: {
    SmokeObject *so = SmokeObject::fromSexp(rvalue);
    if (so->instanceOf("QWidget"))
      variant =
        qVariantFromValue(reinterpret_cast<QWidget *>(so->castPtr("QWidget")));
    else if (so->instanceOf("QObject"))
      variant =
        qVariantFromValue(reinterpret_cast<QObject *>(so->castPtr("QObject")));
    else {
      QMetaType::Type type = (QMetaType::Type) QMetaType::type(so->className());
      if (type)
        variant = asQVariantOfType(rvalue, type, false);
      else variant = qVariantFromValue(so->ptr());
    }
  }
    break;
  case NILSXP: // invalid QVariant
    break;
  default:
    error("Converting to QVariant: unhandled R type");
  }
  return variant;
}