Closed samreid closed 1 year ago
This patch works great. I was able to remove all of the isSettingPhetioStateProperty
guards in Mean: Share and Balance and it still worked without any of the bugs those workarounds addressed.
Next steps:
isSettingPhetioStateProperty
across around 25 repos and see which can be eliminated base on this change.I believe that you are on a great track! Thanks for implementing. I believe that many cases will indeed be fixed by this, but in general there are more stateful items than just Properties. We don't want to be adding/removing/mutating dynamic elements during state setting, or also updating observable arrays etc. So we will likely not be able to cover all usages.
For example these usages in ProjectileMotion don't seem to be fixed by the patch.
I made a couple of adjustments, ensuring the unguarded set was private. Looks great though! Committed below. Thoughts?
After the commit, instrumented DerivedProperty instances cannot get updated during PhET-iO state set. So I'll add a check for that.
Love it!
Here's a chip-away for the remaining cases. The main rule:
If there is a guard like isSettingPhetioStateProperty.value
that is
phetioState: true
then the guard can probably be removed. The sim state should be tested before (to make sure it was already working OK) and after removal of the guard (to make sure it still works correctly after the change). I'll do a few examples then bring it to dev meeting for kicking off a chip-away.
Also the names above are from my memory and partly from the responsible devs list when I didn't recall. That doesn't mean the responsible dev needs to be the implementer---we can adjust accordingly at the dev meeting.
UPDATE: The cases in axon and center-and-variability could not be removed. But both in gravity-and-orbits could be removed, please see the commits below. Ready for team discussion and chip-away.
Self assigning to chip away.
Discussed with @samreid. I'm relucant to remove isSettingPhetioStateProperty
checks from existing code. First, the behavior of the guard that was added to ReadOnlyProperty.set
is not equivalent -- listeners are still called once, so code that was guarded by isSettingPhetioStateProperty
will be called once instead of not at all. Second, @samreid reported that he was only able to remove isSettingPhetioStateProperty
checks in a couple of places. So I feel that the return on investment here is likely to be low, and very likely to introduce problems. I'll certainly give this a try in new code. Self unassigning.
In ReadOnlyProperty.ts:
private unguardedSet( value: T ): void {
if ( !this.isDisposed ) {
if ( this.isDeferred ) {
this.deferredValue = value;
this.hasDeferredValue = true;
}
else if ( !this.equalsValue( value ) ) {
const oldValue = this.get();
this.setPropertyValue( value );
this._notifyListeners( oldValue );
}
}
}
Why are we not checking this.equalsValue( value )
earlier in this method? We may be deferring a value that is effectively a no-op.
Why are we not checking this.equalsValue( value ) earlier in this method? We may be deferring a value that is effectively a no-op.
@zepumph I'm unclear about whether the deferred value can be the same. What do you think?
@samreid will document this.
We determined today that this was not worth the time to go back to change/remove this workaround. It also has a low rate of success (most aren't removed). As a result, we will document this nuance in PhET-iO doc, and try to be more sparring with usages of isSettingPhetioStateProperty
in the future.
Doc updated. Closing
Just noting here that we the guard on ReadOnlyProperty added here was WAY too powerful, and we had to tamper it down to allow Properties to be changed during stateSetEmitter over in https://github.com/phetsims/phet-io/issues/1958.
@pixelzoom and I were got by this no-op today in ReadOnlyProperty.set()
. We both totally forgot about this feature, and how clever it is. I added some doc above. I hope that helps future us.
@marlitas and I discovered this during working on Mean: Share and Balance and @zepumph says it sounds promising. Instrumented stateful Properties should only accept values from the state during state set.
Hopefully we can get rid of all of the manual guards for
joist.isSettingPhetioStateProperty