static QScriptValue native_recurse(QScriptContext *ctx, QScriptEngine *eng) { QScriptValue func = ctx->argumentsObject().property(0); QScriptValue n = ctx->argumentsObject().property(1); if(n.toUInt32() <= 1) { return func.call(QScriptValue(), QScriptValueList()); } else { return eng->evaluate("native_recurse").call(QScriptValue(), QScriptValueList() << func << QScriptValue(n.toUInt32() - 1)); } }
void qColorFromScriptValue(const QScriptValue& object, QColor& color) { if (object.isNumber()) { color.setRgb(object.toUInt32()); } else if (object.isString()) { color.setNamedColor(object.toString()); } else { QScriptValue alphaValue = object.property("alpha"); color.setRgb(object.property("red").toInt32(), object.property("green").toInt32(), object.property("blue").toInt32(), alphaValue.isNumber() ? alphaValue.toInt32() : 255); } }
void ReflectiveScriptClass::setProperty( QScriptValue& object, const QScriptString & name, uint id, const QScriptValue& value) { // std::cout << __FUNCTION__ << " " << // name.toString().toStdString() << std::endl; Node_ptr node = qscriptvalue_cast< Node_ptr >(object.data()); if (node) { // Ensure it is initialized node->check_for_initialized(); ::gsim::core::descriptor_type type = node->descriptor->get_type(); if (type == ::gsim::core::TYPE_STRUCT) { // because I am sure it is initialized if (id < node->children.size()) { fromScriptValue(value, node->children[id]); } } else if (node->descriptor->is_repeated()) { if (id < node->children.size()) { fromScriptValue(value, node->children[id]); } else if (node->descriptor->is_variable_length() && QString(name) == "length") { // length property unsigned int length = value.toUInt32(); node->descriptor->set_length(node->holder, length); // re-initialized in next access node->reset(); } } } }
void xColorFromScriptValue(const QScriptValue &object, xColor& color) { if (!object.isValid()) { return; } if (object.isNumber()) { color.red = color.green = color.blue = (uint8_t)object.toUInt32(); } else if (object.isString()) { QColor qcolor(object.toString()); if (qcolor.isValid()) { color.red = (uint8_t)qcolor.red(); color.blue = (uint8_t)qcolor.blue(); color.green = (uint8_t)qcolor.green(); } } else { color.red = object.property("red").toVariant().toInt(); color.green = object.property("green").toVariant().toInt(); color.blue = object.property("blue").toVariant().toInt(); } }
void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, const QScriptValue &value) { if (type != 0) { cleanup(); type = 0; } if (callType == qMetaTypeId<QScriptValue>()) { new (&data) QScriptValue(value); type = qMetaTypeId<QScriptValue>(); } else if (callType == QMetaType::Int) { *((int *)&data) = int(value.toInt32()); type = callType; } else if (callType == QMetaType::UInt) { *((uint *)&data) = uint(value.toUInt32()); type = callType; } else if (callType == QMetaType::Bool) { *((bool *)&data) = value.toBool(); type = callType; } else if (callType == QMetaType::Double) { *((double *)&data) = double(value.toNumber()); type = callType; } else if (callType == QMetaType::Float) { *((float *)&data) = float(value.toNumber()); type = callType; } else if (callType == QMetaType::QString) { if (value.isNull() || value.isUndefined()) new (&data) QString(); else new (&data) QString(value.toString()); type = callType; } else if (callType == QMetaType::QObjectStar) { *((QObject **)&data) = value.toQObject(); type = callType; } else if (callType == qMetaTypeId<QVariant>()) { new (&data) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value)); type = callType; } else if (callType == qMetaTypeId<QList<QObject*> >()) { QList<QObject *> *list = new (&data) QList<QObject *>(); if (value.isArray()) { int length = value.property(QLatin1String("length")).toInt32(); for (int ii = 0; ii < length; ++ii) { QScriptValue arrayItem = value.property(ii); QObject *d = arrayItem.toQObject(); list->append(d); } } else if (QObject *d = value.toQObject()) { list->append(d); } type = callType; } else { new (&data) QVariant(); type = -1; QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value); if (v.userType() == callType) { *((QVariant *)&data) = v; } else if (v.canConvert((QVariant::Type)callType)) { *((QVariant *)&data) = v; ((QVariant *)&data)->convert((QVariant::Type)callType); } else { *((QVariant *)&data) = QVariant(callType, (void *)0); } } }
void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, const QScriptValue &value) { if (type != 0) { cleanup(); type = 0; } if (callType == qMetaTypeId<QScriptValue>()) { qscriptValuePtr = new (&allocData) QScriptValue(value); type = qMetaTypeId<QScriptValue>(); } else if (callType == QMetaType::Int) { intValue = quint32(value.toInt32()); type = callType; } else if (callType == QMetaType::UInt) { intValue = quint32(value.toUInt32()); type = callType; } else if (callType == QMetaType::Bool) { boolValue = value.toBool(); type = callType; } else if (callType == QMetaType::Double) { doubleValue = double(value.toNumber()); type = callType; } else if (callType == QMetaType::Float) { floatValue = float(value.toNumber()); type = callType; } else if (callType == QMetaType::QString) { if (value.isNull() || value.isUndefined()) qstringPtr = new (&allocData) QString(); else qstringPtr = new (&allocData) QString(value.toString()); type = callType; } else if (callType == QMetaType::QObjectStar) { qobjectPtr = value.toQObject(); type = callType; } else if (callType == qMetaTypeId<QVariant>()) { QVariant other = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value); qvariantPtr = new (&allocData) QVariant(other); type = callType; } else if (callType == qMetaTypeId<QList<QObject*> >()) { qlistPtr = new (&allocData) QList<QObject *>(); if (value.isArray()) { int length = value.property(QLatin1String("length")).toInt32(); for (int ii = 0; ii < length; ++ii) { QScriptValue arrayItem = value.property(ii); QObject *d = arrayItem.toQObject(); qlistPtr->append(d); } } else if (QObject *d = value.toQObject()) { qlistPtr->append(d); } type = callType; } else { qvariantPtr = new (&allocData) QVariant(); type = -1; QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine); QVariant v = priv->scriptValueToVariant(value); if (v.userType() == callType) { *qvariantPtr = v; } else if (v.canConvert((QVariant::Type)callType)) { *qvariantPtr = v; qvariantPtr->convert((QVariant::Type)callType); } else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) { QObject *obj = priv->toQObject(v); if (obj) { const QMetaObject *objMo = obj->metaObject(); while (objMo && objMo != mo) objMo = objMo->superClass(); if (!objMo) obj = 0; } *qvariantPtr = QVariant(callType, &obj); } else { *qvariantPtr = QVariant(callType, (void *)0); } } }
static void marshall_basetype(Marshall *m) { switch(m->type().element()) { case Smoke::t_bool: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (!value.isBool()) { m->item().s_bool = false; } else { m->item().s_bool = value.toBool(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), m->item().s_bool); break; default: m->unsupported(); break; } break; case Smoke::t_char: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_char = 0; } else { m->item().s_char = (char) value.toInt32(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), m->item().s_char); break; default: m->unsupported(); break; } break; case Smoke::t_uchar: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_uchar = 0; } else { m->item().s_uchar = (uchar) value.toUInt32(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), m->item().s_uchar); break; default: m->unsupported(); break; } break; case Smoke::t_short: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_short = 0; } else { m->item().s_short = (short) value.toInt32(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), m->item().s_short); break; default: m->unsupported(); break; } break; case Smoke::t_ushort: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_ushort = 0; } else { m->item().s_ushort = value.toUInt16(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), m->item().s_ushort); break; default: m->unsupported(); break; } break; case Smoke::t_int: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_int = 0; } else { m->item().s_int = value.toInt32(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), m->item().s_int); break; default: m->unsupported(); break; } break; case Smoke::t_uint: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_uint = 0; } else { m->item().s_uint = value.toUInt32(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), m->item().s_uint); break; default: m->unsupported(); break; } break; case Smoke::t_long: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_long = 0; } else { m->item().s_long = (long) value.toInt32(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), (int) m->item().s_long); break; default: m->unsupported(); break; } break; case Smoke::t_ulong: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_ulong = 0; } else { m->item().s_ulong = (ulong) value.toUInt32(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), (uint) m->item().s_ulong); break; default: m->unsupported(); break; } break; case Smoke::t_float: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_float = 0.0; } else { m->item().s_float = (float) value.toNumber(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), m->item().s_float); break; default: m->unsupported(); break; } break; case Smoke::t_double: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_double = 0.0; } else { m->item().s_double = value.toNumber(); } break; } case Marshall::ToQScriptValue: *(m->var()) = QScriptValue(m->engine(), m->item().s_double); break; default: m->unsupported(); break; } break; case Smoke::t_enum: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_enum = 0; } else if (value.instanceOf(JSmoke::Global::QtEnum)) { m->item().s_enum = value.property("value").toUInt32(); } else { m->item().s_enum = value.toUInt32(); } break; } case Marshall::ToQScriptValue: { QScriptValueList args; args << (uint) m->item().s_enum << m->type().name(); *(m->var()) = JSmoke::Global::QtEnum.call(QScriptValue(), args); break; } default: m->unsupported(); break; } break; case Smoke::t_class: switch(m->action()) { case Marshall::FromQScriptValue: { QScriptValue value = *(m->var()); if (value.isNull()) { m->item().s_class = 0; return; } if (value.isDate()) { Smoke::ModuleIndex classId = Smoke::findClass(m->smoke()->classes[m->type().classId()].className); if (classId == JSmoke::Global::QDateClassId) { m->item().s_class = new QDate(value.toDateTime().date()); } else if (classId == JSmoke::Global::QDateTimeClassId) { m->item().s_class = new QDateTime(value.toDateTime()); } else if (classId == JSmoke::Global::QTimeClassId) { m->item().s_class = new QTime(value.toDateTime().time()); } else { m->item().s_class = 0; } return; } else if (value.isRegExp()) { m->item().s_class = new QRegExp(value.toRegExp()); return; } if (!Object::Instance::isSmokeObject(value)) { m->item().s_class = 0; return; } Object::Instance * instance = Object::Instance::get(value); void * ptr = instance->value; if (!m->cleanup() && m->type().isStack()) { ptr = constructCopy(instance); } ptr = instance->classId.smoke->cast( ptr, instance->classId, Smoke::ModuleIndex(m->smoke(), m->type().classId()) ); m->item().s_class = ptr; break; } case Marshall::ToQScriptValue: { if (m->item().s_voidp == 0) { *(m->var()) = m->engine()->nullValue(); return; } void * ptr = m->item().s_voidp; QScriptValue * value = JSmoke::Global::getScriptValue(ptr); if (value != 0) { *(m->var()) = *value; return ; } QByteArray className(m->smoke()->classes[m->type().classId()].className); QScriptValue obj = Global::wrapInstance( m->engine(), Smoke::findClass(className), ptr, QScriptEngine::QtOwnership ); if (m->type().isConst() && m->type().isRef()) { Object::Instance * instance = Object::Instance::get(obj); ptr = constructCopy(instance); if (ptr != 0) { instance->value = ptr; instance->ownership = QScriptEngine::ScriptOwnership; Global::mapPointer(new QScriptValue(obj), instance, instance->classId); } } *(m->var()) = obj; break; } default: m->unsupported(); break; } break; default: m->unsupported(); break; } }
void ReflectiveScriptClass::fromScriptValue( const QScriptValue& value, Node_ptr node) { // std::cout << __FUNCTION__ << std::endl; using namespace gsim::core; const descriptor_type type = node->descriptor->get_type(); node->check_for_initialized(); holder& hold = node->holder; descriptor_base const * descriptor = node->descriptor; switch(type) { case TYPE_STRUCT: { if (value.isObject()) { unsigned int count = node->descriptor->get_children_count(); // Search by name for (unsigned int i = 0; i < count; i++) { const char *childName = descriptor->get_child_name(i); QScriptValue childValue = value.property(childName); if (childValue.isValid()) fromScriptValue(childValue, node->children[i]); } } else { std::cerr << "Must be an object!" << std::endl; } } break; case TYPE_ARRAY: if (descriptor->get_slice()->get_type() == TYPE_CHAR) { const std::string str(value.toString().toStdString()); descriptor->from_string(hold, str); break; } case TYPE_SEQUENCE: { unsigned int length = descriptor->get_length(hold); unsigned int newLength = value.property("length").toUInt32(); if (descriptor->is_variable_length() && length != newLength) { descriptor->set_length(hold, newLength); node->reset(); node->check_for_initialized(); } for (unsigned int i = 0; i < newLength && i < length; i++) { fromScriptValue(value.property(i), node->children[i]); } } break; case TYPE_BOOL: hold.to_value< bool >() = value.toBool(); break; case TYPE_OCTET: hold.to_value< unsigned char >() = value.toInteger(); break; case TYPE_CHAR: hold.to_value< char >() = value.toInteger(); break; case TYPE_SHORT: hold.to_value< short >() = value.toInteger(); break; case TYPE_USHORT: hold.to_value< unsigned short >() = value.toUInt16(); break; case TYPE_LONG: hold.to_value< int32_t >() = value.toInteger(); break; case TYPE_ULONG: hold.to_value< uint32_t >() = value.toUInt32(); break; case TYPE_LONGLONG: hold.to_value< int64_t >() = value.toInteger(); break; case TYPE_ULONGLONG: hold.to_value< uint64_t >() = value.toInteger(); break; case TYPE_STRING: case TYPE_WSTRING: { const std::string str(value.toString().toStdString()); descriptor->from_string(hold, str); } break; case TYPE_ENUM: { const unsigned int count = descriptor->get_children_count(); const QString str (value.toString()); unsigned int idx = descriptor->get_child_index( str.toStdString().c_str()); if (idx < count) { core::holder tmp( descriptor->get_child_value(hold, idx)); descriptor->copy(tmp, hold); } // TODO debería devolverse excepción si se introdujo // un literal no válido. } break; case TYPE_DOUBLE: hold.to_value< double >() = value.toNumber(); break; case TYPE_FLOAT: hold.to_value< float >() = value.toNumber(); default: break; } }
QScriptValue ScShiftDatabase::addType(QScriptContext *ctx, QScriptEngine *engine) { ScProfileFunction SProperty **propPtr = getThis(ctx); SDatabase *db = 0; if(propPtr) { db = (*propPtr)->uncheckedCastTo<SDatabase>(); } if(!db) { ctx->throwError(QScriptContext::SyntaxError, "Incorrect this argument to SPropertyContainer.size(...);"); } if(ctx->argumentCount() != 1) { ctx->throwError(QScriptContext::SyntaxError, "Incorrect number of arguments to SDatabase.addType(...);"); return QScriptValue(); } QScriptValue typeObject = ctx->argument(0); if(!typeObject.isObject()) { ctx->throwError(QScriptContext::SyntaxError, "Incorrect argument type to SDatabase.addType(...); expected object"); return QScriptValue(); } QScriptValue tempObject; tempObject = typeObject.property("name"); QString name = tempObject.toString(); if(name == "" || STypeRegistry::findType(name) != 0) { ctx->throwError(QScriptContext::SyntaxError, "Unique, non zero-lengthed string expected as 'name' property"); return QScriptValue(); } tempObject = typeObject.property("parent"); const SPropertyInformation *parent = 0; if(tempObject.isString()) { parent = STypeRegistry::findType(tempObject.toString()); } if(parent == 0) { ctx->throwError(QScriptContext::SyntaxError, "Defined property type expected as 'parent' property"); return QScriptValue(); } tempObject = typeObject.property("version"); xuint32 version = tempObject.toUInt32(); xsize endOfUsedMemory = parent->dynamicSize(); QList<SPropertyInstanceInformation*> properties; tempObject = typeObject.property("properties"); if(tempObject.isArray()) { xuint32 i = 0; QScriptValue val = tempObject.property(i); QScriptValue tempArrayObject; while(val.isObject()) { tempArrayObject = val.property("name"); if(!tempArrayObject.isString()) { ctx->throwError(QScriptContext::SyntaxError, "String expected as 'properties' array 'name' entry"); break; } QString propName = tempArrayObject.toString(); tempArrayObject = val.property("type"); const SPropertyInformation *propType = 0; if(tempArrayObject.isString()) { propType = STypeRegistry::findType(tempArrayObject.toString()); } if(!propType) { ctx->throwError(QScriptContext::SyntaxError, "String expected as 'properties' array 'type' entry"); break; } SPropertyInstanceInformation::ComputeFunction computeFn = 0; tempArrayObject = val.property("compute"); if(tempArrayObject.isFunction()) { computeFn = computeNode; } SPropertyInstanceInformation *info = propType->createInstanceInformation()(propType, propName, i, *reinterpret_cast<SProperty SPropertyContainer::**>(&endOfUsedMemory)); info->setCompute(computeFn); info->setExtra(true); endOfUsedMemory += propType->size(); properties << info; if(computeFn) { info->setData(g_computeKey, qVariantFromValue(tempArrayObject)); } val = tempObject.property(++i); } i = 0; val = tempObject.property(i); while(val.isObject()) { SProperty SPropertyContainer::* *affects = 0; tempArrayObject = val.property("affects"); bool affectsIsValid = false; if(tempArrayObject.isArray()) { affectsIsValid = true; xuint32 length = tempArrayObject.property("length").toUInt32(); affects = new SProperty SPropertyContainer::* [length+1]; affects[length] = 0; for(xuint32 i=0; i<length; ++i) { affects[i] = 0; QString name = tempArrayObject.property(i).toString(); for(int propIdx=0, s=properties.size(); propIdx<s; ++propIdx) { if(name == properties[propIdx]->name()) { affects[i] = properties[propIdx]->location(); break; } } if(!affects[i]) { affectsIsValid = false; ctx->throwError(QScriptContext::SyntaxError, "Defined sibling property name expected for affectedBy members."); break; } } } if(!affectsIsValid) { delete [] affects; affects = 0; } SPropertyInstanceInformation *info = properties[i]; info->setAffects(affects); val = tempObject.property(++i); } } #warning check what happens if you embed a script type in a script type... etc, i think it will crash and burn? SPropertyInformation *newType = new SPropertyInformation(*parent); newType->setVersion(version); newType->typeName() = name; newType->setParentTypeInformation(parent); newType->setSize(endOfUsedMemory); newType->children() << parent->children() << properties; STypeRegistry::addType(newType); return QScriptValue(); }
void Color::fromScriptValue(const QScriptValue &object) { // red component QScriptValue value = object.property("r"); if ((!value.isValid()) || (value.isUndefined())) { // property is not valid or Undefined. set to 0, not the default NaN m_r = 0; } else { // convert to unsigned integer quint32 r = value.toUInt32(); if (r > MAX_COLOR_VALUE) { // clip value m_r = MAX_COLOR_VALUE; } else { m_r = r; } } // green component value = object.property("g"); if ((!value.isValid()) || (value.isUndefined())) { // property is not valid or Undefined. set to 0, not the default NaN m_g = 0; } else { // convert to unsigned integer quint32 g = value.toUInt32(); if (g > MAX_COLOR_VALUE) { // clip value m_g = MAX_COLOR_VALUE; } else { m_g = g; } } // blue component value = object.property("b"); if ((!value.isValid()) || (value.isUndefined())) { // property is Undefined. set to 0, not the default NaN m_b = 0; } else { // convert to unsigned integer quint32 b = value.toUInt32(); if (b > MAX_COLOR_VALUE) { // clip value m_b = MAX_COLOR_VALUE; } else { m_b = b; } } }