本文整理汇总了C++中QQmlEnginePrivate类的典型用法代码示例。如果您正苦于以下问题:C++ QQmlEnginePrivate类的具体用法?C++ QQmlEnginePrivate怎么用?C++ QQmlEnginePrivate使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了QQmlEnginePrivate类的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Q_ASSERT
QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
const QV4::ValueRef function,
QV4::CallData *callData,
bool *isUndefined)
{
Q_ASSERT(context && context->engine);
if (function->isUndefined()) {
if (isUndefined)
*isUndefined = true;
return QV4::Encode::undefined();
}
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine);
// All code that follows must check with watcher before it accesses data members
// incase we have been deleted.
DeleteWatcher watcher(this);
Q_ASSERT(notifyOnValueChanged() || activeGuards.isEmpty());
GuardCapture capture(context->engine, this, &watcher);
QQmlEnginePrivate::PropertyCapture *lastPropertyCapture = ep->propertyCapture;
ep->propertyCapture = notifyOnValueChanged()?&capture:0;
if (notifyOnValueChanged())
capture.guards.copyAndClearPrepend(activeGuards);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
QV4::Scope scope(v4);
QV4::ScopedValue result(scope, QV4::Primitive::undefinedValue());
QV4::ExecutionContext *ctx = v4->currentContext();
callData->thisObject = v4->globalObject;
if (scopeObject()) {
QV4::ScopedValue value(scope, QV4::QObjectWrapper::wrap(ctx->d()->engine, scopeObject()));
if (value->isObject())
callData->thisObject = value;
}
result = function->asFunctionObject()->call(callData);
if (scope.hasException()) {
if (watcher.wasDeleted())
ctx->catchException(); // ignore exception
else
delayedError()->catchJavaScriptException(ctx);
if (isUndefined)
*isUndefined = true;
} else {
if (isUndefined)
*isUndefined = result->isUndefined();
if (!watcher.wasDeleted() && hasDelayedError())
delayedError()->clearError();
}
if (capture.errorString) {
for (int ii = 0; ii < capture.errorString->count(); ++ii)
qWarning("%s", qPrintable(capture.errorString->at(ii)));
delete capture.errorString;
capture.errorString = 0;
}
while (Guard *g = capture.guards.takeFirst())
g->Delete();
ep->propertyCapture = lastPropertyCapture;
return result.asReturnedValue();
}
示例2: update
void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
{
if (!enabledFlag() || !context() || !context()->isValid())
return;
// Check that the target has not been deleted
if (QQmlData::wasDeleted(object()))
return;
QString url;
quint16 lineNumber;
quint16 columnNumber;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
QV4::Scope scope(ep->v4engine());
QV4::ScopedFunctionObject f(scope, v4function.value());
Q_ASSERT(f);
if (f->bindingKeyFlag()) {
Q_ASSERT(f->as<QV4::QQmlBindingFunction>());
QQmlSourceLocation loc = static_cast<QV4::QQmlBindingFunction *>(f.getPointer())->d()->bindingLocation;
url = loc.sourceFile;
lineNumber = loc.line;
columnNumber = loc.column;
} else {
QV4::Function *function = f->asFunctionObject()->function();
Q_ASSERT(function);
url = function->sourceFile();
lineNumber = function->compiledFunction->location.line;
columnNumber = function->compiledFunction->location.column;
}
int lineNo = qmlSourceCoordinate(lineNumber);
int columnNo = qmlSourceCoordinate(columnNumber);
QQmlTrace trace("General Binding Update");
trace.addDetail("URL", url);
trace.addDetail("Line", lineNo);
trace.addDetail("Column", columnNo);
if (!updatingFlag()) {
QQmlBindingProfiler prof(ep->profiler, url, lineNo, columnNo);
setUpdatingFlag(true);
QQmlAbstractExpression::DeleteWatcher watcher(this);
if (m_core.propType == qMetaTypeId<QQmlBinding *>()) {
int idx = m_core.coreIndex;
Q_ASSERT(idx != -1);
QQmlBinding *t = this;
int status = -1;
void *a[] = { &t, 0, &status, &flags };
QMetaObject::metacall(*m_coreObject, QMetaObject::WriteProperty, idx, a);
} else {
ep->referenceScarceResources();
bool isUndefined = false;
QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(context(), f, &isUndefined));
trace.event("writing binding result");
bool needsErrorLocationData = false;
if (!watcher.wasDeleted() && !hasError())
needsErrorLocationData = !QQmlPropertyPrivate::writeBinding(*m_coreObject, m_core, context(),
this, result, isUndefined, flags);
if (!watcher.wasDeleted()) {
if (needsErrorLocationData)
delayedError()->setErrorLocation(QUrl(url), lineNumber, columnNumber);
if (hasError()) {
if (!delayedError()->addError(ep)) ep->warning(this->error(context()->engine));
} else {
clearError();
}
}
ep->dereferenceScarceResources();
}
if (!watcher.wasDeleted())
setUpdatingFlag(false);
} else {
QQmlProperty p = property();
QQmlAbstractBinding::printBindingLoopError(p);
}
}
示例3: Q_ASSERT
// Parts of this function mirror code in QQmlExpressionPrivate::value() and v8value().
// Changes made here may need to be made there and vice versa.
void QQmlBoundSignalExpression::evaluate(void **a)
{
Q_ASSERT (context() && engine());
if (invalidParameterName())
return;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine());
QV4::Scope scope(ep->v4engine());
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
{
if (!expressionFunctionValid()) {
Q_ASSERT(!m_extra.isNull());
QString expression;
// Add some leading whitespace to account for the binding's column offset.
// It's 2 off because a, we start counting at 1 and b, the '(' below is not counted.
expression.fill(QChar(QChar::Space), qMax(m_extra->m_sourceLocation.column, (quint16)2) - 2);
expression += QStringLiteral("(function ");
expression += m_extra->m_handlerName;
expression += QLatin1Char('(');
if (m_extra->m_parameterString.isEmpty()) {
QString error;
//TODO: look at using the property cache here (as in the compiler)
// for further optimization
QMetaMethod signal = QMetaObjectPrivate::signal(m_target->metaObject(), m_index);
expression += QQmlPropertyCache::signalParameterStringForJS(engine(), signal.parameterNames(), &error);
if (!error.isEmpty()) {
qmlInfo(scopeObject()) << error;
setInvalidParameterName(true);
ep->dereferenceScarceResources();
return;
}
} else
expression += m_extra->m_parameterString;
expression += QStringLiteral(") { ");
expression += m_extra->m_expression;
expression += QStringLiteral(" })");
m_extra->m_expression.clear();
m_extra->m_handlerName.clear();
m_extra->m_parameterString.clear();
m_v8function = evalFunction(context(), scopeObject(), expression,
m_extra->m_sourceLocation.sourceFile, m_extra->m_sourceLocation.line, &m_extra->m_v8qmlscope);
if (m_v8function.isNullOrUndefined()) {
ep->dereferenceScarceResources();
return; // could not evaluate function. Not valid.
}
setExpressionFunctionValid(true);
}
QV8Engine *engine = ep->v8engine();
QVarLengthArray<int, 9> dummy;
//TODO: lookup via signal index rather than method index as an optimization
int methodIndex = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).methodIndex();
int *argsTypes = QQmlPropertyCache::methodParameterTypes(m_target, methodIndex, dummy, 0);
int argCount = argsTypes ? *argsTypes : 0;
QV4::ScopedValue f(scope, m_v8function.value());
QV4::ScopedCallData callData(scope, argCount);
for (int ii = 0; ii < argCount; ++ii) {
int type = argsTypes[ii + 1];
//### ideally we would use metaTypeToJS, however it currently gives different results
// for several cases (such as QVariant type and QObject-derived types)
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
if (type == QMetaType::QVariant) {
callData->args[ii] = engine->fromVariant(*((QVariant *)a[ii + 1]));
} else if (type == QMetaType::Int) {
//### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise
callData->args[ii] = QV4::Primitive::fromInt32(*reinterpret_cast<const int*>(a[ii + 1]));
} else if (type == qMetaTypeId<QQmlV4Handle>()) {
callData->args[ii] = *reinterpret_cast<QQmlV4Handle *>(a[ii + 1]);
} else if (ep->isQObject(type)) {
if (!*reinterpret_cast<void* const *>(a[ii + 1]))
callData->args[ii] = QV4::Primitive::nullValue();
else
callData->args[ii] = QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast<QObject* const *>(a[ii + 1]));
} else {
callData->args[ii] = engine->fromVariant(QVariant(type, a[ii + 1]));
}
}
QQmlJavaScriptExpression::evaluate(context(), f, callData, 0);
}
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
}
示例4: qmlSourceCoordinate
void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
{
if (!enabledFlag() || !context() || !context()->isValid())
return;
// Check that the target has not been deleted
if (QQmlData::wasDeleted(object()))
return;
int lineNo = qmlSourceCoordinate(m_lineNumber);
int columnNo = qmlSourceCoordinate(m_columnNumber);
QQmlTrace trace("General Binding Update");
trace.addDetail("URL", m_url);
trace.addDetail("Line", lineNo);
trace.addDetail("Column", columnNo);
if (!updatingFlag()) {
QQmlBindingProfiler prof(m_url, lineNo, columnNo, QQmlProfilerService::QmlBinding);
setUpdatingFlag(true);
QQmlAbstractExpression::DeleteWatcher watcher(this);
if (m_core.propType == qMetaTypeId<QQmlBinding *>()) {
int idx = m_core.coreIndex;
Q_ASSERT(idx != -1);
QQmlBinding *t = this;
int status = -1;
void *a[] = { &t, 0, &status, &flags };
QMetaObject::metacall(*m_coreObject, QMetaObject::WriteProperty, idx, a);
} else {
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
ep->referenceScarceResources();
bool isUndefined = false;
v8::HandleScope handle_scope;
v8::Context::Scope scope(ep->v8engine()->context());
v8::Local<v8::Value> result =
QQmlJavaScriptExpression::evaluate(context(), v8function, &isUndefined);
trace.event("writing binding result");
bool needsErrorLocationData = false;
if (!watcher.wasDeleted() && !hasError())
needsErrorLocationData = !QQmlPropertyPrivate::writeBinding(*m_coreObject, m_core, context(),
this, result, isUndefined, flags);
if (!watcher.wasDeleted()) {
if (needsErrorLocationData)
delayedError()->setErrorLocation(QUrl(m_url), m_lineNumber, m_columnNumber);
if (hasError()) {
if (!delayedError()->addError(ep)) ep->warning(this->error(context()->engine));
} else {
clearError();
}
}
ep->dereferenceScarceResources();
}
if (!watcher.wasDeleted())
setUpdatingFlag(false);
} else {
QQmlProperty p = property();
QQmlAbstractBinding::printBindingLoopError(p);
}
}
示例5: classBegin
void QQuickAnimationController::classBegin()
{
QQmlEnginePrivate *engPriv = QQmlEnginePrivate::get(qmlEngine(this));
engPriv->registerFinalizeCallback(this, this->metaObject()->indexOfSlot("componentFinalized()"));
}
示例6: QML_MEMORY_SCOPE_URL
void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
{
if (!compiledData)
return;
QML_MEMORY_SCOPE_URL(compiledData->url());
QExplicitlySharedDataPointer<QQmlIncubatorPrivate> protectThis(this);
QRecursionWatcher<QQmlIncubatorPrivate, &QQmlIncubatorPrivate::recursion> watcher(this);
QQmlEngine *engine = compiledData->engine;
QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine);
if (!vmeGuard.isOK()) {
QQmlError error;
error.setUrl(compiledData->url());
error.setDescription(QQmlComponent::tr("Object destroyed during incubation"));
errors << error;
progress = QQmlIncubatorPrivate::Completed;
goto finishIncubate;
}
vmeGuard.clear();
if (progress == QQmlIncubatorPrivate::Execute) {
enginePriv->referenceScarceResources();
QObject *tresult = 0;
tresult = creator->create(subComponentToCreate, /*parent*/0, &i);
if (!tresult)
errors = creator->errors;
enginePriv->dereferenceScarceResources();
if (watcher.hasRecursed())
return;
result = tresult;
if (errors.isEmpty() && result == 0)
goto finishIncubate;
if (result) {
QQmlData *ddata = QQmlData::get(result);
Q_ASSERT(ddata);
//see QQmlComponent::beginCreate for explanation of indestructible
ddata->indestructible = true;
ddata->explicitIndestructibleSet = true;
ddata->rootObjectInCreation = false;
if (q)
q->setInitialState(result);
}
if (watcher.hasRecursed())
return;
if (errors.isEmpty())
progress = QQmlIncubatorPrivate::Completing;
else
progress = QQmlIncubatorPrivate::Completed;
changeStatus(calculateStatus());
if (watcher.hasRecursed())
return;
if (i.shouldInterrupt())
goto finishIncubate;
}
if (progress == QQmlIncubatorPrivate::Completing) {
do {
if (watcher.hasRecursed())
return;
QQmlContextData *ctxt = 0;
ctxt = creator->finalize(i);
if (ctxt) {
rootContext = ctxt;
progress = QQmlIncubatorPrivate::Completed;
goto finishIncubate;
}
} while (!i.shouldInterrupt());
}
finishIncubate:
if (progress == QQmlIncubatorPrivate::Completed && waitingFor.isEmpty()) {
QExplicitlySharedDataPointer<QQmlIncubatorPrivate> isWaiting = waitingOnMe;
clear();
if (isWaiting) {
QRecursionWatcher<QQmlIncubatorPrivate, &QQmlIncubatorPrivate::recursion> watcher(isWaiting.data());
changeStatus(calculateStatus());
if (!watcher.hasRecursed())
isWaiting->incubate(i);
} else {
changeStatus(calculateStatus());
}
enginePriv->inProgressCreations--;
//.........这里部分代码省略.........
示例7: propertystring
v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property,
const v8::AccessorInfo &info)
{
QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This());
// Its possible we could delay the calculation of the "actual" context (in the case
// of sub contexts) until it is definately needed.
QQmlContextData *context = resource->getContext();
QQmlContextData *expressionContext = context;
if (!context)
return v8::Undefined();
if (v8::Context::GetCallingQmlGlobal() != info.This())
return v8::Handle<v8::Value>();
// Search type (attached property/enum/imported scripts) names
// while (context) {
// Search context properties
// Search scope object
// Search context object
// context = context->parent
// }
QV8Engine *engine = resource->engine;
QObject *scopeObject = resource->getScopeObject();
QHashedV8String propertystring(property);
if (context->imports && QV8Engine::startsWithUpper(property)) {
// Search for attached properties, enums and imported scripts
QQmlTypeNameCache::Result r = context->imports->query(propertystring);
if (r.isValid()) {
if (r.scriptIndex != -1) {
int index = r.scriptIndex;
if (index < context->importedScripts.count())
return context->importedScripts.at(index);
else
return v8::Undefined();
} else if (r.type) {
return engine->typeWrapper()->newObject(scopeObject, r.type);
} else if (r.importNamespace) {
return engine->typeWrapper()->newObject(scopeObject, context->imports, r.importNamespace);
}
Q_ASSERT(!"Unreachable");
}
// Fall through
}
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine->engine());
QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper();
while (context) {
// Search context properties
if (context->propertyNames) {
int propertyIdx = context->propertyNames->value(propertystring);
if (propertyIdx != -1) {
if (propertyIdx < context->idValueCount) {
ep->captureProperty(&context->idValues[propertyIdx].bindings);
return engine->newQObject(context->idValues[propertyIdx]);
} else {
QQmlContextPrivate *cp = context->asQQmlContextPrivate();
ep->captureProperty(context->asQQmlContext(), -1,
propertyIdx + cp->notifyIndex);
const QVariant &value = cp->propertyValues.at(propertyIdx);
if (value.userType() == qMetaTypeId<QList<QObject*> >()) {
QQmlListProperty<QObject> prop(context->asQQmlContext(), (void*) qintptr(propertyIdx),
QQmlContextPrivate::context_count,
QQmlContextPrivate::context_at);
return engine->listWrapper()->newList(prop, qMetaTypeId<QQmlListProperty<QObject> >());
} else {
return engine->fromVariant(cp->propertyValues.at(propertyIdx));
}
}
}
}
// Search scope object
if (scopeObject) {
v8::Handle<v8::Value> result = qobjectWrapper->getProperty(scopeObject, propertystring,
context, QV8QObjectWrapper::CheckRevision);
if (!result.IsEmpty()) return result;
}
scopeObject = 0;
// Search context object
if (context->contextObject) {
v8::Handle<v8::Value> result = qobjectWrapper->getProperty(context->contextObject, propertystring,
context, QV8QObjectWrapper::CheckRevision);
if (!result.IsEmpty()) return result;
//.........这里部分代码省略.........
示例8: foreach
//.........这里部分代码省略.........
if (lastDotIndex != -1) {
enclosingNamespace = qualifier.left(lastDotIndex);
qualifier = qualifier.mid(lastDotIndex+1);
}
compiledData->importCache->add(qualifier, scriptIndex, enclosingNamespace);
#if 0
QQmlScriptData *scriptData = script.script->scriptData();
scriptData->addref();
compiledData->scripts << scriptData;
#endif
}
// resolve component boundaries and aliases
if (!resolveComponentBoundariesAndAliases())
return false;
// Compile JS binding expressions and signal handlers
if (!compilation->document->javaScriptCompilationUnit) {
// We can compile script strings ahead of time, but they must be compiled
// without type optimizations as their scope is always entirely dynamic.
scanScriptStrings();
// TBD: check how it uses importCache
// TBD: check how links with other scripts
QmlIR::JSCodeGen v4CodeGenerator(compilation->urlString, compilation->document->code, &compilation->document->jsModule,
&compilation->document->jsParserEngine, compilation->document->program,
compiledData->importCache, &compilation->document->jsGenerator.stringTable);
JSCodeGenerator jsCodeGen(this, &v4CodeGenerator);
if (!jsCodeGen.generateCodeForComponents())
return false;
simplifyJavaScriptBindingExpressions();
QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(compilation->engine);
QV4::ExecutionEngine *v4 = enginePrivate->v4engine();
// TBD: store unlinked binaries
#if 0
QScopedPointer<QV4::EvalInstructionSelection> isel(
v4->iselFactory->create(enginePrivate, v4->executableAllocator,
&compilation->document->jsModule, &compilation->document->jsGenerator));
#endif
QScopedPointer<QmcInstructionSelection> isel(
new QmcInstructionSelection(enginePrivate, v4->executableAllocator,
&compilation->document->jsModule, &compilation->document->jsGenerator));
isel->setUseFastLookups(false);
compilation->document->javaScriptCompilationUnit = isel->compile(/*generated unit data*/false);
compilation->linkData = isel->linkData();
compilation->exceptionReturnLabels = isel->exceptionReturnLabelsData();
compilation->exceptionPropagationJumps = isel->exceptionPropagationJumpsData();
#if CPU(ARM_THUMB2)
compilation->jumpsToLinkData = isel->linkRecordData();
compilation->unlinkedCodeData = isel->unlinkedCodeData();
#endif
}
// Generate QML compiled type data structures
QmlIR::QmlUnitGenerator qmlGenerator;
QV4::CompiledData::QmlUnit *qmlUnit = qmlGenerator.generate(*compilation->document);
Q_ASSERT(compilation->document->javaScriptCompilationUnit);
Q_ASSERT((void*)qmlUnit == (void*)&qmlUnit->header);
// The js unit owns the data and will free the qml unit.
compilation->document->javaScriptCompilationUnit->data = &qmlUnit->header;
compiledData->compilationUnit = compilation->document->javaScriptCompilationUnit;
if (compiledData->compilationUnit)
compiledData->compilationUnit->ref();
compiledData->qmlUnit = qmlUnit; // ownership transferred to m_compiledData
// add to type registry
// qqmltypecompiler.cpp:248
if (compiledData->isCompositeType()) {
if (compilation->singleton)
qmlUnit->header.flags |= QV4::CompiledData::Unit::IsSingleton;
QQmlEnginePrivate::get(compilation->engine)->registerInternalCompositeType(compiledData);
} else {
if (compilation->singleton) {
qmlUnit->header.flags = qmlUnit->header.flags | QV4::CompiledData::Unit::IsSingleton;
}
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(qmlUnit->indexOfRootObject);
QQmlCompiledData::TypeReference *typeRef = compiledData->resolvedTypes.value(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
if (typeRef->component) {
compiledData->metaTypeId = typeRef->component->metaTypeId;
compiledData->listMetaTypeId = typeRef->component->listMetaTypeId;
} else {
compiledData->metaTypeId = typeRef->type->typeId();
compiledData->listMetaTypeId = typeRef->type->qListTypeId();
}
}
// Sanity check property bindings and compile custom parsers
if (!validateProperties())
return false;
return true;
}
示例9: Q_ASSERT
// Parts of this function mirror code in QQmlExpressionPrivate::value() and v8value().
// Changes made here may need to be made there and vice versa.
void QQmlBoundSignalExpression::evaluate(void **a)
{
Q_ASSERT (context() && engine());
if (m_invalidParameterName)
return;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine());
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
{
v8::HandleScope handle_scope;
v8::Context::Scope context_scope(ep->v8engine()->context());
if (!m_expressionFunctionValid) {
//TODO: look at using the property cache here (as in the compiler)
// for further optimization
QMetaMethod signal = QMetaObjectPrivate::signal(m_target->metaObject(), m_index);
QQmlRewrite::RewriteSignalHandler rewriter;
QString expression;
bool ok = true;
if (m_expressionFunctionRewritten) {
expression = QString::fromUtf8(m_expressionUtf8);
//if we need parameters, and the rewrite doesn't include them,
//create and insert the parameter string now
if (m_parameterCountForJS == -1 && signal.parameterCount()) {
const QString ¶meters = rewriter.createParameterString(signal.parameterNames(),
ep->v8engine()->illegalNames());
int index = expression.indexOf(QLatin1Char('('), 1);
Q_ASSERT(index > -1);
expression.insert(index + 1, parameters);
setParameterCountForJS(rewriter.parameterCountForJS());
}
m_expressionUtf8.clear();
} else {
//expression is still in its original form, so perform a full rewrite
expression = rewriter(m_expression, QString()/*no name hint available*/, &ok,
signal.parameterNames(),
ep->v8engine()->illegalNames());
setParameterCountForJS(rewriter.parameterCountForJS());
m_expression.clear();
}
if (rewriter.hasParameterError()) {
qmlInfo(scopeObject()) << rewriter.parameterError();
m_invalidParameterName = true;
ep->dereferenceScarceResources();
return;
}
if (ok) {
m_v8function = evalFunction(context(), scopeObject(), expression,
m_fileName, m_line, &m_v8qmlscope);
}
if (m_v8function.IsEmpty() || m_v8function->IsNull()) {
ep->dereferenceScarceResources();
return; // could not evaluate function. Not valid.
}
setUseSharedContext(false);
m_expressionFunctionValid = true;
}
if (!hasParameterInfo()) {
QQmlJavaScriptExpression::evaluate(context(), m_v8function, 0);
} else {
QV8Engine *engine = ep->v8engine();
QVarLengthArray<int, 9> dummy;
//TODO: lookup via signal index rather than method index as an optimization
int methodIndex = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).methodIndex();
int *argsTypes = QQmlPropertyCache::methodParameterTypes(m_target, methodIndex, dummy, 0);
int argCount = argsTypes ? m_parameterCountForJS : 0;
QVarLengthArray<v8::Handle<v8::Value>, 9> args(argCount);
for (int ii = 0; ii < argCount; ++ii) {
int type = argsTypes[ii + 1];
//### ideally we would use metaTypeToJS, however it currently gives different results
// for several cases (such as QVariant type and QObject-derived types)
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
if (type == QMetaType::QVariant) {
args[ii] = engine->fromVariant(*((QVariant *)a[ii + 1]));
} else if (type == QMetaType::Int) {
//### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise
args[ii] = v8::Integer::New(*reinterpret_cast<const int*>(a[ii + 1]));
} else if (type == qMetaTypeId<QQmlV8Handle>()) {
args[ii] = reinterpret_cast<QQmlV8Handle *>(a[ii + 1])->toHandle();
} else if (ep->isQObject(type)) {
if (!*reinterpret_cast<void* const *>(a[ii + 1]))
args[ii] = v8::Null();
else
args[ii] = engine->newQObject(*reinterpret_cast<QObject* const *>(a[ii + 1]));
//.........这里部分代码省略.........
示例10: Q_ASSERT
int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
{
int id = _id;
if (c == QMetaObject::WriteProperty && interceptors &&
!(*reinterpret_cast<int*>(a[3]) & QQmlPropertyPrivate::BypassInterceptor)) {
for (QQmlPropertyValueInterceptor *vi = interceptors; vi; vi = vi->m_next) {
if (vi->m_coreIndex != id)
continue;
int valueIndex = vi->m_valueTypeCoreIndex;
int type = QQmlData::get(object)->propertyCache->property(id)->propType;
if (type != QVariant::Invalid) {
if (valueIndex != -1) {
QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type);
Q_ASSERT(valueType);
//
// Consider the following case:
// color c = { 0.1, 0.2, 0.3 }
// interceptor exists on c.r
// write { 0.2, 0.4, 0.6 }
//
// The interceptor may choose not to update the r component at this
// point (for example, a behavior that creates an animation). But we
// need to ensure that the g and b components are updated correctly.
//
// So we need to perform a full write where the value type is:
// r = old value, g = new value, b = new value
//
// And then call the interceptor which may or may not write the
// new value to the r component.
//
// This will ensure that the other components don't contain stale data
// and any relevant signals are emitted.
//
// To achieve this:
// (1) Store the new value type as a whole (needed due to
// aliasing between a[0] and static storage in value type).
// (2) Read the entire existing value type from object -> valueType temp.
// (3) Read the previous value of the component being changed
// from the valueType temp.
// (4) Write the entire new value type into the temp.
// (5) Overwrite the component being changed with the old value.
// (6) Perform a full write to the value type (which may emit signals etc).
// (7) Issue the interceptor call with the new component value.
//
QMetaProperty valueProp = valueType->metaObject()->property(valueIndex);
QVariant newValue(type, a[0]);
valueType->read(object, id);
QVariant prevComponentValue = valueProp.read(valueType);
valueType->setValue(newValue);
QVariant newComponentValue = valueProp.read(valueType);
// Don't apply the interceptor if the intercepted value has not changed
bool updated = false;
if (newComponentValue != prevComponentValue) {
valueProp.write(valueType, prevComponentValue);
valueType->write(object, id, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
vi->write(newComponentValue);
updated = true;
}
if (updated)
return -1;
} else {
vi->write(QVariant(type, a[0]));
return -1;
}
}
}
}
if (c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty) {
if (id >= propOffset()) {
id -= propOffset();
if (id < metaData->propertyCount) {
int t = (metaData->propertyData() + id)->propertyType;
bool needActivate = false;
if (id >= firstVarPropertyIndex) {
Q_ASSERT(t == QMetaType::QVariant);
// the context can be null if accessing var properties from cpp after re-parenting an item.
QQmlEnginePrivate *ep = (ctxt == 0 || ctxt->engine == 0) ? 0 : QQmlEnginePrivate::get(ctxt->engine);
QV8Engine *v8e = (ep == 0) ? 0 : ep->v8engine();
if (v8e) {
if (c == QMetaObject::ReadProperty) {
*reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
} else if (c == QMetaObject::WriteProperty) {
writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
}
} else if (c == QMetaObject::ReadProperty) {
// if the context was disposed, we just return an invalid variant from read.
*reinterpret_cast<QVariant *>(a[0]) = QVariant();
}
//.........这里部分代码省略.........
示例11: ensureQObjectWrapper
void QQmlVMEMetaObject::ensureQObjectWrapper()
{
QQmlEnginePrivate *ep = (ctxt == 0 || ctxt->engine == 0) ? 0 : QQmlEnginePrivate::get(ctxt->engine);
QV4::ExecutionEngine *v4 = (ep == 0) ? 0 : ep->v4engine();
QV4::QObjectWrapper::wrap(v4, object);
}
示例12: Q_ASSERT
v8::Local<v8::Value>
QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
v8::Handle<v8::Function> function,
int argc, v8::Handle<v8::Value> args[],
bool *isUndefined)
{
Q_ASSERT(context && context->engine);
if (function.IsEmpty() || function->IsUndefined()) {
if (isUndefined) *isUndefined = true;
return v8::Local<v8::Value>();
}
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine);
Q_ASSERT(notifyOnValueChanged() || activeGuards.isEmpty());
GuardCapture capture(context->engine, this);
QQmlEnginePrivate::PropertyCapture *lastPropertyCapture = ep->propertyCapture;
ep->propertyCapture = notifyOnValueChanged()?&capture:0;
if (notifyOnValueChanged())
capture.guards.copyAndClearPrepend(activeGuards);
QQmlContextData *lastSharedContext = 0;
QObject *lastSharedScope = 0;
bool sharedContext = useSharedContext();
// All code that follows must check with watcher before it accesses data members
// incase we have been deleted.
DeleteWatcher watcher(this);
if (sharedContext) {
lastSharedContext = ep->sharedContext;
lastSharedScope = ep->sharedScope;
ep->sharedContext = context;
ep->sharedScope = scopeObject();
}
v8::Local<v8::Value> result;
{
v8::TryCatch try_catch;
v8::Handle<v8::Object> This = ep->v8engine()->global();
if (scopeObject() && requiresThisObject()) {
v8::Handle<v8::Value> value = ep->v8engine()->newQObject(scopeObject());
if (value->IsObject()) This = v8::Handle<v8::Object>::Cast(value);
}
result = function->Call(This, argc, args);
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<v8::Message> message = try_catch.Message();
if (!message.IsEmpty()) {
delayedError()->setMessage(message);
} else {
if (hasDelayedError()) delayedError()->clearError();
}
} else {
if (hasDelayedError()) delayedError()->clearError();
}
}
if (sharedContext) {
ep->sharedContext = lastSharedContext;
ep->sharedScope = lastSharedScope;
}
if (capture.errorString) {
for (int ii = 0; ii < capture.errorString->count(); ++ii)
qWarning("%s", qPrintable(capture.errorString->at(ii)));
delete capture.errorString;
capture.errorString = 0;
}
while (Guard *g = capture.guards.takeFirst())
g->Delete();
ep->propertyCapture = lastPropertyCapture;
return result;
}