Skip to content

Commit

Permalink
Fixes to recursive properties dependency checking
Browse files Browse the repository at this point in the history
PR-URL: #233
  • Loading branch information
pavelvasev authored and ChALkeR committed May 8, 2016
1 parent ce8e76d commit 32d8a18
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 17 deletions.
4 changes: 2 additions & 2 deletions src/modules/QtQuick/Repeater.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ function QMLRepeater(meta) {
var newItem = self.delegate.createObject(self);

createProperty("int", newItem, "index");
newItem.index = index;

var model = self.model instanceof QMLListModel ? self.model.$model : self.model;
for (var i in model.roleNames) {
if (typeof newItem.$properties[model.roleNames[i]] == 'undefined')
Expand All @@ -43,8 +45,6 @@ function QMLRepeater(meta) {
self.container().childrenChanged();
self.$items.splice(index, 0, newItem);

newItem.index = index;

// TODO debug this. Without check to Init, Completed sometimes called twice.. But is this check correct?
if (engine.operationState !== QMLOperationState.Init && engine.operationState !== QMLOperationState.Idle) {
// We don't call those on first creation, as they will be called
Expand Down
48 changes: 33 additions & 15 deletions src/qtcore/qml/QMLProperty.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,31 @@ QMLProperty.ReasonUser = 0;
QMLProperty.ReasonInit = 1;
QMLProperty.ReasonAnimation = 2;

function pushEvalStack() {
evaluatingPropertyStackOfStacks.push( evaluatingPropertyStack );
evaluatingPropertyStack = [];
evaluatingProperty = undefined;
// console.log("evaluatingProperty=>undefined due to push stck ");
}

function popEvalStack() {
evaluatingPropertyStack = evaluatingPropertyStackOfStacks.pop() || [];
evaluatingProperty = evaluatingPropertyStack[ evaluatingPropertyStack.length-1 ];
}

function pushEvaluatingProperty( prop ) {
// TODO say warnings if already on stack. This means binding loop. BTW actually we do not loop because needsUpdate flag is reset before entering update again.
if (evaluatingPropertyStack.indexOf( prop ) >= 0) {
console.error("Property binding loop detected for property ",prop.name, [prop].slice(0));
}
evaluatingProperty = prop;
evaluatingPropertyStack.push( prop ); //keep stack of props
}

function popEvaluatingProperty() {

evaluatingPropertyStack.pop();
if (evaluatingPropertyStack.length == 0)
evaluatingProperty = undefined;
else
evaluatingProperty = evaluatingPropertyStack[ evaluatingPropertyStack.length-1 ];
evaluatingProperty = evaluatingPropertyStack[ evaluatingPropertyStack.length-1 ];
}

// Updater recalculates the value of a property if one of the
Expand All @@ -43,11 +55,15 @@ QMLProperty.prototype.update = function() {
return;

var oldVal = this.val;
pushEvaluatingProperty(this);
if (!this.binding.eval)
this.binding.compile();
this.val = this.binding.eval(this.objectScope, this.componentScope);
popEvaluatingProperty();

try {
pushEvaluatingProperty(this);
if (!this.binding.eval)
this.binding.compile();
this.val = this.binding.eval(this.objectScope, this.componentScope);
} finally {
popEvaluatingProperty();
}

if (this.animation) {
this.animation.$actions = [{
Expand Down Expand Up @@ -105,12 +121,14 @@ QMLProperty.prototype.set = function(newVal, reason, objectScope, componentScope
if (engine.operationState !== QMLOperationState.Init) {
if (!newVal.eval)
newVal.compile();

pushEvaluatingProperty(this);
this.needsUpdate = false;
newVal = this.binding.eval(objectScope, componentScope);
popEvaluatingProperty();

try {
pushEvaluatingProperty(this);

this.needsUpdate = false;
newVal = this.binding.eval(objectScope, componentScope);
} finally {
popEvaluatingProperty();
}
} else {
engine.bindedProperties.push(this);
return;
Expand Down
1 change: 1 addition & 0 deletions src/qtcore/qml/qml.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var GETTER = "__defineGetter__",
evaluatingProperty = undefined,
evaluatingPropertyStack = [],
evaluatingPropertyPaused = false,
evaluatingPropertyStackOfStacks = [],
_executionContext = null,
// All object constructors
constructors = {
Expand Down
2 changes: 2 additions & 0 deletions src/qtcore/signal.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ global.Signal = function Signal(params, options) {
var obj = options.obj

var signal = function() {
pushEvalStack();
for (var i in connectedSlots)
try {
connectedSlots[i].slot.apply(connectedSlots[i].thisObj, arguments);
} catch(err) {
console.log(err.message);
}
popEvalStack();
};
signal.parameters = params || [];
signal.connect = function() {
Expand Down

0 comments on commit 32d8a18

Please sign in to comment.