-
Notifications
You must be signed in to change notification settings - Fork 5
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
Public API for isSettingStateProperty
should be read-only.
#311
Comments
Here is a working implementation of the proposal above. I used a patch instead of branches: Subject: [PATCH] Rename "Case Index" to "Case index", see https://github.com/phetsims/projectile-data-lab/issues/251
---
Index: phet-io/js/PhetioStateEngine.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/phet-io/js/PhetioStateEngine.ts b/phet-io/js/PhetioStateEngine.ts
--- a/phet-io/js/PhetioStateEngine.ts (revision f2f620fb6f958ac3e7c504355b7c7d1dd2652795)
+++ b/phet-io/js/PhetioStateEngine.ts (date 1715377244737)
@@ -16,7 +16,6 @@
import Emitter from '../../axon/js/Emitter.js';
import TEmitter, { TReadOnlyEmitter } from '../../axon/js/TEmitter.js';
-import TProperty from '../../axon/js/TProperty.js';
import PropertyStateHandler from '../../axon/js/PropertyStateHandler.js';
import propertyStateHandlerSingleton from '../../axon/js/propertyStateHandlerSingleton.js';
import merge from '../../phet-core/js/merge.js';
@@ -31,7 +30,7 @@
import dataStream from './dataStream.js';
import phetio from './phetio.js';
import { TPhetioEngine } from './phetioEngine.js';
-import isSettingPhetioStateProperty from '../../tandem/js/isSettingPhetioStateProperty.js';
+import { writableIsSettingPhetioStateProperty } from '../../tandem/js/isSettingPhetioStateProperty.js';
import isClearingPhetioDynamicElementsProperty from '../../tandem/js/isClearingPhetioDynamicElementsProperty.js';
import isPhetioStateEngineManagingPropertyValuesProperty from '../../tandem/js/isPhetioStateEngineManagingPropertyValuesProperty.js';
import { TPhetioStateEngine } from '../../tandem/js/TPhetioStateEngine.js';
@@ -74,7 +73,7 @@
// to indicate whether state is being set or not. In general when using for a sim. TANDEM/isSettingPhetioStateProperty
// should be preferred to this Property because it will exist for all brands (where this is only available in
// phet-io brand).
- public isSettingStateProperty: TProperty<boolean> = isSettingPhetioStateProperty;
+ public isSettingStateProperty = writableIsSettingPhetioStateProperty;
// a list of setStateHelpers. These are sim specific functions that help set state to avoid
// "Impossible set state errors".
Index: projectile-data-lab/js/sampling/view/SampleSizeThumbnailNode.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/projectile-data-lab/js/sampling/view/SampleSizeThumbnailNode.ts b/projectile-data-lab/js/sampling/view/SampleSizeThumbnailNode.ts
--- a/projectile-data-lab/js/sampling/view/SampleSizeThumbnailNode.ts (revision b00659aac770fd068b6c23828495f3b1ec3305a0)
+++ b/projectile-data-lab/js/sampling/view/SampleSizeThumbnailNode.ts (date 1715377375059)
@@ -187,7 +187,7 @@
}
};
- isSettingPhetioStateProperty.addListener( updateHistogram );
+ isSettingPhetioStateProperty.lazyLink( updateHistogram );
// Similar to code in VSMScreenView that updates the angle tool node and speed tool node when the data changes.
fields.forEach( field => {
Index: projectile-data-lab/js/common/view/HistogramNode.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/projectile-data-lab/js/common/view/HistogramNode.ts b/projectile-data-lab/js/common/view/HistogramNode.ts
--- a/projectile-data-lab/js/common/view/HistogramNode.ts (revision b00659aac770fd068b6c23828495f3b1ec3305a0)
+++ b/projectile-data-lab/js/common/view/HistogramNode.ts (date 1715377366180)
@@ -258,7 +258,7 @@
}
};
- isSettingPhetioStateProperty.addListener( () => updateHistogram( true ) );
+ isSettingPhetioStateProperty.lazyLink( () => updateHistogram( true ) );
// Similar to code in VSMScreenView that updates the angle tool node and speed tool node when the data changes.
fields.forEach( field => {
Index: tandem/js/isSettingPhetioStateProperty.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tandem/js/isSettingPhetioStateProperty.ts b/tandem/js/isSettingPhetioStateProperty.ts
--- a/tandem/js/isSettingPhetioStateProperty.ts (revision a444e3f516f4c52eea41f71d87e4051450fa1c1c)
+++ b/tandem/js/isSettingPhetioStateProperty.ts (date 1715377505170)
@@ -2,15 +2,22 @@
/**
* Property that is set to true when the PhET-iO State Engine is setting the state of a simulation.
+ *
* @author Sam Reid (PhET Interactive Simulations)
* @author Michael Kauzmann (PhET Interactive Simulations)
*/
import tandemNamespace from './tandemNamespace.js';
import TinyProperty from '../../axon/js/TinyProperty.js';
+import TReadOnlyProperty from '../../axon/js/TReadOnlyProperty.js';
-const isSettingPhetioStateProperty = new TinyProperty( false );
+// This one is for specialized usage in the PhetioStateEngine, which changes the value
+const writableIsSettingPhetioStateProperty = new TinyProperty( false );
+
+// Simulations can use this one to observe the value
+const isSettingPhetioStateProperty: TReadOnlyProperty<boolean> = writableIsSettingPhetioStateProperty;
tandemNamespace.register( 'isSettingPhetioStateProperty', isSettingPhetioStateProperty );
-export default isSettingPhetioStateProperty;
\ No newline at end of file
+export default isSettingPhetioStateProperty;
+export { writableIsSettingPhetioStateProperty };
\ No newline at end of file
This is also passing all precommit hooks (took 1m45s). @pixelzoom or @zepumph please review and feel free to commit if it passes review. |
The patch is marginally better, but still provides a public API for modifying Since PhetioStateEngine is the sole place where isSettingPhetioStateProperty should be set, a better implementation would be:
const isSettingPhetioStateProperty = PhetioStateEngine.isSettingPhetioStateProperty;
tandemNamespace.register( 'isSettingPhetioStateProperty', isSettingPhetioStateProperty );
export default isSettingPhetioStateProperty; |
isSettingStateProperty
should be TReadOnlyProperty<boolean>
.isSettingStateProperty
should be read-only.
Below is a patch to demonstrate the implementation I described in #311 (comment). It's equivalent to the current implementation in that patchSubject: [PATCH] add isSettingPhetioStateProperty check, https://github.com/phetsims/gas-properties/issues/238
---
Index: phet-io/js/PhetioStateEngine.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/phet-io/js/PhetioStateEngine.ts b/phet-io/js/PhetioStateEngine.ts
--- a/phet-io/js/PhetioStateEngine.ts (revision f2f620fb6f958ac3e7c504355b7c7d1dd2652795)
+++ b/phet-io/js/PhetioStateEngine.ts (date 1715379079440)
@@ -31,10 +31,10 @@
import dataStream from './dataStream.js';
import phetio from './phetio.js';
import { TPhetioEngine } from './phetioEngine.js';
-import isSettingPhetioStateProperty from '../../tandem/js/isSettingPhetioStateProperty.js';
import isClearingPhetioDynamicElementsProperty from '../../tandem/js/isClearingPhetioDynamicElementsProperty.js';
import isPhetioStateEngineManagingPropertyValuesProperty from '../../tandem/js/isPhetioStateEngineManagingPropertyValuesProperty.js';
import { TPhetioStateEngine } from '../../tandem/js/TPhetioStateEngine.js';
+import TinyProperty from '../../axon/js/TinyProperty.js';
// constants
const DELETED_VALUE = 'DELETED'; // this is copied in documentation for PhetioEngineIO.getChangedState(), and used in Studio.
@@ -48,6 +48,8 @@
alreadyCalledForThisStateSet?: boolean;
};
+const isSettingPhetioStateProperty = new TinyProperty( false );
+
class PhetioStateEngine implements TPhetioStateEngine {
// emits before state the state is set. Emits with the state object that will be set. Use the
@@ -86,6 +88,8 @@
hasListenerOrderDependencies: true // We rely on Properties undeferring value first (since everything else just notifies).
} );
+ public static readonly isSettingPhetioStateProperty = isSettingPhetioStateProperty;
+
public constructor( private readonly phetioEngine: TPhetioEngine, providedOptions?: PhetioStateEngineOptions ) {
const options = optionize<PhetioStateEngineOptions>()( {
Index: tandem/js/isSettingPhetioStateProperty.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tandem/js/isSettingPhetioStateProperty.ts b/tandem/js/isSettingPhetioStateProperty.ts
--- a/tandem/js/isSettingPhetioStateProperty.ts (revision a444e3f516f4c52eea41f71d87e4051450fa1c1c)
+++ b/tandem/js/isSettingPhetioStateProperty.ts (date 1715379079447)
@@ -7,9 +7,9 @@
*/
import tandemNamespace from './tandemNamespace.js';
-import TinyProperty from '../../axon/js/TinyProperty.js';
+import PhetioStateEngine from '../../phet-io/js/PhetioStateEngine.js';
-const isSettingPhetioStateProperty = new TinyProperty( false );
+const isSettingPhetioStateProperty = PhetioStateEngine.isSettingPhetioStateProperty;
tandemNamespace.register( 'isSettingPhetioStateProperty', isSettingPhetioStateProperty );
|
Below is a patch that I believe addresses the problem. patchSubject: [PATCH] add isSettingPhetioStateProperty check, https://github.com/phetsims/gas-properties/issues/238
---
Index: phet-io/js/PhetioStateEngine.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/phet-io/js/PhetioStateEngine.ts b/phet-io/js/PhetioStateEngine.ts
--- a/phet-io/js/PhetioStateEngine.ts (revision f2f620fb6f958ac3e7c504355b7c7d1dd2652795)
+++ b/phet-io/js/PhetioStateEngine.ts (date 1715379455639)
@@ -31,10 +31,11 @@
import dataStream from './dataStream.js';
import phetio from './phetio.js';
import { TPhetioEngine } from './phetioEngine.js';
-import isSettingPhetioStateProperty from '../../tandem/js/isSettingPhetioStateProperty.js';
import isClearingPhetioDynamicElementsProperty from '../../tandem/js/isClearingPhetioDynamicElementsProperty.js';
import isPhetioStateEngineManagingPropertyValuesProperty from '../../tandem/js/isPhetioStateEngineManagingPropertyValuesProperty.js';
import { TPhetioStateEngine } from '../../tandem/js/TPhetioStateEngine.js';
+import TinyProperty from '../../axon/js/TinyProperty.js';
+import TReadOnlyProperty from '../../axon/js/TReadOnlyProperty.js';
// constants
const DELETED_VALUE = 'DELETED'; // this is copied in documentation for PhetioEngineIO.getChangedState(), and used in Studio.
@@ -48,6 +49,8 @@
alreadyCalledForThisStateSet?: boolean;
};
+const isSettingPhetioStateProperty = new TinyProperty( false );
+
class PhetioStateEngine implements TPhetioStateEngine {
// emits before state the state is set. Emits with the state object that will be set. Use the
@@ -86,6 +89,8 @@
hasListenerOrderDependencies: true // We rely on Properties undeferring value first (since everything else just notifies).
} );
+ public static readonly isSettingPhetioStateProperty: TReadOnlyProperty<boolean> = isSettingPhetioStateProperty;
+
public constructor( private readonly phetioEngine: TPhetioEngine, providedOptions?: PhetioStateEngineOptions ) {
const options = optionize<PhetioStateEngineOptions>()( {
Index: projectile-data-lab/js/common/view/HistogramNode.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/projectile-data-lab/js/common/view/HistogramNode.ts b/projectile-data-lab/js/common/view/HistogramNode.ts
--- a/projectile-data-lab/js/common/view/HistogramNode.ts (revision b00659aac770fd068b6c23828495f3b1ec3305a0)
+++ b/projectile-data-lab/js/common/view/HistogramNode.ts (date 1715379466140)
@@ -258,7 +258,7 @@
}
};
- isSettingPhetioStateProperty.addListener( () => updateHistogram( true ) );
+ isSettingPhetioStateProperty.link( () => updateHistogram( true ) );
// Similar to code in VSMScreenView that updates the angle tool node and speed tool node when the data changes.
fields.forEach( field => {
Index: tandem/js/isSettingPhetioStateProperty.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tandem/js/isSettingPhetioStateProperty.ts b/tandem/js/isSettingPhetioStateProperty.ts
--- a/tandem/js/isSettingPhetioStateProperty.ts (revision a444e3f516f4c52eea41f71d87e4051450fa1c1c)
+++ b/tandem/js/isSettingPhetioStateProperty.ts (date 1715379079447)
@@ -7,9 +7,9 @@
*/
import tandemNamespace from './tandemNamespace.js';
-import TinyProperty from '../../axon/js/TinyProperty.js';
+import PhetioStateEngine from '../../phet-io/js/PhetioStateEngine.js';
-const isSettingPhetioStateProperty = new TinyProperty( false );
+const isSettingPhetioStateProperty = PhetioStateEngine.isSettingPhetioStateProperty;
tandemNamespace.register( 'isSettingPhetioStateProperty', isSettingPhetioStateProperty );
Index: projectile-data-lab/js/sampling/view/SampleSizeThumbnailNode.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/projectile-data-lab/js/sampling/view/SampleSizeThumbnailNode.ts b/projectile-data-lab/js/sampling/view/SampleSizeThumbnailNode.ts
--- a/projectile-data-lab/js/sampling/view/SampleSizeThumbnailNode.ts (revision b00659aac770fd068b6c23828495f3b1ec3305a0)
+++ b/projectile-data-lab/js/sampling/view/SampleSizeThumbnailNode.ts (date 1715379483432)
@@ -187,7 +187,7 @@
}
};
- isSettingPhetioStateProperty.addListener( updateHistogram );
+ isSettingPhetioStateProperty.link( updateHistogram );
// Similar to code in VSMScreenView that updates the angle tool node and speed tool node when the data changes.
fields.forEach( field => { In PhetioStateEngine: const isSettingPhetioStateProperty = new TinyProperty( false );
...
public static readonly isSettingPhetioStateProperty: TReadOnlyProperty<boolean> = isSettingPhetioStateProperty; Note that this requires PDL to use |
This proposed line is incompatible with our constraints: In tandem/js/isSettingPhetioStateProperty.ts import PhetioStateEngine from '../../phet-io/js/PhetioStateEngine.js'; phet-io cannot be imported from tandem, because phet-io is a private repo and not everyone (such as open source clients) can clone it. |
Does it also follow that sims cannot import PhetioStateEngine.ts to use |
Correct, public code cannot statically import private code. Instead, we use a dynamic import in simLauncher like so: https://github.com/phetsims/joist/blob/main/js/simLauncher.ts#L23-L31 |
Then I guess your patch in #311 (comment) is as good as it's going to get. I'm OK with that. |
@zepumph are you OK with @samreid's patch in #311 (comment)? |
Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
…ndem#311 Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
Yes perfect. Thanks for discussing. I committed with @samreid this morning. |
Thanks @zepumph, @pixelzoom want to review or close? |
👍🏻 |
Noted while investigating phetsims/gas-properties#240 (comment), yet another problem that involves
isSettingPhetioStateProperty
.I find myself having to check
isSettingPhetioStateProperty
frequently when instrumenting sims, to short-circuit code that should not be called when restoring state. So I was surprised to find that this rather important (global!) Property allows me to set it, with no complains from tsc. For example:My understanding is that the only place that
isSettingPhetioStateProperty
should be set (and therefore the only place this should be settable) is in PhetioStateEngine.ts, specifically:Let's tighten this up so that
isSettingStateProperty
is read-only.The text was updated successfully, but these errors were encountered: