From 7ad493f4c217c7876d6ab51f5a679536b3a6e8b4 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 16 Jun 2011 15:38:40 +1000 Subject: [PATCH] Cleanup --- src/declarative/qml/qdeclarativebinding.cpp | 168 ++++++++--------- src/declarative/qml/qdeclarativebinding_p.h | 2 +- src/declarative/qml/qdeclarativebinding_p_p.h | 6 +- src/declarative/qml/qdeclarativeexpression.cpp | 251 +++++++++++-------------- src/declarative/qml/qdeclarativeexpression_p.h | 225 +++++++++++++++------- 5 files changed, 358 insertions(+), 294 deletions(-) diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index 6cca327..d1fdec5 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -218,13 +218,12 @@ void QDeclarativeBindingPrivate::refresh() } QDeclarativeBindingPrivate::QDeclarativeBindingPrivate() -: updating(false), enabled(false), deleted(0) +: updating(false), enabled(false) { } QDeclarativeBindingPrivate::~QDeclarativeBindingPrivate() { - if (deleted) *deleted = true; } QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj, @@ -311,13 +310,13 @@ QDeclarativeProperty QDeclarativeBinding::property() const void QDeclarativeBinding::setEvaluateFlags(EvaluateFlags flags) { Q_D(QDeclarativeBinding); - d->setEvaluateFlags(QDeclarativeQtScriptExpression::EvaluateFlags(static_cast(flags))); + d->setRequiresThisObject(flags & RequiresThisObject); } QDeclarativeBinding::EvaluateFlags QDeclarativeBinding::evaluateFlags() const { Q_D(const QDeclarativeBinding); - return QDeclarativeBinding::EvaluateFlags(static_cast(d->evaluateFlags())); + return d->requiresThisObject()?RequiresThisObject:None; } @@ -336,6 +335,57 @@ public: } }; +bool QDeclarativeBindingPrivate::writeBindingResult(QDeclarativeJavaScriptExpression *expression, + QDeclarativeProperty &prop, v8::Handle result, + bool isUndefined, QDeclarativePropertyPrivate::WriteFlags flags) +{ + QV8Engine *engine = QDeclarativeEnginePrivate::getV8Engine(expression->context()->engine); + QDeclarativeDeleteWatcher watcher(expression); + + QVariant value; + + if (isUndefined) { + } else if (prop.propertyTypeCategory() == QDeclarativeProperty::List) { + value = engine->toVariant(result, qMetaTypeId >()); + } else if (result->IsNull() && prop.propertyTypeCategory() == QDeclarativeProperty::Object) { + value = QVariant::fromValue((QObject *)0); + } else { + value = engine->toVariant(result, prop.propertyType()); + } + + if (expression->error.isValid()) { + return false; + } else if (isUndefined && prop.isResettable()) { + prop.reset(); + } else if (isUndefined && prop.propertyType() == qMetaTypeId()) { + QDeclarativePropertyPrivate::write(prop, QVariant(), flags); + } else if (isUndefined) { + expression->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + + QLatin1String(QMetaType::typeName(prop.propertyType())) + + QLatin1String(" ") + prop.name()); + return false; + } else if (result->IsFunction()) { + expression->error.setDescription(QLatin1String("Unable to assign a function to a property.")); + return false; + } else if (prop.object() && !QDeclarativePropertyPrivate::write(prop, value, flags)) { + + if (watcher.wasDeleted()) + return true; + + const char *valueType = 0; + if (value.userType() == QVariant::Invalid) valueType = "null"; + else valueType = QMetaType::typeName(value.userType()); + + expression->error.setDescription(QLatin1String("Unable to assign ") + + QLatin1String(valueType) + + QLatin1String(" to ") + + QLatin1String(QMetaType::typeName(prop.propertyType()))); + return false; + } + + return true; +} + void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) { Q_D(QDeclarativeBinding); @@ -346,8 +396,8 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) if (!d->updating) { QDeclarativeBindingProfiler prof(this); d->updating = true; - bool wasDeleted = false; - d->deleted = &wasDeleted; + + QDeclarativeDeleteWatcher watcher(d); if (d->property.propertyType() == qMetaTypeId()) { @@ -361,9 +411,6 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) QMetaObject::WriteProperty, idx, a); - if (wasDeleted) - return; - } else { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(d->context()->engine); ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation. @@ -375,99 +422,36 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) v8::Context::Scope scope(ep->v8engine.context()); v8::Local result = d->v8value(0, &isUndefined); - if (wasDeleted) { - ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete. - return; + bool needsErrorData = false; + if (!watcher.wasDeleted() && !d->error.isValid()) { + needsErrorData = !d->writeBindingResult(d, d->property, result, isUndefined, flags); } - if (isUndefined) { - } else if (d->property.propertyTypeCategory() == QDeclarativeProperty::List) { - value = ep->v8engine.toVariant(result, qMetaTypeId >()); - } else if (result->IsNull() && d->property.propertyTypeCategory() == QDeclarativeProperty::Object) { - value = QVariant::fromValue((QObject *)0); - } else { - value = ep->v8engine.toVariant(result, d->property.propertyType()); - } - - - if (d->error.isValid()) { + if (!watcher.wasDeleted()) { + + if (needsErrorData) { + QUrl url = QUrl(d->url); + int line = d->line; + if (url.isEmpty()) url = QUrl(QLatin1String("")); - } else if (isUndefined && d->property.isResettable()) { - - d->property.reset(); - - } else if (isUndefined && d->property.propertyType() == qMetaTypeId()) { - - QDeclarativePropertyPrivate::write(d->property, QVariant(), flags); - - } else if (isUndefined) { - - QUrl url = QUrl(d->url); - int line = d->line; - if (url.isEmpty()) url = QUrl(QLatin1String("")); - - d->error.setUrl(url); - d->error.setLine(line); - d->error.setColumn(-1); - d->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + - QLatin1String(QMetaType::typeName(d->property.propertyType())) + - QLatin1String(" ") + d->property.name()); - - } else if (result->IsFunction()) { - - QUrl url = QUrl(d->url); - int line = d->line; - if (url.isEmpty()) url = QUrl(QLatin1String("")); - - d->error.setUrl(url); - d->error.setLine(line); - d->error.setColumn(-1); - d->error.setDescription(QLatin1String("Unable to assign a function to a property.")); - - } else if (d->property.object() && - !QDeclarativePropertyPrivate::write(d->property, value, flags)) { - - if (wasDeleted) { - ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete. - return; + d->error.setUrl(url); + d->error.setLine(line); + d->error.setColumn(-1); } - QUrl url = QUrl(d->url); - int line = d->line; - if (url.isEmpty()) url = QUrl(QLatin1String("")); - - const char *valueType = 0; - if (value.userType() == QVariant::Invalid) valueType = "null"; - else valueType = QMetaType::typeName(value.userType()); - - d->error.setUrl(url); - d->error.setLine(line); - d->error.setColumn(-1); - d->error.setDescription(QLatin1String("Unable to assign ") + - QLatin1String(valueType) + - QLatin1String(" to ") + - QLatin1String(QMetaType::typeName(d->property.propertyType()))); - } - - if (wasDeleted) { - ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete. - return; - } + if (d->error.isValid()) { + if (!d->addError(ep)) ep->warning(this->error()); + } else { + d->removeError(); + } - if (d->error.isValid()) { - if (!d->addError(ep)) ep->warning(this->error()); - } else { - d->removeError(); } - // at this point, the binding has been evaluated. If any scarce - // resources were copied during the evaluation of the binding, - // we need to release those copies. - ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete. + ep->dereferenceScarceResources(); } - d->updating = false; - d->deleted = 0; + if (!watcher.wasDeleted()) + d->updating = false; } else { qmlInfo(d->property.object()) << tr("Binding loop detected for property \"%1\"").arg(d->property.name()); } diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h index f0b3335..e646c86 100644 --- a/src/declarative/qml/qdeclarativebinding_p.h +++ b/src/declarative/qml/qdeclarativebinding_p.h @@ -147,7 +147,7 @@ class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeBinding : public QDeclarativeExpr { Q_OBJECT public: - enum EvaluateFlag { RequiresThisObject = 0x01 }; + enum EvaluateFlag { None = 0x00, RequiresThisObject = 0x01 }; Q_DECLARE_FLAGS(EvaluateFlags, EvaluateFlag) QDeclarativeBinding(const QString &, QObject *, QDeclarativeContext *, QObject *parent=0); diff --git a/src/declarative/qml/qdeclarativebinding_p_p.h b/src/declarative/qml/qdeclarativebinding_p_p.h index 9e6f75b..1b1b03b 100644 --- a/src/declarative/qml/qdeclarativebinding_p_p.h +++ b/src/declarative/qml/qdeclarativebinding_p_p.h @@ -69,6 +69,10 @@ public: virtual void emitValueChanged(); + static bool writeBindingResult(QDeclarativeJavaScriptExpression *expression, + QDeclarativeProperty &prop, v8::Handle value, bool isUndefined, + QDeclarativePropertyPrivate::WriteFlags flags); + protected: virtual void refresh(); @@ -76,8 +80,6 @@ private: bool updating:1; bool enabled:1; QDeclarativeProperty property; - - bool *deleted; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 7d2803f..d709d5c 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -68,30 +68,27 @@ bool QDeclarativeDelayedError::addError(QDeclarativeEnginePrivate *e) return true; } -QDeclarativeQtScriptExpression::QDeclarativeQtScriptExpression() -: dataRef(0), extractExpressionFromFunction(false), expressionFunctionMode(ExplicitContext), - scopeObject(0), trackChange(false), guardList(0), guardListLength(0), guardObject(0), - guardObjectNotifyIndex(-1), deleted(0) +QDeclarativeJavaScriptExpression::QDeclarativeJavaScriptExpression() +: m_requiresThisObject(0), m_useSharedContext(0), m_notifyOnValueChanged(0), + m_scopeObject(0), m_notifyObject(0), m_notifyIndex(-1) { } -QDeclarativeQtScriptExpression::~QDeclarativeQtScriptExpression() +QDeclarativeJavaScriptExpression::~QDeclarativeJavaScriptExpression() { - qPersistentDispose(v8function); - qPersistentDispose(v8qmlscope); - - if (guardList) { delete [] guardList; guardList = 0; } - if (dataRef) dataRef->release(); - if (deleted) *deleted = true; } QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate() -: expressionFunctionValid(true), line(-1) +: expressionFunctionValid(true), extractExpressionFromFunction(false), line(-1), dataRef(0) { } QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate() { + qPersistentDispose(v8qmlscope); + qPersistentDispose(v8function); + if (dataRef) dataRef->release(); + dataRef = 0; } void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr, @@ -100,7 +97,7 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QS expression = expr; QDeclarativeAbstractExpression::setContext(ctxt); - scopeObject = me; + setScopeObject(me); expressionFunctionValid = false; } @@ -108,10 +105,10 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, v8::Hand QObject *me) { QDeclarativeAbstractExpression::setContext(ctxt); - scopeObject = me; + setScopeObject(me); v8function = qPersistentNew(func); - expressionFunctionMode = ExplicitContext; + setUseSharedContext(false); expressionFunctionValid = true; extractExpressionFromFunction = true; } @@ -139,11 +136,12 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *ex v8function = evalFunction(ctxt, me, expression, url, line, &v8qmlscope); - expressionFunctionMode = ExplicitContext; + setUseSharedContext(false); + expressionFunctionValid = true; QDeclarativeAbstractExpression::setContext(ctxt); - scopeObject = me; + setScopeObject(me); } // Callee owns the persistent handle @@ -405,7 +403,7 @@ void QDeclarativeExpression::setExpression(const QString &expression) { Q_D(QDeclarativeExpression); - d->resetNotifyOnChange(); + d->resetNotifyOnValueChanged(); d->expression = expression; d->expressionFunctionValid = false; qPersistentDispose(d->v8function); @@ -439,158 +437,138 @@ void QDeclarativeExpressionPrivate::exceptionToError(v8::Handle mes error.setDescription(qDescription); } -bool QDeclarativeQtScriptExpression::notifyOnValueChange() const +void QDeclarativeJavaScriptExpression::setNotifyOnValueChanged(bool v) { - return trackChange; + m_notifyOnValueChanged = v; + if (!v) guardList.clear(); } -void QDeclarativeQtScriptExpression::setNotifyOnValueChange(bool notify) +void QDeclarativeJavaScriptExpression::resetNotifyOnValueChanged() { - trackChange = notify; - if (!notify && guardList) - clearGuards(); + guardList.clear(); } -void QDeclarativeQtScriptExpression::resetNotifyOnChange() +void QDeclarativeJavaScriptExpression::setNotifyObject(QObject *object, int index) { - clearGuards(); -} + guardList.clear(); -void QDeclarativeQtScriptExpression::setNotifyObject(QObject *object, int notifyIndex) -{ - if (guardList) clearGuards(); - - if (!object || notifyIndex == -1) { - guardObject = 0; - notifyIndex = -1; - } else { - guardObject = object; - guardObjectNotifyIndex = notifyIndex; + m_notifyObject = object; + m_notifyIndex = index; + if (!object || index == -1) { + m_notifyObject = 0; + m_notifyIndex = -1; } } -void QDeclarativeQtScriptExpression::setEvaluateFlags(EvaluateFlags flags) -{ - evalFlags = flags; -} - -QDeclarativeQtScriptExpression::EvaluateFlags QDeclarativeQtScriptExpression::evaluateFlags() const -{ - return evalFlags; -} - -v8::Local QDeclarativeQtScriptExpression::v8value(QObject *secondaryScope, bool *isUndefined) +v8::Local QDeclarativeJavaScriptExpression::evaluate(v8::Handle function, bool *isUndefined) { Q_ASSERT(context() && context()->engine); - Q_ASSERT(!trackChange || (guardObject && guardObjectNotifyIndex != -1)); + Q_ASSERT(!notifyOnValueChanged() || (m_notifyObject && m_notifyIndex != -1)); - if (v8function.IsEmpty() || v8function->IsUndefined()) { + if (function.IsEmpty() || function->IsUndefined()) { if (isUndefined) *isUndefined = true; return v8::Local(); } - DeleteWatcher watcher(this); - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context()->engine); bool lastCaptureProperties = ep->captureProperties; QPODVector lastCapturedProperties; - ep->captureProperties = trackChange; + ep->captureProperties = notifyOnValueChanged(); ep->capturedProperties.copyAndClear(lastCapturedProperties); - v8::Local value = eval(secondaryScope, isUndefined); - - if (!watcher.wasDeleted() && trackChange) { - if (ep->capturedProperties.count() == 0) { - - if (guardList) clearGuards(); + QDeclarativeContextData *lastSharedContext = 0; + QObject *lastSharedScope = 0; - } else { + bool sharedContext = useSharedContext(); - updateGuards(ep->capturedProperties); + // All code that follows must check with watcher before it accesses data members + // incase we have been deleted. + QDeclarativeDeleteWatcher watcher(this); - } + if (sharedContext) { + lastSharedContext = ep->sharedContext; + lastSharedScope = ep->sharedScope; + ep->sharedContext = context(); + ep->sharedScope = scopeObject(); } - lastCapturedProperties.copyAndClear(ep->capturedProperties); - ep->captureProperties = lastCaptureProperties; - - return value; -} - -v8::Local QDeclarativeQtScriptExpression::eval(QObject *secondaryScope, bool *isUndefined) -{ - Q_ASSERT(context() && context()->engine); - DeleteWatcher watcher(this); - - QDeclarativeEngine *engine = context()->engine; - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - - QObject *restoreSecondaryScope = 0; - if (secondaryScope) - restoreSecondaryScope = ep->v8engine.contextWrapper()->setSecondaryScope(v8qmlscope, secondaryScope); - - v8::TryCatch try_catch; - - v8::Handle This; - - if (evaluateFlags() & RequiresThisObject) { - v8::Handle value = ep->v8engine.newQObject(scopeObject); - if (value->IsObject()) This = v8::Handle::Cast(value); - } - if (This.IsEmpty()) { - This = ep->v8engine.global(); - } - - v8::Local result = v8function->Call(This, 0, 0); + v8::Local result; + { + v8::TryCatch try_catch; + v8::Handle This = ep->v8engine.global(); + if (scopeObject() && requiresThisObject()) { + v8::Handle value = ep->v8engine.newQObject(scopeObject()); + if (value->IsObject()) This = v8::Handle::Cast(value); + } - if (secondaryScope) - ep->v8engine.contextWrapper()->setSecondaryScope(v8qmlscope, restoreSecondaryScope); + result = function->Call(This, 0, 0); - if (isUndefined) - *isUndefined = try_catch.HasCaught() || result->IsUndefined(); + if (isUndefined) + *isUndefined = try_catch.HasCaught() || result->IsUndefined(); - if (watcher.wasDeleted()) { - } else if (try_catch.HasCaught()) { - v8::Context::Scope scope(ep->v8engine.context()); - v8::Local message = try_catch.Message(); - if (!message.IsEmpty()) { - QDeclarativeExpressionPrivate::exceptionToError(message, error); + if (watcher.wasDeleted()) { + } else if (try_catch.HasCaught()) { + v8::Context::Scope scope(ep->v8engine.context()); + v8::Local message = try_catch.Message(); + if (!message.IsEmpty()) { + QDeclarativeExpressionPrivate::exceptionToError(message, error); + } else { + error = QDeclarativeError(); + } } else { error = QDeclarativeError(); } - } else { - error = QDeclarativeError(); } + if (sharedContext) { + ep->sharedContext = lastSharedContext; + ep->sharedScope = lastSharedScope; + } + + if (!watcher.wasDeleted() && notifyOnValueChanged()) { + guardList.updateGuards(m_notifyObject, m_notifyIndex, expressionString(), + ep->capturedProperties); + } + + lastCapturedProperties.copyAndClear(ep->capturedProperties); + ep->captureProperties = lastCaptureProperties; + return result; } -void QDeclarativeQtScriptExpression::updateGuards(const QPODVector &properties) +void QDeclarativeJavaScriptExpression::GuardList::updateGuards(QObject *notifyObject, int notifyIndex, + const QStringRef &expression, + const CapturedProperties &properties) { - Q_ASSERT(guardObject); - Q_ASSERT(guardObjectNotifyIndex != -1); + Q_ASSERT(notifyObject); + Q_ASSERT(notifyIndex != -1); - if (properties.count() != guardListLength) { + if (properties.count() == 0) { + clear(); + return; + } + + if (properties.count() != length) { QDeclarativeNotifierEndpoint *newGuardList = new QDeclarativeNotifierEndpoint[properties.count()]; - for (int ii = 0; ii < qMin(guardListLength, properties.count()); ++ii) - guardList[ii].copyAndClear(newGuardList[ii]); + for (int ii = 0; ii < qMin(length, properties.count()); ++ii) + endpoints[ii].copyAndClear(newGuardList[ii]); - delete [] guardList; - guardList = newGuardList; - guardListLength = properties.count(); + delete [] endpoints; + endpoints = newGuardList; + length = properties.count(); } bool outputWarningHeader = false; bool noChanges = true; for (int ii = 0; ii < properties.count(); ++ii) { - QDeclarativeNotifierEndpoint &guard = guardList[ii]; + QDeclarativeNotifierEndpoint &guard = endpoints[ii]; const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii); - guard.target = guardObject; - guard.targetMethod = guardObjectNotifyIndex; + guard.target = notifyObject; + guard.targetMethod = notifyIndex; if (property.notifier != 0) { @@ -602,7 +580,7 @@ void QDeclarativeQtScriptExpression::updateGuards(const QPODVector QDeclarativeExpressionPrivate::v8value(QObject *secondaryScope, bool *isUndefined) { if (!expressionFunctionValid) { - QDeclarativeEngine *engine = context()->engine; - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeRewrite::RewriteBinding rewriteBinding; rewriteBinding.setName(name); bool ok = true; const QString code = rewriteBinding(expression, &ok); - if (ok) v8function = evalFunction(context(), scopeObject, code, url, line, &v8qmlscope); - expressionFunctionMode = ExplicitContext; + if (ok) v8function = evalFunction(context(), scopeObject(), code, url, line, &v8qmlscope); + setUseSharedContext(false); expressionFunctionValid = true; } - return QDeclarativeQtScriptExpression::v8value(secondaryScope, isUndefined); + + if (secondaryScope) { + v8::Local result; + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context()->engine); + QObject *restoreSecondaryScope = 0; + restoreSecondaryScope = ep->v8engine.contextWrapper()->setSecondaryScope(v8qmlscope, secondaryScope); + result = evaluate(v8function, isUndefined); + ep->v8engine.contextWrapper()->setSecondaryScope(v8qmlscope, restoreSecondaryScope); + return result; + } else { + return evaluate(v8function, isUndefined); + } } QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined) @@ -716,7 +702,7 @@ value changes. bool QDeclarativeExpression::notifyOnValueChanged() const { Q_D(const QDeclarativeExpression); - return d->notifyOnValueChange(); + return d->notifyOnValueChanged(); } /*! @@ -738,7 +724,7 @@ bool QDeclarativeExpression::notifyOnValueChanged() const void QDeclarativeExpression::setNotifyOnValueChanged(bool notifyOnChange) { Q_D(QDeclarativeExpression); - d->setNotifyOnValueChange(notifyOnChange); + d->setNotifyOnValueChanged(notifyOnChange); } /*! @@ -781,7 +767,7 @@ void QDeclarativeExpression::setSourceLocation(const QString &url, int line) QObject *QDeclarativeExpression::scopeObject() const { Q_D(const QDeclarativeExpression); - return d->scopeObject; + return d->scopeObject(); } /*! @@ -827,13 +813,6 @@ void QDeclarativeExpressionPrivate::_q_notify() emitValueChanged(); } -void QDeclarativeQtScriptExpression::clearGuards() -{ - delete [] guardList; - guardList = 0; - guardListLength = 0; -} - /*! \fn void QDeclarativeExpression::valueChanged() diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index b03c709..dcf47c3 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -55,8 +55,8 @@ #include "qdeclarativeexpression.h" -#include "private/qdeclarativeengine_p.h" -#include "private/qdeclarativeguard_p.h" +#include +#include #include @@ -107,73 +107,84 @@ private: QDeclarativeDelayedError **prevError; }; -class QDeclarativeQtScriptExpression : public QDeclarativeAbstractExpression, - public QDeclarativeDelayedError +class QDeclarativeDeleteWatchable { public: - enum Mode { SharedContext, ExplicitContext }; - - enum EvaluateFlag { RequiresThisObject = 0x01 }; - Q_DECLARE_FLAGS(EvaluateFlags, EvaluateFlag) - - QDeclarativeQtScriptExpression(); - virtual ~QDeclarativeQtScriptExpression(); + inline QDeclarativeDeleteWatchable(); + inline ~QDeclarativeDeleteWatchable(); +private: + friend class QDeclarativeDeleteWatcher; + bool *m_wasDeleted; +}; - QDeclarativeRefCount *dataRef; +class QDeclarativeDeleteWatcher { +public: + inline QDeclarativeDeleteWatcher(QDeclarativeDeleteWatchable *data); + inline ~QDeclarativeDeleteWatcher(); + inline bool wasDeleted() const; +private: + void *operator new(size_t); + bool *m_wasDeleted; + bool m_wasDeletedStorage; + QDeclarativeDeleteWatchable *m_d; +}; - QString expression; - bool extractExpressionFromFunction; +class QDeclarativeJavaScriptExpression : public QDeclarativeAbstractExpression, + public QDeclarativeDelayedError, + public QDeclarativeDeleteWatchable +{ +public: + QDeclarativeJavaScriptExpression(); + virtual ~QDeclarativeJavaScriptExpression(); - Mode expressionFunctionMode; - v8::Persistent v8function; - v8::Persistent v8qmlscope; + v8::Local evaluate(v8::Handle, bool *isUndefined); - QObject *scopeObject; // Only used in SharedContext + inline bool requiresThisObject() const; + inline void setRequiresThisObject(bool v); + inline bool useSharedContext() const; + inline void setUseSharedContext(bool v); + inline bool notifyOnValueChanged() const; - bool notifyOnValueChange() const; - void setNotifyOnValueChange(bool); - void resetNotifyOnChange(); + void setNotifyOnValueChanged(bool v); + void resetNotifyOnValueChanged(); void setNotifyObject(QObject *, int ); - void setEvaluateFlags(EvaluateFlags flags); - EvaluateFlags evaluateFlags() const; + inline QObject *scopeObject() const; + inline void setScopeObject(QObject *v); - v8::Local v8value(QObject *secondaryScope, bool *isUndefined); - - class DeleteWatcher { - public: - inline DeleteWatcher(QDeclarativeQtScriptExpression *data); - inline ~DeleteWatcher(); - inline bool wasDeleted() const; - private: - bool *m_wasDeleted; - bool m_wasDeletedStorage; - QDeclarativeQtScriptExpression *m_d; - }; +protected: + inline virtual QStringRef expressionString(); private: - void clearGuards(); - v8::Local eval(QObject *secondaryScope, bool *isUndefined); - void updateGuards(const QPODVector &properties); + quint32 m_requiresThisObject:1; + quint32 m_useSharedContext:1; + quint32 m_notifyOnValueChanged:1; + quint32 m_dummy:29; - bool trackChange; + QObject *m_scopeObject; + QObject *m_notifyObject; + int m_notifyIndex; - QDeclarativeNotifierEndpoint *guardList; - int guardListLength; + class GuardList { + public: + inline GuardList(); + inline ~GuardList(); + void inline clear(); - QObject *guardObject; - int guardObjectNotifyIndex; - bool *deleted; + typedef QPODVector CapturedProperties; + void updateGuards(QObject *guardObject, int guardObjectNotifyIndex, + const QStringRef &expression, const CapturedProperties &properties); - EvaluateFlags evalFlags; + private: + QDeclarativeNotifierEndpoint *endpoints; + int length; + }; + GuardList guardList; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeQtScriptExpression::EvaluateFlags) - - class QDeclarativeExpression; class QString; -class QDeclarativeExpressionPrivate : public QObjectPrivate, public QDeclarativeQtScriptExpression +class QDeclarativeExpressionPrivate : public QObjectPrivate, public QDeclarativeJavaScriptExpression { Q_DECLARE_PUBLIC(QDeclarativeExpression) public: @@ -188,12 +199,8 @@ public: v8::Local v8value(QObject *secondaryScope = 0, bool *isUndefined = 0); - static QDeclarativeExpressionPrivate *get(QDeclarativeExpression *expr) { - return static_cast(QObjectPrivate::get(expr)); - } - static QDeclarativeExpression *get(QDeclarativeExpressionPrivate *expr) { - return expr->q_func(); - } + static inline QDeclarativeExpressionPrivate *get(QDeclarativeExpression *expr); + static inline QDeclarativeExpression *get(QDeclarativeExpressionPrivate *expr); void _q_notify(); virtual void emitValueChanged(); @@ -204,31 +211,123 @@ public: v8::Persistent *qmlscope = 0); bool expressionFunctionValid:1; + bool extractExpressionFromFunction:1; + + inline virtual QStringRef expressionString(); + + QString expression; + + v8::Persistent v8qmlscope; + v8::Persistent v8function; QString url; // This is a QString for a reason. QUrls are slooooooow... int line; QByteArray name; //function name, hint for the debugger + + QDeclarativeRefCount *dataRef; }; -QDeclarativeQtScriptExpression::DeleteWatcher::DeleteWatcher(QDeclarativeQtScriptExpression *data) +QDeclarativeDeleteWatchable::QDeclarativeDeleteWatchable() +: m_wasDeleted(0) +{ +} + +QDeclarativeDeleteWatchable::~QDeclarativeDeleteWatchable() +{ + if (m_wasDeleted) *m_wasDeleted = true; +} + +QDeclarativeDeleteWatcher::QDeclarativeDeleteWatcher(QDeclarativeDeleteWatchable *data) : m_wasDeletedStorage(false), m_d(data) { - if (!m_d->deleted) - m_d->deleted = &m_wasDeletedStorage; - m_wasDeleted = m_d->deleted; + if (!m_d->m_wasDeleted) + m_d->m_wasDeleted = &m_wasDeletedStorage; + m_wasDeleted = m_d->m_wasDeleted; } -QDeclarativeQtScriptExpression::DeleteWatcher::~DeleteWatcher() +QDeclarativeDeleteWatcher::~QDeclarativeDeleteWatcher() { - if (false == *m_wasDeleted && m_wasDeleted == m_d->deleted) - m_d->deleted = 0; + if (false == *m_wasDeleted && m_wasDeleted == m_d->m_wasDeleted) + m_d->m_wasDeleted = 0; } -bool QDeclarativeQtScriptExpression::DeleteWatcher::wasDeleted() const +bool QDeclarativeDeleteWatcher::wasDeleted() const { return *m_wasDeleted; } +bool QDeclarativeJavaScriptExpression::requiresThisObject() const +{ + return m_requiresThisObject; +} + +void QDeclarativeJavaScriptExpression::setRequiresThisObject(bool v) +{ + m_requiresThisObject = v; +} + +bool QDeclarativeJavaScriptExpression::useSharedContext() const +{ + return m_useSharedContext; +} + +void QDeclarativeJavaScriptExpression::setUseSharedContext(bool v) +{ + m_useSharedContext = v; +} + +bool QDeclarativeJavaScriptExpression::notifyOnValueChanged() const +{ + return m_notifyOnValueChanged; +} + +QObject *QDeclarativeJavaScriptExpression::scopeObject() const +{ + return m_scopeObject; +} + +void QDeclarativeJavaScriptExpression::setScopeObject(QObject *v) +{ + m_scopeObject = v; +} + +QStringRef QDeclarativeJavaScriptExpression::expressionString() +{ + return QStringRef(); +} + +QDeclarativeJavaScriptExpression::GuardList::GuardList() +: endpoints(0), length(0) +{ +} + +QDeclarativeJavaScriptExpression::GuardList::~GuardList() +{ + clear(); +} + +void QDeclarativeJavaScriptExpression::GuardList::clear() +{ + delete [] endpoints; + endpoints = 0; + length = 0; +} + +QDeclarativeExpressionPrivate *QDeclarativeExpressionPrivate::get(QDeclarativeExpression *expr) +{ + return static_cast(QObjectPrivate::get(expr)); +} + +QDeclarativeExpression *QDeclarativeExpressionPrivate::get(QDeclarativeExpressionPrivate *expr) +{ + return expr->q_func(); +} + +QStringRef QDeclarativeExpressionPrivate::expressionString() +{ + return QStringRef(&expression); +} + QT_END_NAMESPACE #endif // QDECLARATIVEEXPRESSION_P_H -- 2.7.4