80void QQmlOpenMetaObjectType::createProperties(
const QList<QByteArray> &names)
82 for (
int i = 0; i < names.size(); ++i) {
83 const QByteArray &name = names.at(i);
84 const int id = d->mob.propertyCount();
85 d->mob.addSignal(
"__" + QByteArray::number(id) +
"()");
86 QMetaPropertyBuilder build = d->mob.addProperty(name,
"QVariant", id);
87 propertyCreated(id, build);
88 d->names.insert(name, id);
91 d->mem = d->mob.toMetaObject();
92 QSet<QQmlOpenMetaObject*>::iterator it = d->referers.begin();
93 while (it != d->referers.end()) {
94 QQmlOpenMetaObject *omo = *it;
95 *
static_cast<QMetaObject *>(omo) = *d->mem;
97 d->cache->update(omo);
102int QQmlOpenMetaObjectType::createProperty(
const QByteArray &name)
104 const int signalIdx = d->mob.addSignal(
105 "__" + QByteArray::number(d->mob.propertyCount()) +
"()").index();
106 QMetaPropertyBuilder build = d->mob.addProperty(name,
"QVariant", signalIdx);
107 propertyCreated(build.index(), build);
109 d->mem = d->mob.toMetaObject();
110 d->names.insert(name, build.index());
111 QSet<QQmlOpenMetaObject*>::iterator it = d->referers.begin();
112 while (it != d->referers.end()) {
113 QQmlOpenMetaObject *omo = *it;
114 *
static_cast<QMetaObject *>(omo) = *d->mem;
116 d->cache->update(omo);
120 return d->propertyOffset + build.index();
123void QQmlOpenMetaObjectType::propertyCreated(
int id, QMetaPropertyBuilder &builder)
132 mob.setSuperClass(metaObj);
133 mob.setClassName(metaObj->className());
134 mob.setFlags(MetaObjectFlag::DynamicMetaObject);
136 mem = mob.toMetaObject();
138 propertyOffset = mem->propertyOffset();
139 signalOffset = mem->methodOffset();
223QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj,
const QMetaObject *base)
224: d(
new QQmlOpenMetaObjectPrivate(
this, obj))
226 d->type.adopt(
new QQmlOpenMetaObjectType(base ? base : obj->metaObject()));
227 d->type->d->referers.insert(
this);
229 QObjectPrivate *op = QObjectPrivate::get(obj);
230 d->parent = op->metaObject;
231 *
static_cast<QMetaObject *>(
this) = *d->type->d->mem;
232 op->metaObject =
this;
235QQmlOpenMetaObject::QQmlOpenMetaObject(
236 QObject *obj,
const QQmlRefPointer<QQmlOpenMetaObjectType> &type)
237: d(
new QQmlOpenMetaObjectPrivate(
this, obj))
240 d->type->d->referers.insert(
this);
242 QObjectPrivate *op = QObjectPrivate::get(obj);
243 d->parent = op->metaObject;
244 *
static_cast<QMetaObject *>(
this) = *d->type->d->mem;
245 op->metaObject =
this;
261void QQmlOpenMetaObject::emitPropertyNotification(
const QByteArray &propertyName)
263 QHash<QByteArray,
int>::ConstIterator iter = d->type->d->names.constFind(propertyName);
264 if (iter == d->type->d->names.constEnd())
266 activate(d->object, *iter + d->type->d->signalOffset,
nullptr);
274int QQmlOpenMetaObject::metaCall(QObject *o, QMetaObject::Call c,
int id,
void **a)
276 Q_ASSERT(d->object == o);
278 if (( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty)
279 && id >= d->type->d->propertyOffset) {
280 int propId = id - d->type->d->propertyOffset;
281 if (c == QMetaObject::ReadProperty) {
282 propertyRead(propId);
283 *
reinterpret_cast<QVariant *>(a[0]) = d->propertyValue(propId);
284 }
else if (c == QMetaObject::WriteProperty) {
285 if (propId >= d->data.size() || d->data.at(propId).value() != *
reinterpret_cast<QVariant *>(a[0])) {
286 propertyWrite(propId);
287 d->setPropertyValue(propId, propertyWriteValue(propId, *
reinterpret_cast<QVariant *>(a[0])));
288 propertyWritten(propId);
289 activate(o, d->type->d->signalOffset + propId,
nullptr);
295 return d->parent->metaCall(o, c, id, a);
297 return o->qt_metacall(c, id, a);
306bool QQmlOpenMetaObject::checkedSetValue(
int index,
const QVariant &value,
bool force)
308 if (!force && d->propertyValue(index) == value)
311 d->setPropertyValue(index, value);
312 activate(d->object, index + d->type->d->signalOffset,
nullptr);
321void QQmlOpenMetaObject::setValue(
int id,
const QVariant &value)
323 d->setPropertyValue(id, propertyWriteValue(id, value));
324 activate(d->object, id + d->type->d->signalOffset,
nullptr);
344bool QQmlOpenMetaObject::setValue(
const QByteArray &name,
const QVariant &val,
bool force)
346 QHash<QByteArray,
int>::ConstIterator iter = d->type->d->names.constFind(name);
349 if (iter == d->type->d->names.cend()) {
350 id = createProperty(name.constData(),
"") - d->type->d->propertyOffset;
356 return checkedSetValue(id, val, force);
361void QQmlOpenMetaObject::setValues(
const QHash<QByteArray, QVariant> &values,
bool force)
363 QList<QByteArray> missingProperties;
364 d->deferredPropertyNames = &missingProperties;
365 const auto &names = d->type->d->names;
367 for (
auto valueIt = values.begin(), end = values.end(); valueIt != end; ++valueIt) {
368 const auto nameIt = names.constFind(valueIt.key());
369 if (nameIt == names.constEnd()) {
370 const int id = createProperty(valueIt.key(),
"") - d->type->d->propertyOffset;
377 checkedSetValue(id, valueIt.value(), force);
379 checkedSetValue(*nameIt, valueIt.value(), force);
383 d->deferredPropertyNames =
nullptr;
384 if (missingProperties.isEmpty())
387 d->type->createProperties(missingProperties);
388 d->dropStalePropertyCache();
390 for (
const QByteArray &name : std::as_const(missingProperties))
391 checkedSetValue(names[name], values[name], force);
400void QQmlOpenMetaObject::setCached(
bool c)
402 if (c == d->cacheProperties)
405 d->cacheProperties = c;
407 QQmlData *qmldata = QQmlData::get(d->object,
true);
408 if (d->cacheProperties) {
412 if (!d->type->d->cache)
413 d->type->d->cache = QQmlPropertyCache::createStandalone(
this);
414 qmldata->propertyCache = d->type->d->cache;
416 d->type->d->cache.reset();
417 qmldata->propertyCache.reset();
432int QQmlOpenMetaObject::createProperty(
const char *name,
const char *)
435 if (d->deferredPropertyNames) {
437 d->deferredPropertyNames->append(name);
441 const int result = d->type->createProperty(name);
442 d->dropStalePropertyCache();