79void QQmlOpenMetaObjectType::createProperties(
const QVector<QByteArray> &names)
81 for (
int i = 0; i < names.size(); ++i) {
82 const QByteArray &name = names.at(i);
83 const int id = d->mob.propertyCount();
84 d->mob.addSignal(
"__" + QByteArray::number(id) +
"()");
85 QMetaPropertyBuilder build = d->mob.addProperty(name,
"QVariant", id);
86 propertyCreated(id, build);
87 d->names.insert(name, id);
90 d->mem = d->mob.toMetaObject();
91 QSet<QQmlOpenMetaObject*>::iterator it = d->referers.begin();
92 while (it != d->referers.end()) {
93 QQmlOpenMetaObject *omo = *it;
94 *
static_cast<QMetaObject *>(omo) = *d->mem;
96 d->cache->update(omo);
101int QQmlOpenMetaObjectType::createProperty(
const QByteArray &name)
103 const int signalIdx = d->mob.addSignal(
104 "__" + QByteArray::number(d->mob.propertyCount()) +
"()").index();
105 QMetaPropertyBuilder build = d->mob.addProperty(name,
"QVariant", signalIdx);
106 propertyCreated(build.index(), build);
108 d->mem = d->mob.toMetaObject();
109 d->names.insert(name, build.index());
110 QSet<QQmlOpenMetaObject*>::iterator it = d->referers.begin();
111 while (it != d->referers.end()) {
112 QQmlOpenMetaObject *omo = *it;
113 *
static_cast<QMetaObject *>(omo) = *d->mem;
115 d->cache->update(omo);
119 return d->propertyOffset + build.index();
122void QQmlOpenMetaObjectType::propertyCreated(
int id, QMetaPropertyBuilder &builder)
131 mob.setSuperClass(metaObj);
132 mob.setClassName(metaObj->className());
133 mob.setFlags(MetaObjectFlag::DynamicMetaObject);
135 mem = mob.toMetaObject();
137 propertyOffset = mem->propertyOffset();
138 signalOffset = mem->methodOffset();
222QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj,
const QMetaObject *base)
223: d(
new QQmlOpenMetaObjectPrivate(
this, obj))
225 d->type.adopt(
new QQmlOpenMetaObjectType(base ? base : obj->metaObject()));
226 d->type->d->referers.insert(
this);
228 QObjectPrivate *op = QObjectPrivate::get(obj);
229 d->parent = op->metaObject;
230 *
static_cast<QMetaObject *>(
this) = *d->type->d->mem;
231 op->metaObject =
this;
234QQmlOpenMetaObject::QQmlOpenMetaObject(
235 QObject *obj,
const QQmlRefPointer<QQmlOpenMetaObjectType> &type)
236: d(
new QQmlOpenMetaObjectPrivate(
this, obj))
239 d->type->d->referers.insert(
this);
241 QObjectPrivate *op = QObjectPrivate::get(obj);
242 d->parent = op->metaObject;
243 *
static_cast<QMetaObject *>(
this) = *d->type->d->mem;
244 op->metaObject =
this;
260void QQmlOpenMetaObject::emitPropertyNotification(
const QByteArray &propertyName)
262 QHash<QByteArray,
int>::ConstIterator iter = d->type->d->names.constFind(propertyName);
263 if (iter == d->type->d->names.constEnd())
265 activate(d->object, *iter + d->type->d->signalOffset,
nullptr);
273int QQmlOpenMetaObject::metaCall(QObject *o, QMetaObject::Call c,
int id,
void **a)
275 Q_ASSERT(d->object == o);
277 if (( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty)
278 && id >= d->type->d->propertyOffset) {
279 int propId = id - d->type->d->propertyOffset;
280 if (c == QMetaObject::ReadProperty) {
281 propertyRead(propId);
282 *
reinterpret_cast<QVariant *>(a[0]) = d->propertyValue(propId);
283 }
else if (c == QMetaObject::WriteProperty) {
284 if (propId >= d->data.size() || d->data.at(propId).value() != *
reinterpret_cast<QVariant *>(a[0])) {
285 propertyWrite(propId);
286 d->setPropertyValue(propId, propertyWriteValue(propId, *
reinterpret_cast<QVariant *>(a[0])));
287 propertyWritten(propId);
288 activate(o, d->type->d->signalOffset + propId,
nullptr);
294 return d->parent->metaCall(o, c, id, a);
296 return o->qt_metacall(c, id, a);
305bool QQmlOpenMetaObject::checkedSetValue(
int index,
const QVariant &value,
bool force)
307 if (!force && d->propertyValue(index) == value)
310 d->setPropertyValue(index, value);
311 activate(d->object, index + d->type->d->signalOffset,
nullptr);
320void QQmlOpenMetaObject::setValue(
int id,
const QVariant &value)
322 d->setPropertyValue(id, propertyWriteValue(id, value));
323 activate(d->object, id + d->type->d->signalOffset,
nullptr);
343bool QQmlOpenMetaObject::setValue(
const QByteArray &name,
const QVariant &val,
bool force)
345 QHash<QByteArray,
int>::ConstIterator iter = d->type->d->names.constFind(name);
348 if (iter == d->type->d->names.cend()) {
349 id = createProperty(name.constData(),
"") - d->type->d->propertyOffset;
355 return checkedSetValue(id, val, force);
360void QQmlOpenMetaObject::setValues(
const QHash<QByteArray, QVariant> &values,
bool force)
362 QVector<QByteArray> missingProperties;
363 d->deferredPropertyNames = &missingProperties;
364 const auto &names = d->type->d->names;
366 for (
auto valueIt = values.begin(), end = values.end(); valueIt != end; ++valueIt) {
367 const auto nameIt = names.constFind(valueIt.key());
368 if (nameIt == names.constEnd()) {
369 const int id = createProperty(valueIt.key(),
"") - d->type->d->propertyOffset;
376 checkedSetValue(id, valueIt.value(), force);
378 checkedSetValue(*nameIt, valueIt.value(), force);
382 d->deferredPropertyNames =
nullptr;
383 if (missingProperties.isEmpty())
386 d->type->createProperties(missingProperties);
387 d->dropStalePropertyCache();
389 for (
const QByteArray &name : std::as_const(missingProperties))
390 checkedSetValue(names[name], values[name], force);
399void QQmlOpenMetaObject::setCached(
bool c)
401 if (c == d->cacheProperties)
404 d->cacheProperties = c;
406 QQmlData *qmldata = QQmlData::get(d->object,
true);
407 if (d->cacheProperties) {
411 if (!d->type->d->cache)
412 d->type->d->cache = QQmlPropertyCache::createStandalone(
this);
413 qmldata->propertyCache = d->type->d->cache;
415 d->type->d->cache.reset();
416 qmldata->propertyCache.reset();
431int QQmlOpenMetaObject::createProperty(
const char *name,
const char *)
434 if (d->deferredPropertyNames) {
436 d->deferredPropertyNames->append(name);
440 const int result = d->type->createProperty(name);
441 d->dropStalePropertyCache();