summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
authorWarwick Allison <warwick.allison@nokia.com>2009-07-21 07:24:36 (GMT)
committerWarwick Allison <warwick.allison@nokia.com>2009-07-21 07:24:36 (GMT)
commit34055e0160e2e94b0dd6b972c5bdc96a421adcf1 (patch)
treebf7667e86dfe4d5c8e7ee3be40aa8862ff4042ca /src/declarative/qml
parentc301d995c646c70f8f943e2e4fc293a3e2d29edf (diff)
parent8db694cb38e1f7f5096db96fcc1f168b13e643a4 (diff)
downloadQt-34055e0160e2e94b0dd6b972c5bdc96a421adcf1.zip
Qt-34055e0160e2e94b0dd6b972c5bdc96a421adcf1.tar.gz
Qt-34055e0160e2e94b0dd6b972c5bdc96a421adcf1.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qml.pri9
-rw-r--r--src/declarative/qml/qmlbasicscript.cpp434
-rw-r--r--src/declarative/qml/qmlbasicscript_p.h41
-rw-r--r--src/declarative/qml/qmlbindablecomponent.cpp104
-rw-r--r--src/declarative/qml/qmlbindablecomponent.h91
-rw-r--r--src/declarative/qml/qmlbindablecomponent_p.h77
-rw-r--r--src/declarative/qml/qmlbinding.cpp (renamed from src/declarative/qml/qmlbindablevalue.cpp)59
-rw-r--r--src/declarative/qml/qmlbinding.h (renamed from src/declarative/qml/qmlbindablevalue.h)29
-rw-r--r--src/declarative/qml/qmlbinding_p.h (renamed from src/declarative/qml/qmlbindablevalue_p.h)18
-rw-r--r--src/declarative/qml/qmlboundsignal.cpp6
-rw-r--r--src/declarative/qml/qmlboundsignal_p.h2
-rw-r--r--src/declarative/qml/qmlcomponent.cpp21
-rw-r--r--src/declarative/qml/qmlcomponent.h9
-rw-r--r--src/declarative/qml/qmlcomponent_p.h2
-rw-r--r--src/declarative/qml/qmlcontext.cpp2
-rw-r--r--src/declarative/qml/qmlengine.cpp90
-rw-r--r--src/declarative/qml/qmlengine_p.h13
-rw-r--r--src/declarative/qml/qmlexpression.cpp418
-rw-r--r--src/declarative/qml/qmlexpression.h39
-rw-r--r--src/declarative/qml/qmlexpression_p.h81
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp20
-rw-r--r--src/declarative/qml/qmlmetaproperty.h6
-rw-r--r--src/declarative/qml/qmlparser.cpp1
-rw-r--r--src/declarative/qml/qmlvme.cpp20
-rw-r--r--src/declarative/qml/qpodvector_p.h13
25 files changed, 745 insertions, 860 deletions
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index eecf8cd..b71ca1f 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -3,8 +3,9 @@ SOURCES += qml/qmlparser.cpp \
qml/qmlvmemetaobject.cpp \
qml/qmlengine.cpp \
qml/qmlexpression.cpp \
- qml/qmlbindablevalue.cpp \
+ qml/qmlbinding.cpp \
qml/qmlmetaproperty.cpp \
+ qml/qmlbindablecomponent.cpp \
qml/qmlcomponent.cpp \
qml/qmlcontext.cpp \
qml/qmlcustomparser.cpp \
@@ -33,9 +34,11 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlinstruction_p.h \
qml/qmlvmemetaobject_p.h \
qml/qml.h \
- qml/qmlbindablevalue.h \
- qml/qmlbindablevalue_p.h \
+ qml/qmlbinding.h \
+ qml/qmlbinding_p.h \
qml/qmlmetaproperty.h \
+ qml/qmlbindablecomponent.h \
+ qml/qmlbindablecomponent_p.h \
qml/qmlcomponent.h \
qml/qmlcomponent_p.h \
qml/qmlcustomparser_p.h \
diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp
index 40ffffe..073642f 100644
--- a/src/declarative/qml/qmlbasicscript.cpp
+++ b/src/declarative/qml/qmlbasicscript.cpp
@@ -56,13 +56,10 @@ using namespace QmlJS;
struct ScriptInstruction {
enum {
- Load, // fetch
- Fetch, // fetch
-
LoadIdObject, // fetch
FetchConstant, // constant
- FetchD0Constant, // constant
- FetchD1Constant, // constant
+ FetchContextConstant, // constant
+ FetchRootConstant, // constant
Equals, // NA
@@ -88,8 +85,6 @@ struct ScriptInstruction {
};
};
-DEFINE_BOOL_CONFIG_OPTION(scriptWarnings, QML_SCRIPT_WARNINGS);
-
class QmlBasicScriptPrivate
{
public:
@@ -120,60 +115,6 @@ public:
}
};
-QDebug operator<<(QDebug lhs, const QmlBasicScriptNodeCache &rhs)
-{
- switch(rhs.type) {
- case QmlBasicScriptNodeCache::Invalid:
- lhs << "Invalid";
- break;
- case QmlBasicScriptNodeCache::Core:
- lhs << "Core" << rhs.object << rhs.core;
- break;
- case QmlBasicScriptNodeCache::Attached:
- lhs << "Attached" << rhs.object << rhs.attached;
- break;
- case QmlBasicScriptNodeCache::SignalProperty:
- lhs << "SignalProperty" << rhs.object << rhs.core;
- break;
- case QmlBasicScriptNodeCache::Variant:
- lhs << "Variant" << rhs.context;
- break;
- }
-
- return lhs;
-}
-
-void QmlBasicScriptNodeCache::clear()
-{
- object = 0;
- metaObject = 0;
- type = Invalid;
-}
-
-static QVariant toObjectOrVariant(const QVariant &v)
-{
- switch(v.userType()) {
- case QVariant::String:
- case QVariant::UInt:
- case QVariant::Int:
- case QMetaType::Float:
- case QVariant::Double:
- case QVariant::Color:
- case QVariant::Bool:
- default:
- {
- if (v.type() == QVariant::UserType) {
- QObject *o = QmlMetaType::toQObject(v);
- if (o)
- return qVariantFromValue(o);
- else
- return v;
- }
- return v;
- }
- }
-}
-
static QVariant fetch_value(QObject *o, int idx, int type)
{
if (!o)
@@ -259,26 +200,6 @@ static QVariant fetch_value(QObject *o, int idx, int type)
};
}
-QVariant QmlBasicScriptNodeCache::value(const char *) const
-{
- //QFxPerfTimer<QFxPerf::BasicScriptValue> pt;
- switch(type) {
- case Invalid:
- break;
- case Core:
- return fetch_value(object, core, coreType);
- break;
- case Attached:
- return qVariantFromValue(static_cast<QObject *>(attached));
- break;
- case SignalProperty:
- break;
- case Variant:
- return context->propertyValues[contextIndex];
- };
- return QVariant();
-}
-
struct QmlBasicScriptCompiler
{
QmlBasicScriptCompiler()
@@ -298,7 +219,11 @@ struct QmlBasicScriptCompiler
bool tryConstant(QmlJS::AST::Node *);
bool parseConstant(QmlJS::AST::Node *);
bool tryName(QmlJS::AST::Node *);
- bool parseName(QmlJS::AST::Node *, QmlParser::Object ** = 0);
+ bool parseName(QmlJS::AST::Node *);
+
+ bool buildName(QStringList &, QmlJS::AST::Node *);
+ const QMetaObject *fetch(int type, const QMetaObject *, int idx);
+
bool tryBinaryExpression(QmlJS::AST::Node *);
bool compileBinaryExpression(QmlJS::AST::Node *);
@@ -340,7 +265,7 @@ QmlBasicScript::QmlBasicScript()
}
/*!
- Create a new QmlBasicScript instance from saved \a data.
+ Load the QmlBasicScript instance with saved \a data.
\a data \b must be data previously acquired from calling compileData() on a
previously created QmlBasicScript instance. Any other data will almost
@@ -352,9 +277,12 @@ QmlBasicScript::QmlBasicScript()
If \a owner is set, it is referenced on creation and dereferenced on
destruction of this instance.
*/
-QmlBasicScript::QmlBasicScript(const char *data, QmlRefCount *owner)
-: flags(0), d((QmlBasicScriptPrivate *)data), rc(owner)
+
+void QmlBasicScript::load(const char *data, QmlRefCount *owner)
{
+ clear();
+ d = (QmlBasicScriptPrivate *)data;
+ rc = owner;
if (rc) rc->addref();
}
@@ -374,11 +302,7 @@ QByteArray QmlBasicScript::expression() const
*/
QmlBasicScript::~QmlBasicScript()
{
- if (flags & QmlBasicScriptPrivate::OwnData)
- free(d);
- if (rc) rc->release();
- d = 0;
- rc = 0;
+ clear();
}
/*!
@@ -401,24 +325,14 @@ void QmlBasicScript::clear()
*/
void *QmlBasicScript::newScriptState()
{
- if (!d) {
- return 0;
- } else {
- void *rv = ::malloc(d->stateSize * sizeof(QmlBasicScriptNodeCache));
- ::memset(rv, 0, d->stateSize * sizeof(QmlBasicScriptNodeCache));
- return rv;
- }
+ return 0;
}
/*!
Delete the \a data previously allocated by newScriptState().
*/
-void QmlBasicScript::deleteScriptState(void *data)
+void QmlBasicScript::deleteScriptState(void *)
{
- if (!data) return;
- Q_ASSERT(d);
- clearCache(data);
- free(data);
}
/*!
@@ -430,18 +344,21 @@ void QmlBasicScript::dump()
return;
qWarning() << d->instructionCount << "instructions:";
- const char *data = d->data();
for (int ii = 0; ii < d->instructionCount; ++ii) {
const ScriptInstruction &instr = d->instructions()[ii];
switch(instr.type) {
- case ScriptInstruction::Load:
- qWarning().nospace() << "LOAD\t\t" << instr.fetch.idx << "\t\t"
- << QByteArray(data + instr.fetch.idx);
+ case ScriptInstruction::LoadIdObject:
+ qWarning().nospace() << "LOAD_ID_OBJECT";
break;
- case ScriptInstruction::Fetch:
- qWarning().nospace() << "FETCH\t\t" << instr.fetch.idx << "\t\t"
- << QByteArray(data + instr.fetch.idx);
+ case ScriptInstruction::FetchConstant:
+ qWarning().nospace() << "FETCH_CONSTANT";
+ break;
+ case ScriptInstruction::FetchContextConstant:
+ qWarning().nospace() << "FETCH_CONTEXT_CONSTANT";
+ break;
+ case ScriptInstruction::FetchRootConstant:
+ qWarning().nospace() << "FETCH_ROOT_CONSTANT";
break;
case ScriptInstruction::Equals:
qWarning().nospace() << "EQUALS";
@@ -552,101 +469,121 @@ bool QmlBasicScriptCompiler::tryName(QmlJS::AST::Node *node)
node->kind == AST::Node::Kind_FieldMemberExpression;
}
-bool QmlBasicScriptCompiler::parseName(AST::Node *node,
- QmlParser::Object **type)
+bool QmlBasicScriptCompiler::buildName(QStringList &name,
+ QmlJS::AST::Node *node)
{
- bool load = false;
- QmlParser::Object *loadedType = 0;
- QString name;
if (node->kind == AST::Node::Kind_IdentifierExpression) {
- name = static_cast<AST::IdentifierExpression *>(node)->name->asString();
- load = true;
+ name << static_cast<AST::IdentifierExpression*>(node)->name->asString();
} else if (node->kind == AST::Node::Kind_FieldMemberExpression) {
- AST::FieldMemberExpression *expr = static_cast<AST::FieldMemberExpression *>(node);
+ AST::FieldMemberExpression *expr =
+ static_cast<AST::FieldMemberExpression *>(node);
- if (!parseName(expr->base, &loadedType))
+ if (!buildName(name, expr->base))
return false;
- name = expr->name->asString();
+ name << expr->name->asString();
} else {
return false;
}
+ return true;
+}
+
+const QMetaObject *
+QmlBasicScriptCompiler::fetch(int type, const QMetaObject *mo, int idx)
+{
ScriptInstruction instr;
- if (load) {
+ (int &)instr.type = type;
+ instr.constant.idx = idx;
+ QMetaProperty prop = mo->property(idx);
+ if (prop.isConstant())
+ instr.constant.notify = 0;
+ else
+ instr.constant.notify = prop.notifySignalIndex();
+ instr.constant.type = prop.userType();
+ bytecode << instr;
+ return QmlMetaType::metaObjectForType(prop.userType());
+}
+
+bool QmlBasicScriptCompiler::parseName(AST::Node *node)
+{
+ QStringList nameParts;
+ if (!buildName(nameParts, node))
+ return false;
- if (ids.contains(name)) {
- instr.type = ScriptInstruction::LoadIdObject;
- instr.fetch.idx = ids.value(name)->idIndex;
+ QmlParser::Object *absType = 0;
+ const QMetaObject *metaType = 0;
- if (type)
- *type = ids.value(name);
+ for (int ii = 0; ii < nameParts.count(); ++ii) {
+ const QString &name = nameParts.at(ii);
- } else {
- int d0Idx = context->metaObject()->indexOfProperty(name.toUtf8().constData());
- int d1Idx = -1;
- if (d0Idx == -1)
- d1Idx = component->metaObject()->indexOfProperty(name.toUtf8().constData());
- if (d0Idx != -1) {
-
- instr.type = ScriptInstruction::FetchD0Constant;
- instr.constant.idx = d0Idx;
- QMetaProperty prop = context->metaObject()->property(d0Idx);
- if (prop.isConstant())
- instr.constant.notify = 0;
- else
- instr.constant.notify = prop.notifySignalIndex();
- instr.constant.type = prop.userType();
-
- } else if (d1Idx != -1) {
-
- instr.type = ScriptInstruction::FetchD1Constant;
- instr.constant.idx = d1Idx;
- QMetaProperty prop = component->metaObject()->property(d1Idx);
- if (prop.isConstant())
- instr.constant.notify = 0;
- else
- instr.constant.notify = prop.notifySignalIndex();
- instr.constant.type = prop.userType();
-
- } else {
-
- int nref = data.count();
- data.append(name.toUtf8());
- data.append('\0');
- instr.type = ScriptInstruction::Load;
- instr.fetch.idx = nref;
- ++stateSize;
+ // We don't handle signal properties
+ if (name.length() > 2 && name.startsWith(QLatin1String("on")) &&
+ name.at(2).isUpper())
+ return false;
+ if (ii == 0) {
+
+ if (0) {
+ // ### - Must test for an attached type name
+ } else if (ids.contains(name)) {
+ ScriptInstruction instr;
+ instr.type = ScriptInstruction::LoadIdObject;
+ instr.fetch.idx = ids.value(name)->idIndex;
+ bytecode << instr;
+ absType = ids.value(name);
+ } else if(name.at(0).isLower()) {
+
+ QByteArray utf8Name = name.toUtf8();
+ const char *cname = utf8Name.constData();
+
+ int d0Idx = context->metaObject()->indexOfProperty(cname);
+ int d1Idx = -1;
+ if (d0Idx == -1)
+ d1Idx = component->metaObject()->indexOfProperty(cname);
+
+ if (d0Idx != -1) {
+ metaType = fetch(ScriptInstruction::FetchContextConstant,
+ context->metaObject(), d0Idx);
+ } else if(d1Idx != -1) {
+ metaType = fetch(ScriptInstruction::FetchRootConstant,
+ component->metaObject(), d1Idx);
+ } else {
+ return false;
+ }
+
+ } else {
+ return false;
}
- }
+ } else {
- } else {
+ if (!name.at(0).isLower())
+ return false;
- int idx = -1;
- if (loadedType)
- idx = loadedType->metaObject()->indexOfProperty(name.toUtf8().constData());
- if (idx != -1) {
- instr.type = ScriptInstruction::FetchConstant;
- instr.constant.idx = idx;
- QMetaProperty prop = loadedType->metaObject()->property(idx);
- if (prop.isConstant())
- instr.constant.notify = 0;
+ const QMetaObject *mo = 0;
+ if (absType)
+ mo = absType->metaObject();
+ else if(metaType)
+ mo = metaType;
else
- instr.constant.notify = prop.notifySignalIndex();
- instr.constant.type = prop.userType();
- } else {
- int nref = data.count();
- data.append(name.toUtf8());
- data.append('\0');
- instr.type = ScriptInstruction::Fetch;
- instr.fetch.idx = nref;
- ++stateSize;
- }
+ return false;
+
+ QByteArray utf8Name = name.toUtf8();
+ const char *cname = utf8Name.constData();
+ int idx = mo->indexOfProperty(cname);
+ if (idx == -1)
+ return false;
+
+ if (absType || mo->property(idx).isFinal()) {
+ absType = 0; metaType = 0;
+ metaType = fetch(ScriptInstruction::FetchConstant, mo, idx);
+ } else {
+ return false;
+ }
+ }
}
- bytecode.append(instr);
return true;
}
@@ -699,44 +636,6 @@ bool QmlBasicScriptCompiler::compileBinaryExpression(AST::Node *node)
}
/*!
- \internal
-*/
-void QmlBasicScript::clearCache(void *voidCache)
-{
- QmlBasicScriptNodeCache *dataCache =
- reinterpret_cast<QmlBasicScriptNodeCache *>(voidCache);
-
- for (int ii = 0; ii < d->stateSize; ++ii) {
- if (!dataCache[ii].isCore() && !dataCache[ii].isVariant() &&
- dataCache[ii].object) {
- QMetaObject::removeGuard(&dataCache[ii].object);
- dataCache[ii].object = 0;
- }
- dataCache[ii].clear();
- }
-}
-
-void QmlBasicScript::guard(QmlBasicScriptNodeCache &n)
-{
- if (n.object) {
- if (n.isVariant()) {
- } else if (n.isCore()) {
- n.metaObject =
- n.object->metaObject();
- } else {
- QMetaObject::addGuard(&n.object);
- }
- }
-}
-
-bool QmlBasicScript::valid(QmlBasicScriptNodeCache &n, QObject *obj)
-{
- return n.object == obj &&
- (!n.isCore() || obj->metaObject() == n.metaObject);
-}
-
-
-/*!
\enum QmlBasicScript::CacheState
\value NoChange The query has not change. Any previous monitoring is still
valid.
@@ -753,31 +652,17 @@ bool QmlBasicScript::valid(QmlBasicScriptNodeCache &n, QObject *obj)
*/
QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *cached)
{
+ Q_UNUSED(voidCache);
if (!isValid())
return QVariant();
QmlContextPrivate *contextPrivate = context->d_func();
QmlEnginePrivate *enginePrivate = context->engine()->d_func();
- QmlBasicScriptNodeCache *dataCache =
- reinterpret_cast<QmlBasicScriptNodeCache *>(voidCache);
- int dataCacheItem;
-
QStack<QVariant> stack;
- bool resetting = false;
- bool hasReset = false;
-
- const char *data = d->data();
-
- if (dataCache[0].type == QmlBasicScriptNodeCache::Invalid) {
- resetting = true;
- hasReset = true;
- }
-
CacheState state = NoChange;
- dataCacheItem = 0;
for (int idx = 0; idx < d->instructionCount; ++idx) {
const ScriptInstruction &instr = d->instructions()[idx];
@@ -791,7 +676,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
}
break;
- case ScriptInstruction::FetchD0Constant:
+ case ScriptInstruction::FetchContextConstant:
{
QObject *obj = contextPrivate->defaultObjects.at(0);
@@ -803,7 +688,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
}
break;
- case ScriptInstruction::FetchD1Constant:
+ case ScriptInstruction::FetchRootConstant:
{
QObject *obj = contextPrivate->defaultObjects.at(1);
@@ -828,64 +713,14 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
}
break;
- case ScriptInstruction::Load: // either an object or a property
- case ScriptInstruction::Fetch: // can only be a property
- {
- const char *id = data + instr.fetch.idx;
- QmlBasicScriptNodeCache &n = dataCache[dataCacheItem];
-
- if (instr.type == ScriptInstruction::Load) {
-
- if (n.type == QmlBasicScriptNodeCache::Invalid || state == Reset) {
- context->engine()->d_func()->loadCache(n, QLatin1String(id), static_cast<QmlContextPrivate*>(context->d_ptr));
- if (state != Reset)
- state = Incremental;
- }
-
- if(!n.isValid())
- qWarning("ReferenceError: %s is not defined", id);
-
- } else { // instr.type == ScriptInstruction::Fetch
-
- QVariant o = stack.pop();
- QObject *obj = qvariant_cast<QObject *>(o);
- if (!obj) {
- if (n.type == QmlBasicScriptNodeCache::Invalid) {
- if (scriptWarnings())
- qWarning() << "QmlBasicScript: Unable to convert" << o;
- *cached = state;
- return QVariant();
- } else {
- clearCache(dataCache);
- *cached = Reset;
- CacheState dummy;
- return run(context, voidCache, &dummy);
- }
- } else if (n.type == QmlBasicScriptNodeCache::Invalid || state == Reset) {
- context->engine()->d_func()->fetchCache(n, QLatin1String(id), obj);
- guard(n);
- if (state != Reset)
- state = Incremental;
- } else if (!valid(n, obj)) {
- clearCache(dataCache);
- *cached = Reset;
- CacheState dummy;
- return run(context, voidCache, &dummy);
- }
-
- }
-
- QVariant var = n.value(id);
- stack.push(var);
- ++dataCacheItem;
- }
- break;
case ScriptInstruction::Int:
stack.push(QVariant(instr.integer.value));
break;
+
case ScriptInstruction::Bool:
stack.push(QVariant(instr.boolean.value));
break;
+
case ScriptInstruction::Equals:
{
QVariant rhs = stack.pop();
@@ -899,7 +734,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
}
}
- *cached = state;
+ *cached = Reset;
if (stack.isEmpty())
return QVariant();
@@ -927,23 +762,4 @@ unsigned int QmlBasicScript::compileDataSize() const
return 0;
}
-bool QmlBasicScript::isSingleLoad() const
-{
- if (!d)
- return false;
-
- return d->instructionCount == 1 &&
- d->instructions()[0].type == ScriptInstruction::Load;
-}
-
-QByteArray QmlBasicScript::singleLoadTarget() const
-{
- if (!isSingleLoad())
- return QByteArray();
-
- // We know there is one instruction and it is a load
- return QByteArray(d->data() + d->instructions()[0].fetch.idx);
-}
-
-
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlbasicscript_p.h b/src/declarative/qml/qmlbasicscript_p.h
index 77d59eb..539227f 100644
--- a/src/declarative/qml/qmlbasicscript_p.h
+++ b/src/declarative/qml/qmlbasicscript_p.h
@@ -70,9 +70,10 @@ class QmlBasicScript
{
public:
QmlBasicScript();
- QmlBasicScript(const char *, QmlRefCount * = 0);
~QmlBasicScript();
+ void load(const char *, QmlRefCount * = 0);
+
// Always 4-byte aligned
const char *compileData() const;
unsigned int compileDataSize() const;
@@ -100,50 +101,12 @@ public:
enum CacheState { NoChange, Incremental, Reset };
QVariant run(QmlContext *, void *, CacheState *);
- // Optimization opportunities
- bool isSingleLoad() const;
- QByteArray singleLoadTarget() const;
-
private:
int flags;
QmlBasicScriptPrivate *d;
QmlRefCount *rc;
-
- void clearCache(void *);
- void guard(QmlBasicScriptNodeCache &);
- bool valid(QmlBasicScriptNodeCache &, QObject *);
};
-class QmlContextPrivate;
-class QDebug;
-class QmlBasicScriptNodeCache
-{
-public:
- QObject *object;
- const QMetaObject *metaObject;
- enum { Invalid,
- Core,
- Attached,
- SignalProperty,
- Variant
- } type;
- union {
- int core;
- QObject *attached;
- QmlContextPrivate *context;
- };
- int coreType;
- int contextIndex;
-
- bool isValid() const { return type != Invalid; }
- bool isCore() const { return type == Core; }
- bool isVariant() const { return type == Variant; }
- void clear();
- QVariant value(const char *) const;
-};
-
-QDebug operator<<(QDebug, const QmlBasicScriptNodeCache &);
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/declarative/qml/qmlbindablecomponent.cpp b/src/declarative/qml/qmlbindablecomponent.cpp
new file mode 100644
index 0000000..ed9924a
--- /dev/null
+++ b/src/declarative/qml/qmlbindablecomponent.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlbindablecomponent.h"
+#include "qmlbindablecomponent_p.h"
+#include "qmlcomponent.h"
+
+QT_BEGIN_NAMESPACE
+QmlBindableComponent::QmlBindableComponent(QmlEngine *engine, QObject *parent)
+ : QmlComponent(*(new QmlBindableComponentPrivate), parent)
+{
+ Q_D(QmlBindableComponent);
+ d->engine = engine;
+ connect(this, SIGNAL(statusChanged(QmlComponent::Status)),
+ this, SLOT(statusChange(QmlComponent::Status)));
+}
+
+QmlBindableComponent::QmlBindableComponent(QmlEngine *engine, const QUrl &url, QObject *parent)
+ : QmlComponent(*(new QmlBindableComponentPrivate), parent)
+{
+ Q_D(QmlBindableComponent);
+ d->engine = engine;
+ loadUrl(url);
+ connect(this, SIGNAL(statusChanged(QmlComponent::Status)),
+ this, SLOT(statusChange(QmlComponent::Status)));
+}
+
+void QmlBindableComponent::setContext(QmlContext* c)
+{
+ Q_D(QmlBindableComponent);
+ d->ctxt =c;
+}
+/*!
+ Create a script object instance from this component. Returns a null
+ script object if creation failed. It will create the instance in the
+ same context that it was created it. QmlBindableComponent is only
+ meant to be created from with script - C++ developers should just use
+ QmlComponent directly.
+
+ Similar to QmlComponent::create(), but creates an object suitable
+ for usage within scripts.
+*/
+QScriptValue QmlBindableComponent::createObject()
+{
+ Q_D(QmlBindableComponent);
+ QObject* ret = create(d->ctxt);
+ return QmlEngine::qmlScriptObject(ret, d->engine);
+}
+
+void QmlBindableComponent::statusChange(QmlComponent::Status newStatus)
+{
+ Q_D(QmlBindableComponent);
+ if(newStatus == d->prevStatus)
+ return;
+ if(newStatus == QmlComponent::Null || d->prevStatus == QmlComponent::Null)
+ emit isNullChanged();
+ if(newStatus == QmlComponent::Ready || d->prevStatus == QmlComponent::Ready)
+ emit isReadyChanged();
+ if(newStatus == QmlComponent::Loading || d->prevStatus == QmlComponent::Loading)
+ emit isLoadingChanged();
+ if(newStatus == QmlComponent::Error || d->prevStatus == QmlComponent::Error)
+ emit isErrorChanged();
+ d->prevStatus = newStatus;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlbindablecomponent.h b/src/declarative/qml/qmlbindablecomponent.h
new file mode 100644
index 0000000..2b3e0ce
--- /dev/null
+++ b/src/declarative/qml/qmlbindablecomponent.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLBINDABLECOMPONENT_H
+#define QMLBINDABLECOMPONENT_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+#include <QtDeclarative/qfxglobal.h>
+#include <QtDeclarative/qml.h>
+#include <QtDeclarative/qmlcomponent.h>
+#include <QtDeclarative/qmlerror.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QmlBindableComponentPrivate;
+class QmlEngine;
+class QmlContext;
+class Q_DECLARATIVE_EXPORT QmlBindableComponent : public QmlComponent
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlBindableComponent)
+ friend class QmlEngine;
+public:
+ QmlBindableComponent(QmlEngine *, const QUrl &url, QObject *parent = 0);
+ QmlBindableComponent(QmlEngine *, QObject *parent=0);
+ Q_PROPERTY(bool isNull READ isNull NOTIFY isNullChanged);
+ Q_PROPERTY(bool isReady READ isReady NOTIFY isReadyChanged);
+ Q_PROPERTY(bool isError READ isError NOTIFY isErrorChanged);
+ Q_PROPERTY(bool isLoading READ isLoading NOTIFY isLoadingChanged);
+
+ Q_INVOKABLE QScriptValue createObject();
+
+ void setContext(QmlContext* c);
+Q_SIGNALS:
+ void isNullChanged();
+ void isErrorChanged();
+ void isReadyChanged();
+ void isLoadingChanged();
+private slots:
+ void statusChange(QmlComponent::Status newStatus);
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QmlBindableComponent)
+
+QT_END_HEADER
+#endif
diff --git a/src/declarative/qml/qmlbindablecomponent_p.h b/src/declarative/qml/qmlbindablecomponent_p.h
new file mode 100644
index 0000000..79335df
--- /dev/null
+++ b/src/declarative/qml/qmlbindablecomponent_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLBINDABLECOMPONENT_P_H
+#define QMLBINDABLECOMPONENT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qmlcomponent.h"
+#include "qmlbindablecomponent.h"
+#include "qmlcomponent_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QmlContext;
+class QmlBindableComponentPrivate : public QmlComponentPrivate
+{
+ Q_DECLARE_PUBLIC(QmlBindableComponent)
+public:
+ QmlBindableComponentPrivate() : QmlComponentPrivate(),
+ prevStatus(QmlBindableComponent::Null), ctxt(0)
+ { }
+
+ QmlComponent::Status prevStatus;
+ QmlContext* ctxt;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/declarative/qml/qmlbindablevalue.cpp b/src/declarative/qml/qmlbinding.cpp
index 6dda5e3..57c1187 100644
--- a/src/declarative/qml/qmlbindablevalue.cpp
+++ b/src/declarative/qml/qmlbinding.cpp
@@ -40,8 +40,8 @@
****************************************************************************/
#include <qml.h>
-#include "qmlbindablevalue.h"
-#include "qmlbindablevalue_p.h"
+#include "qmlbinding.h"
+#include "qmlbinding_p.h"
#include <qmlcontext.h>
#include <qmlinfo.h>
#include <QVariant>
@@ -54,46 +54,47 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(scriptWarnings, QML_SCRIPT_WARNINGS);
-QmlBindableValuePrivate::QmlBindableValuePrivate()
+QmlBindingPrivate::QmlBindingPrivate()
: inited(false), updating(false), enabled(true), mePtr(0)
{
}
-QML_DEFINE_NOCREATE_TYPE(QmlBindableValue);
-QmlBindableValue::QmlBindableValue(void *data, QmlRefCount *rc, QObject *obj, QmlContext *ctxt, QObject *parent)
-: QmlPropertyValueSource(*new QmlBindableValuePrivate, parent), QmlExpression(ctxt, data, rc, obj)
+QmlBinding::QmlBinding(void *data, QmlRefCount *rc, QObject *obj, QmlContext *ctxt, QObject *parent)
+: QmlExpression(ctxt, data, rc, obj, *new QmlBindingPrivate)
{
+ setParent(parent);
}
-QmlBindableValue::QmlBindableValue(const QString &str, QObject *obj, QmlContext *ctxt, QObject *parent)
-: QmlPropertyValueSource(*new QmlBindableValuePrivate, parent), QmlExpression(ctxt, str, obj)
+QmlBinding::QmlBinding(const QString &str, QObject *obj, QmlContext *ctxt, QObject *parent)
+: QmlExpression(ctxt, str, obj, *new QmlBindingPrivate)
{
+ setParent(parent);
}
-QmlBindableValue::~QmlBindableValue()
+QmlBinding::~QmlBinding()
{
- Q_D(QmlBindableValue);
+ Q_D(QmlBinding);
if(d->mePtr)
*(d->mePtr) = 0;
}
-void QmlBindableValue::setTarget(const QmlMetaProperty &prop)
+void QmlBinding::setTarget(const QmlMetaProperty &prop)
{
- Q_D(QmlBindableValue);
+ Q_D(QmlBinding);
d->property = prop;
update();
}
-QmlMetaProperty QmlBindableValue::property() const
+QmlMetaProperty QmlBinding::property() const
{
- Q_D(const QmlBindableValue);
+ Q_D(const QmlBinding);
return d->property;
}
-void QmlBindableValue::init()
+void QmlBinding::init()
{
- Q_D(QmlBindableValue);
+ Q_D(QmlBinding);
if (d->inited)
return;
@@ -101,24 +102,18 @@ void QmlBindableValue::init()
update();
}
-void QmlBindableValue::setExpression(const QString &expr)
+void QmlBinding::forceUpdate()
{
- QmlExpression::setExpression(expr);
- update();
-}
-
-void QmlBindableValue::forceUpdate()
-{
- Q_D(QmlBindableValue);
+ Q_D(QmlBinding);
if (!d->inited)
init();
else
update();
}
-void QmlBindableValue::update()
+void QmlBinding::update()
{
- Q_D(QmlBindableValue);
+ Q_D(QmlBinding);
#ifdef Q_ENABLE_PERFORMANCE_LOG
QFxPerfTimer<QFxPerf::BindableValueUpdate> bu;
@@ -135,7 +130,7 @@ void QmlBindableValue::update()
Q_ASSERT(idx != -1);
void *a[1];
- QmlBindableValue *t = this;
+ QmlBinding *t = this;
a[0] = (void *)&t;
QMetaObject::metacall(d->property.object(),
QMetaObject::WriteProperty,
@@ -164,21 +159,21 @@ void QmlBindableValue::update()
}
}
-void QmlBindableValue::valueChanged()
+void QmlBinding::valueChanged()
{
update();
}
-void QmlBindableValue::setEnabled(bool e)
+void QmlBinding::setEnabled(bool e)
{
- Q_D(QmlBindableValue);
+ Q_D(QmlBinding);
d->enabled = e;
setTrackChange(e);
}
-bool QmlBindableValue::enabled() const
+bool QmlBinding::enabled() const
{
- Q_D(const QmlBindableValue);
+ Q_D(const QmlBinding);
return d->enabled;
}
diff --git a/src/declarative/qml/qmlbindablevalue.h b/src/declarative/qml/qmlbinding.h
index 12da9f6..5f6d6f4 100644
--- a/src/declarative/qml/qmlbindablevalue.h
+++ b/src/declarative/qml/qmlbinding.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QMLBINDABLEVALUE_H
-#define QMLBINDABLEVALUE_H
+#ifndef QMLBINDING_H
+#define QMLBINDING_H
#include <QtCore/QObject>
#include <QtDeclarative/qfxglobal.h>
@@ -56,23 +56,18 @@ QT_MODULE(Declarative)
class QmlExpression;
class QmlContext;
-class QmlBindableValuePrivate;
-class Q_DECLARATIVE_EXPORT QmlBindableValue : public QmlPropertyValueSource,
- public QmlExpression
+class QmlBindingPrivate;
+class Q_DECLARATIVE_EXPORT QmlBinding : public QmlExpression
{
Q_OBJECT
public:
- QmlBindableValue(const QString &, QObject *, QmlContext *, QObject *parent=0);
- QmlBindableValue(void *, QmlRefCount *, QObject *, QmlContext *, QObject *parent);
- ~QmlBindableValue();
+ QmlBinding(const QString &, QObject *, QmlContext *, QObject *parent=0);
+ QmlBinding(void *, QmlRefCount *, QObject *, QmlContext *, QObject *parent);
+ ~QmlBinding();
- virtual void setTarget(const QmlMetaProperty &);
+ void setTarget(const QmlMetaProperty &);
QmlMetaProperty property() const;
- Q_CLASSINFO("DefaultProperty", "expression")
- Q_PROPERTY(QString expression READ expression WRITE setExpression)
- virtual void setExpression(const QString &);
-
void init();
void forceUpdate();
@@ -86,13 +81,13 @@ protected:
virtual void valueChanged();
private:
- Q_DECLARE_PRIVATE(QmlBindableValue)
+ Q_DECLARE_PRIVATE(QmlBinding)
};
-QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QmlBinding*);
-QML_DECLARE_TYPE(QmlBindableValue)
+QT_END_NAMESPACE
QT_END_HEADER
-#endif // QMLBINDABLEVALUE_H
+#endif // QMLBINDING_H
diff --git a/src/declarative/qml/qmlbindablevalue_p.h b/src/declarative/qml/qmlbinding_p.h
index a37b2c0..ec1a04a 100644
--- a/src/declarative/qml/qmlbindablevalue_p.h
+++ b/src/declarative/qml/qmlbinding_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QMLBINDABLEVALUE_P_H
-#define QMLBINDABLEVALUE_P_H
+#ifndef QMLBINDING_P_H
+#define QMLBINDING_P_H
//
// W A R N I N G
@@ -53,17 +53,17 @@
// We mean it.
//
-#include <private/qobject_p.h>
-#include <QtDeclarative/qmlbindablevalue.h>
+#include <QtDeclarative/qmlbinding.h>
#include <QtDeclarative/qmlmetaproperty.h>
+#include "qmlexpression_p.h"
QT_BEGIN_NAMESPACE
-class QmlBindableValuePrivate : public QObjectPrivate
+class QmlBindingPrivate : public QmlExpressionPrivate
{
- Q_DECLARE_PUBLIC(QmlBindableValue)
+ Q_DECLARE_PUBLIC(QmlBinding)
public:
- QmlBindableValuePrivate();
+ QmlBindingPrivate();
bool inited:1;
bool updating:1;
@@ -71,9 +71,9 @@ public:
QmlMetaProperty property;
- QmlBindableValue **mePtr;
+ QmlBinding **mePtr;
};
QT_END_NAMESPACE
-#endif // QMLBINDABLEVALUE_P_H
+#endif // QMLBINDING_P_H
diff --git a/src/declarative/qml/qmlboundsignal.cpp b/src/declarative/qml/qmlboundsignal.cpp
index 9779e46..9af4003 100644
--- a/src/declarative/qml/qmlboundsignal.cpp
+++ b/src/declarative/qml/qmlboundsignal.cpp
@@ -53,14 +53,14 @@ QT_BEGIN_NAMESPACE
int QmlBoundSignal::evaluateIdx = -1;
QmlBoundSignal::QmlBoundSignal(QmlContext *ctxt, const QString &val, QObject *me, int idx, QObject *parent)
-: QmlExpressionObject(ctxt, val, me, false), _idx(idx)
+: QmlExpression(ctxt, val, me), _idx(idx)
{
- // A cached evaluation of the QmlExpressionObject::value() slot index.
+ // A cached evaluation of the QmlExpression::value() slot index.
//
// This is thread safe. Although it may be updated by two threads, they
// will both set it to the same value - so the worst thing that can happen
// is that they both do the work to figure it out. Boo hoo.
- if (evaluateIdx == -1) evaluateIdx = QmlExpressionObject::staticMetaObject.indexOfMethod("value()");
+ if (evaluateIdx == -1) evaluateIdx = QmlExpression::staticMetaObject.indexOfMethod("value()");
setTrackChange(false);
QFx_setParent_noEvent(this, parent);
diff --git a/src/declarative/qml/qmlboundsignal_p.h b/src/declarative/qml/qmlboundsignal_p.h
index 39c0c46..de8f91d 100644
--- a/src/declarative/qml/qmlboundsignal_p.h
+++ b/src/declarative/qml/qmlboundsignal_p.h
@@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE
-class QmlBoundSignal : public QmlExpressionObject
+class QmlBoundSignal : public QmlExpression
{
Q_OBJECT
public:
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index c7d45fd..0fdba64 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -51,7 +51,7 @@
#include <QStringList>
#include <qmlengine.h>
#include <QFileInfo>
-#include <qmlbindablevalue.h>
+#include "qmlbinding.h"
#include <QtCore/qdebug.h>
#include <QApplication>
@@ -431,23 +431,6 @@ QmlComponent::QmlComponent(QmlComponentPrivate &dd, QObject *parent)
{
}
-/*!
- Create a script object instance from this component. Returns a null
- script object if creation failed. It will create the instance in the
- engine's \l {QmlEngine::rootContext()}{root context}.
-
- Similar to QmlComponent::create(), but creates an object suitable
- for usage within scripts.
-*/
-QScriptValue QmlComponent::createObject()
-{
- Q_D(QmlComponent);
- QObject* ret = create();
- if(ret)
- return QmlEngine::qmlScriptObject(ret, d->engine);
- else
- return d->engine->scriptEngine()->nullValue();
-}
/*!
Create an object instance from this component. Returns 0 if creation
@@ -578,7 +561,7 @@ void QmlComponent::completeCreate()
QFxPerfTimer<QFxPerf::BindInit> bi;
#endif
for (int ii = 0; ii < d->bindValues.count(); ++ii) {
- QmlEnginePrivate::SimpleList<QmlBindableValue> bv =
+ QmlEnginePrivate::SimpleList<QmlBinding> bv =
d->bindValues.at(ii);
for (int jj = 0; jj < bv.count; ++jj) {
if(bv.at(jj))
diff --git a/src/declarative/qml/qmlcomponent.h b/src/declarative/qml/qmlcomponent.h
index 9c712df..45b26eb 100644
--- a/src/declarative/qml/qmlcomponent.h
+++ b/src/declarative/qml/qmlcomponent.h
@@ -77,17 +77,16 @@ public:
enum Status { Null, Ready, Loading, Error };
Status status() const;
- Q_INVOKABLE bool isNull() const;
- Q_INVOKABLE bool isReady() const;
- Q_INVOKABLE bool isError() const;
- Q_INVOKABLE bool isLoading() const;
+ bool isNull() const;
+ bool isReady() const;
+ bool isError() const;
+ bool isLoading() const;
QList<QmlError> errors() const;
Q_INVOKABLE QString errorsString() const;
QUrl url() const;
- Q_INVOKABLE QScriptValue createObject();
virtual QObject *create(QmlContext *context = 0);
virtual QObject *beginCreate(QmlContext *);
virtual void completeCreate();
diff --git a/src/declarative/qml/qmlcomponent_p.h b/src/declarative/qml/qmlcomponent_p.h
index 25af342..a7a3230 100644
--- a/src/declarative/qml/qmlcomponent_p.h
+++ b/src/declarative/qml/qmlcomponent_p.h
@@ -88,7 +88,7 @@ public:
int count;
QmlCompiledData *cc;
- QList<QmlEnginePrivate::SimpleList<QmlBindableValue> > bindValues;
+ QList<QmlEnginePrivate::SimpleList<QmlBinding> > bindValues;
QList<QmlEnginePrivate::SimpleList<QmlParserStatus> > parserStatus;
bool completePending;
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index 5bc70bc..bc2e6bf 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -292,7 +292,7 @@ QmlContext::~QmlContext()
d->childExpressions.begin();
iter != d->childExpressions.end();
++iter) {
- (*iter)->d->ctxt = 0;
+ (*iter)->d_func()->ctxt = 0;
}
for (int ii = 0; ii < d->contextObjects.count(); ++ii) {
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index a6f5b28..c4b3c0d 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -71,8 +71,9 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdir.h>
#include <qmlcomponent.h>
+#include <qmlbindablecomponent.h>
#include "private/qmlmetaproperty_p.h"
-#include <private/qmlbindablevalue_p.h>
+#include <private/qmlbinding_p.h>
#include <private/qmlvme_p.h>
#include <private/qmlenginedebug_p.h>
@@ -118,13 +119,13 @@ QmlEnginePrivate::~QmlEnginePrivate()
clear(parserStatus[ii]);
}
-void QmlEnginePrivate::clear(SimpleList<QmlBindableValue> &bvs)
+void QmlEnginePrivate::clear(SimpleList<QmlBinding> &bvs)
{
for (int ii = 0; ii < bvs.count; ++ii) {
- QmlBindableValue *bv = bvs.at(ii);
+ QmlBinding *bv = bvs.at(ii);
if(bv) {
- QmlBindableValuePrivate *p =
- static_cast<QmlBindableValuePrivate *>(QObjectPrivate::get(bv));
+ QmlBindingPrivate *p =
+ static_cast<QmlBindingPrivate *>(QObjectPrivate::get(bv));
p->mePtr = 0;
}
}
@@ -254,74 +255,6 @@ QScriptValue QmlEnginePrivate::propertyObject(const QScriptString &propName,
return QScriptValue();
}
-////////////////////////////////////////////////////////////////////
-
-bool QmlEnginePrivate::fetchCache(QmlBasicScriptNodeCache &cache, const QString &propName, QObject *obj)
-{
- QmlMetaProperty prop(obj, propName);
-
- if (!prop.isValid())
- return false;
-
- if (prop.needsChangedNotifier())
- capturedProperties << CapturedProperty(prop);
-
- if (prop.type() & QmlMetaProperty::Attached) {
-
- cache.object = obj;
- cache.type = QmlBasicScriptNodeCache::Attached;
- cache.attached = prop.d->attachedObject();
- return true;
-
- } else if (prop.type() & QmlMetaProperty::Property) {
-
- cache.object = obj;
- cache.type = QmlBasicScriptNodeCache::Core;
- cache.core = prop.property().propertyIndex();
- cache.coreType = prop.propertyType();
- return true;
-
- } else if (prop.type() & QmlMetaProperty::SignalProperty) {
-
- cache.object = obj;
- cache.type = QmlBasicScriptNodeCache::SignalProperty;
- cache.core = prop.coreIndex();
- return true;
-
- }
-
- return false;
-}
-
-bool QmlEnginePrivate::loadCache(QmlBasicScriptNodeCache &cache, const QString &propName, QmlContextPrivate *context)
-{
- while(context) {
-
- QHash<QString, int>::ConstIterator iter =
- context->propertyNames.find(propName);
- if (iter != context->propertyNames.end()) {
- cache.object = 0;
- cache.type = QmlBasicScriptNodeCache::Variant;
- cache.context = context;
- cache.contextIndex = *iter;
- capturedProperties << CapturedProperty(context->q_ptr, -1, *iter + context->notifyIndex);
- return true;
- }
-
- foreach(QObject *obj, context->defaultObjects) {
- if (fetchCache(cache, propName, obj))
- return true;
- }
-
- if (context->parent)
- context = context->parent->d_func();
- else
- context = 0;
- }
- return false;
-}
-
-
/*!
\class QmlEngine
\brief The QmlEngine class provides an environment for instantiating QML components.
@@ -651,19 +584,20 @@ QScriptValue QmlEngine::qmlScriptObject(QObject* object, QmlEngine* engine)
*/
QScriptValue QmlEngine::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
{
- QmlComponent* c;
+ QmlBindableComponent* c;
QmlEngine* activeEngine = qobject_cast<QmlEngine*>(
engine->globalObject().property(QLatin1String("qmlEngine")).toQObject());
+ QmlContext* context =activeEngine->d_func()->currentExpression->context();
if(ctxt->argumentCount() != 1 || !activeEngine){
- c = new QmlComponent(activeEngine);
+ c = new QmlBindableComponent(activeEngine);
}else{
- QUrl url = QUrl(activeEngine->d_func()->currentExpression->context()
- ->resolvedUrl(ctxt->argument(0).toString()));
+ QUrl url = QUrl(context->resolvedUrl(ctxt->argument(0).toString()));
if(!url.isValid()){
url = QUrl(ctxt->argument(0).toString());
}
- c = new QmlComponent(activeEngine, url, activeEngine);
+ c = new QmlBindableComponent(activeEngine, url, activeEngine);
}
+ c->setContext(context);
return engine->newQObject(c);
}
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index f459dc5..47d2397 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -93,11 +93,10 @@ public:
void init();
- bool fetchCache(QmlBasicScriptNodeCache &cache, const QString &propName, QObject *);
- bool loadCache(QmlBasicScriptNodeCache &cache, const QString &propName, QmlContextPrivate *context);
-
- QScriptClass::QueryFlags queryObject(const QString &name, uint *id, QObject *);
- QScriptValue propertyObject(const QScriptString &propName, QObject *, uint id = 0);
+ QScriptClass::QueryFlags queryObject(const QString &name, uint *id,
+ QObject *);
+ QScriptValue propertyObject(const QScriptString &propName, QObject *,
+ uint id = 0);
struct CapturedProperty {
CapturedProperty(QObject *o, int c, int n)
@@ -152,10 +151,10 @@ public:
}
};
- static void clear(SimpleList<QmlBindableValue> &);
+ static void clear(SimpleList<QmlBinding> &);
static void clear(SimpleList<QmlParserStatus> &);
- QList<SimpleList<QmlBindableValue> > bindValues;
+ QList<SimpleList<QmlBinding> > bindValues;
QList<SimpleList<QmlParserStatus> > parserStatus;
QmlComponent *rootComponent;
diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp
index 2aa1a8a..ea0e9aa 100644
--- a/src/declarative/qml/qmlexpression.cpp
+++ b/src/declarative/qml/qmlexpression.cpp
@@ -50,53 +50,72 @@ Q_DECLARE_METATYPE(QList<QObject *>);
QT_BEGIN_NAMESPACE
-DEFINE_BOOL_CONFIG_OPTION(qmlDebugger, QML_DEBUGGER)
-
-QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b)
-: q(b), ctxt(0), expressionFunctionValid(false), sseData(0), proxy(0), me(0), trackChange(false), line(-1), id(0), log(0)
+QmlExpressionPrivate::QmlExpressionPrivate()
+: ctxt(0), expressionFunctionValid(false), sseData(0), me(0), trackChange(true), line(-1), id(0), guardList(0), guardListLength(0)
{
}
-QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, void *expr, QmlRefCount *rc)
-: q(b), ctxt(0), expressionFunctionValid(false), sse((const char *)expr, rc), sseData(0), proxy(0), me(0), trackChange(true), line(-1), id(0), log(0)
+void QmlExpressionPrivate::init(QmlContext *ctxt, const QString &expr,
+ QObject *me)
{
+ Q_Q(QmlExpression);
+
+ expression = expr;
+
+ this->ctxt = ctxt;
+ if (ctxt && ctxt->engine())
+ id = ctxt->engine()->d_func()->getUniqueId();
+ if (ctxt)
+ ctxt->d_func()->childExpressions.insert(q);
+ this->me = me;
}
-QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, const QString &expr)
-: q(b), ctxt(0), expression(expr), expressionFunctionValid(false), sseData(0), proxy(0), me(0), trackChange(true), line(-1), id(0), log(0)
+void QmlExpressionPrivate::init(QmlContext *ctxt, void *expr, QmlRefCount *rc,
+ QObject *me)
{
+ Q_Q(QmlExpression);
+
+ sse.load((const char *)expr, rc);
+
+ this->ctxt = ctxt;
+ if (ctxt && ctxt->engine())
+ id = ctxt->engine()->d_func()->getUniqueId();
+ if (ctxt)
+ ctxt->d_func()->childExpressions.insert(q);
+ this->me = me;
}
QmlExpressionPrivate::~QmlExpressionPrivate()
{
sse.deleteScriptState(sseData);
sseData = 0;
- delete proxy;
- delete log;
+ if (guardList) { delete [] guardList; guardList = 0; }
}
/*!
+ \class QmlExpression
+ \brief The QmlExpression class evaluates ECMAScript in a QML context.
+*/
+
+/*!
Create an invalid QmlExpression.
As the expression will not have an associated QmlContext, this will be a
null expression object and its value will always be an invalid QVariant.
*/
QmlExpression::QmlExpression()
-: d(new QmlExpressionPrivate(this))
+: QObject(*new QmlExpressionPrivate, 0)
{
}
-/*! \internal */
+/*! \internal */
QmlExpression::QmlExpression(QmlContext *ctxt, void *expr,
- QmlRefCount *rc, QObject *me)
-: d(new QmlExpressionPrivate(this, expr, rc))
+ QmlRefCount *rc, QObject *me,
+ QmlExpressionPrivate &dd)
+: QObject(dd, 0)
{
- d->ctxt = ctxt;
- if(ctxt && ctxt->engine())
- d->id = ctxt->engine()->d_func()->getUniqueId();
- if(ctxt)
- ctxt->d_func()->childExpressions.insert(this);
- d->me = me;
+ Q_D(QmlExpression);
+ d->init(ctxt, expr, rc, me);
}
/*!
@@ -108,14 +127,19 @@ QmlExpression::QmlExpression(QmlContext *ctxt, void *expr,
*/
QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expression,
QObject *scope)
-: d(new QmlExpressionPrivate(this, expression))
+: QObject(*new QmlExpressionPrivate, 0)
{
- d->ctxt = ctxt;
- if(ctxt && ctxt->engine())
- d->id = ctxt->engine()->d_func()->getUniqueId();
- if(ctxt)
- ctxt->d_func()->childExpressions.insert(this);
- d->me = scope;
+ Q_D(QmlExpression);
+ d->init(ctxt, expression, scope);
+}
+
+/*! \internal */
+QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expression,
+ QObject *scope, QmlExpressionPrivate &dd)
+: QObject(dd, 0)
+{
+ Q_D(QmlExpression);
+ d->init(ctxt, expression, scope);
}
/*!
@@ -123,9 +147,9 @@ QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expression,
*/
QmlExpression::~QmlExpression()
{
+ Q_D(QmlExpression);
if (d->ctxt)
d->ctxt->d_func()->childExpressions.remove(this);
- delete d; d = 0;
}
/*!
@@ -134,6 +158,7 @@ QmlExpression::~QmlExpression()
*/
QmlEngine *QmlExpression::engine() const
{
+ Q_D(const QmlExpression);
return d->ctxt?d->ctxt->engine():0;
}
@@ -143,6 +168,7 @@ QmlEngine *QmlExpression::engine() const
*/
QmlContext *QmlExpression::context() const
{
+ Q_D(const QmlExpression);
return d->ctxt;
}
@@ -151,6 +177,7 @@ QmlContext *QmlExpression::context() const
*/
QString QmlExpression::expression() const
{
+ Q_D(const QmlExpression);
if (d->sse.isValid())
return QLatin1String(d->sse.expression());
else
@@ -170,12 +197,13 @@ void QmlExpression::clearExpression()
*/
void QmlExpression::setExpression(const QString &expression)
{
+ Q_D(QmlExpression);
if (d->sseData) {
d->sse.deleteScriptState(d->sseData);
d->sseData = 0;
}
- delete d->proxy; d->proxy = 0;
+ d->clearGuards();
d->expression = expression;
d->expressionFunctionValid = false;
@@ -184,18 +212,6 @@ void QmlExpression::setExpression(const QString &expression)
d->sse.clear();
}
-/*!
- Called by QmlExpression each time the expression value changes from the
- last time it was evaluated. The expression must have been evaluated at
- least once (by calling QmlExpression::value()) before this callback will
- be made.
-
- The default implementation does nothing.
-*/
-void QmlExpression::valueChanged()
-{
-}
-
QVariant QmlExpressionPrivate::evalSSE(QmlBasicScript::CacheState &cacheState)
{
#ifdef Q_ENABLE_PERFORMANCE_LOG
@@ -318,6 +334,8 @@ QVariant QmlExpressionPrivate::evalQtScript()
*/
QVariant QmlExpression::value()
{
+ Q_D(QmlExpression);
+
QVariant rv;
if (!d->ctxt || !engine() || (!d->sse.isValid() && d->expression.isEmpty()))
return rv;
@@ -329,7 +347,11 @@ QVariant QmlExpression::value()
QmlBasicScript::CacheState cacheState = QmlBasicScript::Reset;
QmlEnginePrivate *ep = engine()->d_func();
+
QmlExpression *lastCurrentExpression = ep->currentExpression;
+ QPODVector<QmlEnginePrivate::CapturedProperty> lastCapturedProperties;
+ ep->capturedProperties.copyAndClear(lastCapturedProperties);
+
ep->currentExpression = this;
if (d->sse.isValid()) {
@@ -340,90 +362,13 @@ QVariant QmlExpression::value()
ep->currentExpression = lastCurrentExpression;
- if (cacheState != QmlBasicScript::NoChange) {
- if (cacheState != QmlBasicScript::Incremental && d->proxy) {
- delete d->proxy;
- d->proxy = 0;
- }
-
- if (trackChange() && ep->capturedProperties.count()) {
- if (!d->proxy)
- d->proxy = new QmlExpressionBindProxy(this);
-
- static int changedIndex = -1;
- if (changedIndex == -1)
- changedIndex = QmlExpressionBindProxy::staticMetaObject.indexOfSlot("changed()");
-
- if(qmlDebugger()) {
- QmlExpressionLog log;
- log.setTime(engine()->d_func()->getUniqueId());
- log.setExpression(expression());
- log.setResult(rv);
-
- for (int ii = 0; ii < ep->capturedProperties.count(); ++ii) {
- const QmlEnginePrivate::CapturedProperty &prop =
- ep->capturedProperties.at(ii);
-
- if (prop.notifyIndex != -1) {
- QMetaObject::connect(prop.object, prop.notifyIndex,
- d->proxy, changedIndex);
- } else {
- const QMetaObject *metaObj = prop.object->metaObject();
- QMetaProperty metaProp =
- metaObj->property(prop.coreIndex);
-
- QString warn = QLatin1String("Expression depends on non-NOTIFYable property: ") +
- QLatin1String(metaObj->className()) +
- QLatin1String("::") +
- QLatin1String(metaProp.name());
- log.addWarning(warn);
- }
- }
- d->addLog(log);
-
- } else {
- bool outputWarningHeader = false;
- for (int ii = 0; ii < ep->capturedProperties.count(); ++ii) {
- const QmlEnginePrivate::CapturedProperty &prop =
- ep->capturedProperties.at(ii);
-
- if (prop.notifyIndex != -1) {
- QMetaObject::connect(prop.object, prop.notifyIndex,
- d->proxy, changedIndex);
- } else {
- if (!outputWarningHeader) {
- outputWarningHeader = true;
- qWarning() << "QmlExpression: Expression" << expression() << "depends on non-NOTIFYable properties:";
- }
-
- const QMetaObject *metaObj = prop.object->metaObject();
- QMetaProperty metaProp =
- metaObj->property(prop.coreIndex);
-
- qWarning().nospace() << " " << metaObj->className()
- << "::" << metaProp.name();
- }
- }
- }
- } else {
- QmlExpressionLog log;
- log.setTime(engine()->d_func()->getUniqueId());
- log.setExpression(expression());
- log.setResult(rv);
- d->addLog(log);
- }
-
- } else {
- if(qmlDebugger()) {
- QmlExpressionLog log;
- log.setTime(engine()->d_func()->getUniqueId());
- log.setExpression(expression());
- log.setResult(rv);
- d->addLog(log);
- }
+ if ((!trackChange() || !ep->capturedProperties.count()) && d->guardList) {
+ d->clearGuards();
+ } else if(trackChange()) {
+ d->updateGuards(ep->capturedProperties);
}
- ep->capturedProperties.clear();
+ lastCapturedProperties.copyAndClear(ep->capturedProperties);
return rv;
}
@@ -435,7 +380,8 @@ QVariant QmlExpression::value()
*/
bool QmlExpression::isConstant() const
{
- return d->proxy == 0;
+ Q_D(const QmlExpression);
+ return !d->guardList;
}
/*!
@@ -443,6 +389,7 @@ bool QmlExpression::isConstant() const
*/
bool QmlExpression::trackChange() const
{
+ Q_D(const QmlExpression);
return d->trackChange;
}
@@ -463,6 +410,7 @@ bool QmlExpression::trackChange() const
*/
void QmlExpression::setTrackChange(bool trackChange)
{
+ Q_D(QmlExpression);
d->trackChange = trackChange;
}
@@ -472,6 +420,7 @@ void QmlExpression::setTrackChange(bool trackChange)
*/
void QmlExpression::setSourceLocation(const QUrl &fileName, int line)
{
+ Q_D(QmlExpression);
d->fileName = fileName;
d->line = line;
}
@@ -484,6 +433,7 @@ void QmlExpression::setSourceLocation(const QUrl &fileName, int line)
*/
QObject *QmlExpression::scopeObject() const
{
+ Q_D(const QmlExpression);
return d->me;
}
@@ -492,144 +442,138 @@ QObject *QmlExpression::scopeObject() const
*/
quint32 QmlExpression::id() const
{
+ Q_D(const QmlExpression);
return d->id;
}
-/*!
- \class QmlExpression
- \brief The QmlExpression class evaluates ECMAScript in a QML context.
-*/
-
-/*!
- \class QmlExpressionObject
- \brief The QmlExpressionObject class extends QmlExpression with signals and slots.
-
- To remain as lightweight as possible, QmlExpression does not inherit QObject
- and consequently cannot use signals or slots. For the cases where this is
- more convenient in an application, QmlExpressionObject can be used instead.
-
- QmlExpressionObject behaves identically to QmlExpression, except that the
- QmlExpressionObject::value() method is a slot, and the
- QmlExpressionObject::valueChanged() callback is a signal.
-*/
-/*!
- Create a QmlExpression with the specified \a parent.
-
- As the expression will not have an associated QmlContext, this will be a
- null expression object and its value will always be an invalid QVariant.
-*/
-QmlExpressionObject::QmlExpressionObject(QObject *parent)
-: QObject(parent)
-{
-}
-
-/*!
- Create a QmlExpressionObject with the specified \a parent.
-
- The \a expression ECMAScript will be executed in the \a ctxt QmlContext.
- If specified, the \a scope object's properties will also be in scope during
- the expression's execution.
-*/
-QmlExpressionObject::QmlExpressionObject(QmlContext *ctxt, const QString &expression, QObject *scope, QObject *parent)
-: QObject(parent), QmlExpression(ctxt, expression, scope)
-{
-}
-
-/*! \internal */
-QmlExpressionObject::QmlExpressionObject(QmlContext *ctxt, void *d, QmlRefCount *rc, QObject *me)
-: QmlExpression(ctxt, d, rc, me)
+/*! \internal */
+void QmlExpression::__q_notify()
{
+ valueChanged();
}
-/*!
- Returns the value of the expression, or an invalid QVariant if the
- expression is invalid or has an error.
-*/
-QVariant QmlExpressionObject::value()
+void QmlExpressionPrivate::clearGuards()
{
- return QmlExpression::value();
-}
+ Q_Q(QmlExpression);
-/*!
- \fn void QmlExpressionObject::valueChanged()
+ static int notifyIdx = -1;
+ if (notifyIdx == -1)
+ notifyIdx =
+ QmlExpression::staticMetaObject.indexOfMethod("__q_notify()");
- Emitted each time the expression value changes from the last time it was
- evaluated. The expression must have been evaluated at least once (by
- calling QmlExpressionObject::value()) before this signal will be emitted.
-*/
+ for (int ii = 0; ii < guardListLength; ++ii) {
+ if (guardList[ii].data()) {
+ QMetaObject::disconnect(guardList[ii].data(),
+ guardList[ii].notifyIndex,
+ q, notifyIdx);
+ }
+ }
-void QmlExpressionPrivate::addLog(const QmlExpressionLog &l)
-{
- if (!log)
- log = new QList<QmlExpressionLog>();
- log->append(l);
+ delete [] guardList; guardList = 0;
+ guardListLength = 0;
}
-QmlExpressionLog::QmlExpressionLog()
+void QmlExpressionPrivate::updateGuards(const QPODVector<QmlEnginePrivate::CapturedProperty> &properties)
{
-}
+ //clearGuards();
+ Q_Q(QmlExpression);
-QmlExpressionLog::QmlExpressionLog(const QmlExpressionLog &o)
-: m_time(o.m_time),
- m_expression(o.m_expression),
- m_result(o.m_result),
- m_warnings(o.m_warnings)
-{
-}
+ static int notifyIdx = -1;
+ if (notifyIdx == -1)
+ notifyIdx =
+ QmlExpression::staticMetaObject.indexOfMethod("__q_notify()");
-QmlExpressionLog::~QmlExpressionLog()
-{
-}
+ SignalGuard *newGuardList = 0;
+
+ if (properties.count() != guardListLength)
+ newGuardList = new SignalGuard[properties.count()];
-QmlExpressionLog &QmlExpressionLog::operator=(const QmlExpressionLog &o)
-{
- m_time = o.m_time;
- m_expression = o.m_expression;
- m_result = o.m_result;
- m_warnings = o.m_warnings;
- return *this;
-}
+ bool outputWarningHeader = false;
+ int hit = 0;
+ for (int ii = 0; ii < properties.count(); ++ii) {
+ const QmlEnginePrivate::CapturedProperty &property = properties.at(ii);
-void QmlExpressionLog::setTime(quint32 time)
-{
- m_time = time;
-}
-
-quint32 QmlExpressionLog::time() const
-{
- return m_time;
-}
+ bool needGuard = true;
+ if (ii >= guardListLength) {
+ // New guard
+ } else if(guardList[ii].data() == property.object &&
+ guardList[ii].notifyIndex == property.notifyIndex) {
+ // Cache hit
+ if (!guardList[ii].isDuplicate ||
+ (guardList[ii].isDuplicate && hit == ii)) {
+ needGuard = false;
+ ++hit;
+ }
+ } else if(guardList[ii].data() && !guardList[ii].isDuplicate) {
+ // Cache miss
+ QMetaObject::disconnect(guardList[ii].data(),
+ guardList[ii].notifyIndex,
+ q, notifyIdx);
+ }
+ /* else {
+ // Cache miss, but nothing to do
+ } */
+
+ if (needGuard) {
+ if (!newGuardList) {
+ newGuardList = new SignalGuard[properties.count()];
+ for (int jj = 0; jj < ii; ++jj)
+ newGuardList[jj] = guardList[jj];
+ }
-QString QmlExpressionLog::expression() const
-{
- return m_expression;
-}
+ if (property.notifyIndex != -1) {
+ bool existing = false;
+ for (int jj = 0; !existing && jj < ii; ++jj)
+ existing = newGuardList[jj].data() == property.object &&
+ newGuardList[jj].notifyIndex == property.notifyIndex;
+
+ newGuardList[ii] = property.object;
+ newGuardList[ii].notifyIndex = property.notifyIndex;
+ if (existing)
+ newGuardList[ii].isDuplicate = true;
+ else
+ QMetaObject::connect(property.object, property.notifyIndex,
+ q, notifyIdx);
+ } else {
+ if (!outputWarningHeader) {
+ outputWarningHeader = true;
+ qWarning() << "QmlExpression: Expression" << q->expression()
+ << "depends on non-NOTIFYable properties:";
+ }
-void QmlExpressionLog::setExpression(const QString &e)
-{
- m_expression = e;
-}
+ const QMetaObject *metaObj = property.object->metaObject();
+ QMetaProperty metaProp = metaObj->property(property.coreIndex);
-QStringList QmlExpressionLog::warnings() const
-{
- return m_warnings;
-}
+ qWarning().nospace() << " " << metaObj->className()
+ << "::" << metaProp.name();
+ }
+ } else if (newGuardList) {
+ newGuardList[ii] = guardList[ii];
+ }
+ }
-void QmlExpressionLog::addWarning(const QString &w)
-{
- m_warnings << w;
-}
+ for (int ii = properties.count(); ii < guardListLength; ++ii) {
+ if (guardList[ii].data() && !guardList[ii].isDuplicate) {
+ QMetaObject::disconnect(guardList[ii].data(),
+ guardList[ii].notifyIndex,
+ q, notifyIdx);
+ }
+ }
-QVariant QmlExpressionLog::result() const
-{
- return m_result;
+ if (newGuardList) {
+ if (guardList) delete [] guardList;
+ guardList = newGuardList;
+ guardListLength = properties.count();
+ }
}
-void QmlExpressionLog::setResult(const QVariant &r)
-{
- m_result = r;
-}
+/*!
+ \fn void QmlExpression::valueChanged()
+ Emitted each time the expression value changes from the last time it was
+ evaluated. The expression must have been evaluated at least once (by
+ calling QmlExpression::value()) before this signal will be emitted.
+*/
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h
index 3d8f8df..6db6ef9 100644
--- a/src/declarative/qml/qmlexpression.h
+++ b/src/declarative/qml/qmlexpression.h
@@ -57,12 +57,12 @@ class QmlEngine;
class QmlContext;
class QmlExpressionPrivate;
class QmlBasicScript;
-class Q_DECLARATIVE_EXPORT QmlExpression
+class Q_DECLARATIVE_EXPORT QmlExpression : public QObject
{
+ Q_OBJECT
public:
QmlExpression();
QmlExpression(QmlContext *, const QString &, QObject *);
- QmlExpression(QmlContext *, void *, QmlRefCount *rc, QObject *me);
virtual ~QmlExpression();
QmlEngine *engine() const;
@@ -71,7 +71,6 @@ public:
QString expression() const;
void clearExpression();
virtual void setExpression(const QString &);
- QVariant value();
bool isConstant() const;
bool trackChange() const;
@@ -82,31 +81,27 @@ public:
QObject *scopeObject() const;
quint32 id() const;
-protected:
+
+public Q_SLOTS:
+ QVariant value();
+
+Q_SIGNALS:
virtual void valueChanged();
+protected:
+ QmlExpression(QmlContext *, const QString &, QObject *,
+ QmlExpressionPrivate &dd);
+ QmlExpression(QmlContext *, void *, QmlRefCount *rc, QObject *me,
+ QmlExpressionPrivate &dd);
+
+private Q_SLOTS:
+ void __q_notify();
+
private:
+ Q_DECLARE_PRIVATE(QmlExpression)
friend class QmlExpressionBindProxy;
friend class QmlDebugger;
friend class QmlContext;
- QmlExpressionPrivate *d;
-};
-
-// LK: can't we merge with QmlExpression????
-class Q_DECLARATIVE_EXPORT QmlExpressionObject : public QObject,
- public QmlExpression
-{
- Q_OBJECT
-public:
- QmlExpressionObject(QObject *parent = 0);
- QmlExpressionObject(QmlContext *, const QString &, QObject *scope, QObject *parent = 0);
- QmlExpressionObject(QmlContext *, void *, QmlRefCount *, QObject *);
-
-public Q_SLOTS:
- QVariant value();
-
-Q_SIGNALS:
- void valueChanged();
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h
index 09745a3..41b7749 100644
--- a/src/declarative/qml/qmlexpression_p.h
+++ b/src/declarative/qml/qmlexpression_p.h
@@ -55,23 +55,24 @@
#include "qmlbasicscript_p.h"
#include "qmlexpression.h"
+#include "qmlengine_p.h"
+#include <private/qguard_p.h>
#include <QtScript/qscriptvalue.h>
QT_BEGIN_NAMESPACE
class QmlExpression;
class QString;
-class QmlExpressionLog;
-class QmlExpressionBindProxy;
-class QmlExpressionPrivate
+class QmlExpressionPrivate : public QObjectPrivate
{
+ Q_DECLARE_PUBLIC(QmlExpression)
public:
- QmlExpressionPrivate(QmlExpression *);
- QmlExpressionPrivate(QmlExpression *, const QString &expr);
- QmlExpressionPrivate(QmlExpression *, void *expr, QmlRefCount *rc);
+ QmlExpressionPrivate();
~QmlExpressionPrivate();
- QmlExpression *q;
+ void init(QmlContext *, const QString &, QObject *);
+ void init(QmlContext *, void *, QmlRefCount *, QObject *);
+
QmlContext *ctxt;
QString expression;
bool expressionFunctionValid;
@@ -79,7 +80,6 @@ public:
QmlBasicScript sse;
void *sseData;
- QmlExpressionBindProxy *proxy;
QObject *me;
bool trackChange;
@@ -88,53 +88,30 @@ public:
quint32 id;
- void addLog(const QmlExpressionLog &);
- QList<QmlExpressionLog> *log;
-
QVariant evalSSE(QmlBasicScript::CacheState &cacheState);
QVariant evalQtScript();
-};
-
-class QmlExpressionBindProxy : public QObject
-{
-Q_OBJECT
-public:
- QmlExpressionBindProxy(QmlExpression *be)
- :e(be) { }
-
-private:
- QmlExpression *e;
-
-private Q_SLOTS:
- void changed() { e->valueChanged(); }
-};
-
-class QmlExpressionLog
-{
-public:
- QmlExpressionLog();
- QmlExpressionLog(const QmlExpressionLog &);
- ~QmlExpressionLog();
-
- QmlExpressionLog &operator=(const QmlExpressionLog &);
-
- void setTime(quint32);
- quint32 time() const;
-
- QString expression() const;
- void setExpression(const QString &);
-
- QStringList warnings() const;
- void addWarning(const QString &);
-
- QVariant result() const;
- void setResult(const QVariant &);
-private:
- quint32 m_time;
- QString m_expression;
- QVariant m_result;
- QStringList m_warnings;
+ struct SignalGuard : public QGuard<QObject> {
+ SignalGuard() : isDuplicate(false), notifyIndex(-1) {}
+
+ SignalGuard &operator=(QObject *obj) {
+ QGuard<QObject>::operator=(obj);
+ return *this;
+ }
+ SignalGuard &operator=(const SignalGuard &o) {
+ QGuard<QObject>::operator=(o);
+ isDuplicate = o.isDuplicate;
+ notifyIndex = o.notifyIndex;
+ return *this;
+ }
+
+ bool isDuplicate:1;
+ int notifyIndex:31;
+ };
+ SignalGuard *guardList;
+ int guardListLength;
+ void updateGuards(const QPODVector<QmlEnginePrivate::CapturedProperty> &properties);
+ void clearGuards();
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index dea3467..daa4242 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -44,7 +44,7 @@
#include <qml.h>
#include <private/qfxperf_p.h>
#include <QStringList>
-#include <qmlbindablevalue.h>
+#include "qmlbinding.h"
#include <qmlcontext.h>
#include "qmlboundsignal_p.h"
#include <math.h>
@@ -260,7 +260,7 @@ QmlMetaProperty::QmlMetaProperty(const QmlMetaProperty &other)
\value Unknown The category is unknown. This will never be returned from propertyCategory()
\value InvalidProperty The property is invalid.
- \value Bindable The property is a QmlBindableValue.
+ \value Bindable The property is a QmlBinding.
\value List The property is a QList pointer
\value QmlList The property is a QmlList pointer
\value Object The property is a QObject derived type pointer
@@ -294,7 +294,7 @@ QmlMetaPropertyPrivate::propertyCategory() const
int type = propertyType();
if (type == QmlMetaProperty::Invalid)
category = QmlMetaProperty::InvalidProperty;
- else if (type == qMetaTypeId<QmlBindableValue *>())
+ else if (type == qMetaTypeId<QmlBinding *>())
category = QmlMetaProperty::Bindable;
else if (QmlMetaType::isList(type))
category = QmlMetaProperty::List;
@@ -323,7 +323,7 @@ QmlMetaProperty::propertyCategory(const QMetaProperty &prop)
else
type = prop.type();
- if (type == qMetaTypeId<QmlBindableValue *>())
+ if (type == qMetaTypeId<QmlBinding *>())
return Bindable;
else if (QmlMetaType::isList(type))
return List;
@@ -510,7 +510,7 @@ QMetaProperty QmlMetaProperty::property() const
Returns the binding associated with this property, or 0 if no binding
exists.
*/
-QmlBindableValue *QmlMetaProperty::binding() const
+QmlBinding *QmlMetaProperty::binding() const
{
if (!isProperty() || type() & Attached)
return 0;
@@ -519,8 +519,8 @@ QmlBindableValue *QmlMetaProperty::binding() const
for (QObjectList::ConstIterator iter = children.begin();
iter != children.end(); ++iter) {
QObject *child = *iter;
- if (child->metaObject() == &QmlBindableValue::staticMetaObject) {
- QmlBindableValue *v = static_cast<QmlBindableValue *>(child);
+ if (child->metaObject() == &QmlBinding::staticMetaObject) {
+ QmlBinding *v = static_cast<QmlBinding *>(child);
if (v->property() == *this)
return v;
}
@@ -535,7 +535,7 @@ QmlBindableValue *QmlMetaProperty::binding() const
\a binding will be enabled, and the returned binding (if any) will be
disabled.
*/
-QmlBindableValue *QmlMetaProperty::setBinding(QmlBindableValue *binding) const
+QmlBinding *QmlMetaProperty::setBinding(QmlBinding *binding) const
{
if (!isProperty() || type() & Attached)
return 0;
@@ -544,8 +544,8 @@ QmlBindableValue *QmlMetaProperty::setBinding(QmlBindableValue *binding) const
for (QObjectList::ConstIterator iter = children.begin();
iter != children.end(); ++iter) {
QObject *child = *iter;
- if (child->metaObject() == &QmlBindableValue::staticMetaObject) {
- QmlBindableValue *v = static_cast<QmlBindableValue *>(child);
+ if (child->metaObject() == &QmlBinding::staticMetaObject) {
+ QmlBinding *v = static_cast<QmlBinding *>(child);
if (v->property() == *this && v->enabled()) {
v->setEnabled(false);
diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h
index 688c4fd..fdcf9be 100644
--- a/src/declarative/qml/qmlmetaproperty.h
+++ b/src/declarative/qml/qmlmetaproperty.h
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QObject;
-class QmlBindableValue;
+class QmlBinding;
class QStringList;
class QVariant;
struct QMetaObject;
@@ -121,8 +121,8 @@ public:
QMetaProperty property() const;
- QmlBindableValue *binding() const;
- QmlBindableValue *setBinding(QmlBindableValue *) const;
+ QmlBinding *binding() const;
+ QmlBinding *setBinding(QmlBinding *) const;
static QmlMetaProperty createProperty(QObject *, const QString &);
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index 8eb58c8..9eed3f1 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -47,7 +47,6 @@
#include <QSizeF>
#include <QRectF>
#include <private/qmlvme_p.h>
-#include <qmlbindablevalue.h>
#include <private/qfxperf_p.h>
#include <qml.h>
#include "private/qmlcomponent_p.h"
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index f468cd0..58b8689 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -57,13 +57,13 @@
#include <qmlengine.h>
#include <qmlcontext.h>
#include <qmlcomponent.h>
-#include <qmlbindablevalue.h>
+#include <qmlbinding.h>
#include <private/qmlengine_p.h>
#include <private/qmlcomponent_p.h>
#include "private/qmlvmemetaobject_p.h"
#include <QtCore/qdebug.h>
#include <QtCore/qvarlengtharray.h>
-#include <private/qmlbindablevalue_p.h>
+#include <private/qmlbinding_p.h>
QT_BEGIN_NAMESPACE
@@ -137,7 +137,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
const QList<float> &floatData = comp->floatData;
- QmlEnginePrivate::SimpleList<QmlBindableValue> bindValues;
+ QmlEnginePrivate::SimpleList<QmlBinding> bindValues;
QmlEnginePrivate::SimpleList<QmlParserStatus> parserStatus;
QStack<ListInstance> qliststack;
@@ -153,7 +153,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
case QmlInstruction::Init:
{
if (instr.init.bindingsSize)
- bindValues = QmlEnginePrivate::SimpleList<QmlBindableValue>(instr.init.bindingsSize);
+ bindValues = QmlEnginePrivate::SimpleList<QmlBinding>(instr.init.bindingsSize);
if (instr.init.parserStatusSize)
parserStatus = QmlEnginePrivate::SimpleList<QmlParserStatus>(instr.init.parserStatusSize);
}
@@ -540,10 +540,10 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
QmlMetaProperty mp(target, instr.assignBinding.property,
(QmlMetaProperty::PropertyCategory)instr.assignBinding.category);
- QmlBindableValue *bind = new QmlBindableValue((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, 0);
+ QmlBinding *bind = new QmlBinding((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, 0);
bindValues.append(bind);
- QmlBindableValuePrivate *p =
- static_cast<QmlBindableValuePrivate *>(QObjectPrivate::get(bind));
+ QmlBindingPrivate *p =
+ static_cast<QmlBindingPrivate *>(QObjectPrivate::get(bind));
p->mePtr = &bindValues.values[bindValues.count - 1];
QFx_setParent_noEvent(bind, target);
@@ -560,10 +560,10 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
QmlMetaProperty mp(target, instr.assignBinding.property,
(QmlMetaProperty::PropertyCategory)instr.assignBinding.category);
- QmlBindableValue *bind = new QmlBindableValue(primitives.at(instr.assignBinding.value), context, ctxt);
+ QmlBinding *bind = new QmlBinding(primitives.at(instr.assignBinding.value), context, ctxt);
bindValues.append(bind);
- QmlBindableValuePrivate *p =
- static_cast<QmlBindableValuePrivate *>(QObjectPrivate::get(bind));
+ QmlBindingPrivate *p =
+ static_cast<QmlBindingPrivate *>(QObjectPrivate::get(bind));
p->mePtr = &bindValues.values[bindValues.count - 1];
QFx_setParent_noEvent(bind, target);
diff --git a/src/declarative/qml/qpodvector_p.h b/src/declarative/qml/qpodvector_p.h
index 101c62d..77f7425 100644
--- a/src/declarative/qml/qpodvector_p.h
+++ b/src/declarative/qml/qpodvector_p.h
@@ -63,8 +63,9 @@ class QPODVector
public:
QPODVector()
: m_count(0), m_capacity(0), m_data(0) {}
+ ~QPODVector() { if (m_data) ::free(m_data); }
- const T &at(int idx) {
+ const T &at(int idx) const {
return m_data[idx];
}
@@ -122,6 +123,16 @@ public:
return m_count;
}
+ void copyAndClear(QPODVector<T> &other) {
+ if (other.m_data) ::free(other.m_data);
+ other.m_count = m_count;
+ other.m_capacity = m_capacity;
+ other.m_data = m_data;
+ m_count = 0;
+ m_capacity = 0;
+ m_data = 0;
+ }
+
QPODVector<T> &operator<<(const T &v) { append(v); return *this; }
private:
QPODVector(const QPODVector &);