-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
buggy behavior of bidirectional DynamicProperty #197
Comments
DynamicProperty appears to be missing guards to prevent a call to E.g. see onSelfChange: function( value ) {
if ( this.valuePropertyProperty.value !== null ) {
this.derive( this.valuePropertyProperty.value ).value = this.inverseMap( value );
}
}, When the DynamicProperty is changed ( |
I tried adding (but did not commit) a couple of flags to short-circuit "ping ponging" of this.callingMap = false; // true when we're in the middle of a call to this.map
this.callingInverseMap = false; // true when we're in the middle of a call to this.inverseMap
...
onPropertyPropertyChange: function( value ) {
if ( !this.callingInverseMap ) {
// Since we override the setter here, we need to call the version on the prototype
this.callingMap = true;
Property.prototype.set.call( this, this.map( value ) );
this.callingMap = false;
}
},
...
onSelfChange: function( value ) {
if ( this.valuePropertyProperty.value !== null ) {
if ( !this.callingMap ) {
this.callingInverseMap = true;
this.derive( this.valuePropertyProperty.value ).value = this.inverseMap( value );
this.callingInverseMap = false;
}
}
}, Previous console tests now behave as expected. That is, there is no "ping ponging" of
|
I also verified that the guard flags added to |
Top priority, since this fixes phetsims/graphing-quadratics#52 which is also top priority. |
DynamicProperty unit tests pass with the changes proposed in #197 (comment) |
Hmm, it seems like ignoring onSelfChange in those cases will break DynamicProperty in other cases (where reentrance is legitimately used). I'll try to come up with an example. I'd generally prefer that any time one of the properties changes, the other wouldn't change if either |
Yeah, that's why I said:
So however you want to solve this is fine with me. The purpose of my "solution" was to illustrate the "bouncing", and to verify that eliminating the bouncing solved the other problems that we were seeing in Graphing Quadratics and Studio. Whatever the solution, it also seems like DynamicPropertyTests should be augmented to verify behavior related to this issue. |
I'm running fairly comprehensive testing on a solution right now, I'll expect to commit soon. It cuts off the Property changes in either direction when For testing, it's possible to use a map/inverseMap pair that are obviously not an "exact" inverse: var sourceProperty = new axon.Property( 0 );
var wrapperProperty = new axon.Property( sourceProperty );
var dynamicProperty = new axon.DynamicProperty( wrapperProperty, {
bidirectional: true,
// NOT a true inverse
map: n => n + 2,
inverseMap: n => n - 1
} );
// source: 0, dynamic: 2
dynamicProperty.value = 3;
// source: 2, dynamic: 3
sourceProperty.value = 5;
// source: 5, dynamic: 7 |
Pushed the main behavior, will be adding full tests. |
@ariel-phet should this change be reviewed? |
The example in #197 (comment) is not behaving as expected. See sample console output below. In all of the examples, the first call (to
|
Discussed with @jonathanolson via Zoom. The first and third calls in each example are actually done in |
@samreid @zepumph @chrisklus FYI.
This issue is related to understanding why
reentrant: true
is needed for a bidirectional DynamicProperty in GRAPHING_QUADRATICS/CoefficientSlider, see phetsims/graphing-quadratics#52 and phetsims/sun#417.Here's an example, a bidirectional mapping where
viewProperty
is the square ofmodelProperty
.In the console, here's what I observe:
When I set
viewProperty
to a value that does not involve floating point error, bothinverseMap
andmap
are called. Why ismap
called in this case?When I set
viewProperty
to a value that does involve floating point error, bothinverseMap
andmap
are called, and theninverseMap
is called again. Why ismap
called? Why isinverseMap
called a second time?When I set
modelProperty
, I seemap
andinverseMap
called. Why isinverseMap
called? Why do I never see a second call tomap
, as I did forinverseMap
withviewProperty
?The text was updated successfully, but these errors were encountered: