QDeclarativePropertyCache::Data *QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj, const QString &name, Data &local) { QDeclarativePropertyCache::Data *rv = 0; if (!engine) { local = QDeclarativePropertyCache::create(obj->metaObject(), name); if (local.isValid()) rv = &local; } else { QDeclarativeEnginePrivate *enginePrivate = QDeclarativeEnginePrivate::get(engine); QDeclarativePropertyCache *cache = 0; QDeclarativeData *ddata = QDeclarativeData::get(obj); if (ddata && ddata->propertyCache && ddata->propertyCache->qmlEngine() == engine) cache = ddata->propertyCache; if (!cache) { cache = enginePrivate->cache(obj); if (cache && ddata && !ddata->propertyCache) { cache->addref(); ddata->propertyCache = cache; } } if (cache) { rv = cache->property(name); } else { local = QDeclarativePropertyCache::create(obj->metaObject(), name); if (local.isValid()) rv = &local; } } return rv; }
QDeclarativePropertyCache::Data * QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj, const QHashedV8String &name, Data &local) { // XXX Optimize for worker script case where engine isn't available QDeclarativePropertyCache *cache = 0; if (engine) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QDeclarativeData *ddata = QDeclarativeData::get(obj); if (ddata && ddata->propertyCache) cache = ddata->propertyCache; if (!cache) { cache = ep->cache(obj); if (cache && ddata && !ddata->propertyCache) { cache->addref(); ddata->propertyCache = cache; } } } QDeclarativePropertyCache::Data *rv = 0; if (cache) { rv = cache->property(name); } else { QString strname = QV8Engine::toStringStatic(name.string()); // QString strname = ep->v8engine()->toString(name); local = QDeclarativePropertyCache::create(obj->metaObject(), strname); if (local.isValid()) rv = &local; } return rv; }
QStringList QDeclarativeObjectScriptClass::propertyNames(Object *object) { QObject *obj = toQObject(object); if (!obj) return QStringList(); QDeclarativeEnginePrivate *enginePrivate = QDeclarativeEnginePrivate::get(engine); QDeclarativePropertyCache *cache = 0; QDeclarativeData *ddata = QDeclarativeData::get(obj); if (ddata) cache = ddata->propertyCache; if (!cache) { cache = enginePrivate->cache(obj); if (cache) { if (ddata) { cache->addref(); ddata->propertyCache = cache; } } else { // Not cachable - fall back to QMetaObject (eg. dynamic meta object) // XXX QDeclarativeOpenMetaObject has a cache, so this is suboptimal. // XXX This is a workaround for QTBUG-9420. const QMetaObject *mo = obj->metaObject(); QStringList r; int pc = mo->propertyCount(); int po = mo->propertyOffset(); for (int i=po; i<pc; ++i) r += QString::fromUtf8(mo->property(i).name()); return r; } } return cache->propertyNames(); }
/*! Returns the next related method, if one, or 0. */ QDeclarativePropertyCache::Data * QDeclarativeObjectMethodScriptClass::relatedMethod(QObject *object, QDeclarativePropertyCache::Data *current, QDeclarativePropertyCache::Data &dummy) { QDeclarativePropertyCache *cache = QDeclarativeData::get(object)->propertyCache; if (current->relatedIndex == -1) return 0; if (cache) { return cache->method(current->relatedIndex); } else { const QMetaObject *mo = object->metaObject(); int methodOffset = mo->methodCount() - QMetaObject_methods(mo); while (methodOffset > current->relatedIndex) { mo = mo->superClass(); methodOffset -= QMetaObject_methods(mo); } QMetaMethod method = mo->method(current->relatedIndex); dummy.load(method); // Look for overloaded methods QByteArray methodName = QMetaMethod_name(method); for (int ii = current->relatedIndex - 1; ii >= methodOffset; --ii) { if (methodName == QMetaMethod_name(mo->method(ii))) { dummy.relatedIndex = ii; return &dummy; } } return &dummy; } }