-
Notifications
You must be signed in to change notification settings - Fork 12
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
Provide PhET-iO state compatibility for PhET Studio #385
Comments
Subject: [PATCH] Remove unnecessary TODO, see https://github.com/phetsims/least-squares-regression/issues/90
---
Index: js/common/model/Skater.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/Skater.js b/js/common/model/Skater.js
--- a/js/common/model/Skater.js (revision 07fe2891a653a93e0c2ca35b77ed7f145b82e10a)
+++ b/js/common/model/Skater.js (date 1736372150706)
@@ -57,8 +57,8 @@
// @public - The track the skater is on, or null if free-falling
this.trackProperty = new Property( null, {
- tandem: tandem.createTandem( 'trackProperty' ),
- phetioValueType: NullableIO( ReferenceIO( Track.TrackIO ) )
+ // tandem: tandem.createTandem( 'trackProperty' ),
+ // phetioValueType: NullableIO( ReferenceIO( Track.TrackIO ) )
} );
// @public {number} - Parameter along the parametric spline, unitless since it is in parametric space
Index: js/common/model/Track.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/Track.js b/js/common/model/Track.js
--- a/js/common/model/Track.js (revision 07fe2891a653a93e0c2ca35b77ed7f145b82e10a)
+++ b/js/common/model/Track.js (date 1736371982187)
@@ -1136,7 +1136,12 @@
* @public
*/
disposeControlPoints() {
- this.controlPoints.forEach( controlPoint => this.model.controlPointGroup.disposeElement( controlPoint ) );
+ this.controlPoints.forEach( controlPoint => {
+
+ if ( !controlPoint.isDisposed ) {
+ this.model.controlPointGroup.disposeElement( controlPoint )
+ }
+ } );
}
}
Index: js/graphs/model/GraphsModel.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/graphs/model/GraphsModel.js b/js/graphs/model/GraphsModel.js
--- a/js/graphs/model/GraphsModel.js (revision 07fe2891a653a93e0c2ca35b77ed7f145b82e10a)
+++ b/js/graphs/model/GraphsModel.js (date 1736380283402)
@@ -10,6 +10,7 @@
import EnumerationDeprecatedProperty from '../../../../axon/js/EnumerationDeprecatedProperty.js';
import Multilink from '../../../../axon/js/Multilink.js';
import NumberProperty from '../../../../axon/js/NumberProperty.js';
+import Tandem from '../../../../tandem/js/Tandem.js';
import Range from '../../../../dot/js/Range.js';
import Utils from '../../../../dot/js/Utils.js';
import EnumerationDeprecated from '../../../../phet-core/js/EnumerationDeprecated.js';
@@ -323,7 +324,7 @@
const parabolaTrack = PremadeTracks.createTrack( this, parabolaControlPoints, {
configurable: this.tracksConfigurable,
- tandem: tandem.createTandem( 'parabolaTrack' ),
+ tandem: Tandem.OPT_OUT,
phetioState: false
} );
@@ -348,7 +349,7 @@
} );
const doubleWellTrack = PremadeTracks.createTrack( this, doubleWellControlPoints, {
configurable: this.tracksConfigurable,
- tandem: tandem.createTandem( 'doubleWellTrack' ),
+ tandem: Tandem.OPT_OUT,
phetioState: false
} );
Index: js/common/model/EnergySkateParkTrackSetModel.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/EnergySkateParkTrackSetModel.js b/js/common/model/EnergySkateParkTrackSetModel.js
--- a/js/common/model/EnergySkateParkTrackSetModel.js (revision 07fe2891a653a93e0c2ca35b77ed7f145b82e10a)
+++ b/js/common/model/EnergySkateParkTrackSetModel.js (date 1736380336958)
@@ -11,6 +11,7 @@
import energySkatePark from '../../energySkatePark.js';
import EnergySkateParkSaveSampleModel from './EnergySkateParkSaveSampleModel.js';
import PremadeTracks from './PremadeTracks.js';
+import Tandem from '../../../../tandem/js/Tandem.js';
class EnergySkateParkTrackSetModel extends EnergySkateParkSaveSampleModel {
@@ -125,7 +126,7 @@
if ( trackType === PremadeTracks.TrackType.PARABOLA ) {
const parabolaControlPoints = PremadeTracks.createParabolaControlPoints( this, options.parabolaControlPointOptions );
const parabolaTrack = EnergySkateParkTrackSetModel.createPremadeTrack( this, parabolaControlPoints, merge( {
- tandem: tandem.createTandem( 'parabolaTrack' )
+ tandem: Tandem.OPT_OUT
}, options.parabolaTrackOptions ) );
tracks.push( parabolaTrack );
@@ -137,14 +138,14 @@
// Flag to indicate whether the skater transitions from the right edge of this track directly to the ground
// see #164
slopeToGround: true,
- tandem: tandem.createTandem( 'slopeTrack' )
+ tandem: Tandem.OPT_OUT
}, options.slopeTrackOptions ) );
tracks.push( slopeTrack );
}
else if ( trackType === PremadeTracks.TrackType.DOUBLE_WELL ) {
const doubleWellControlPoints = PremadeTracks.createDoubleWellControlPoints( this, options.doubleWellControlPointOptions );
const doubleWellTrack = EnergySkateParkTrackSetModel.createPremadeTrack( this, doubleWellControlPoints, merge( {
- tandem: tandem.createTandem( 'doubleWellTrack' )
+ tandem: Tandem.OPT_OUT
}, options.doubleWellTrackOptions ) );
tracks.push( doubleWellTrack );
}
@@ -152,7 +153,7 @@
const loopControlPoints = PremadeTracks.createLoopControlPoints( this, options.loopControlPointOptions );
const loopTrack = EnergySkateParkTrackSetModel.createPremadeTrack( this, loopControlPoints, merge( {
draggable: this.tracksDraggable,
- tandem: tandem.createTandem( 'loopTrack' )
+ tandem: Tandem.OPT_OUT
}, options.loopTrackOptions ) );
tracks.push( loopTrack );
}
Index: js/common/model/ControlPoint.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/ControlPoint.js b/js/common/model/ControlPoint.js
--- a/js/common/model/ControlPoint.js (revision 07fe2891a653a93e0c2ca35b77ed7f145b82e10a)
+++ b/js/common/model/ControlPoint.js (date 1736380094387)
@@ -44,7 +44,7 @@
tandem: Tandem.REQUIRED,
phetioType: ControlPoint.ControlPointIO,
- phetioState: PhetioObject.DEFAULT_OPTIONS.phetioState
+ phetioState: false
}, options );
const tandem = options.tandem;
@@ -62,14 +62,14 @@
// @public - where it would be if it hadn't snapped to another point during dragging
this.sourcePositionProperty = new Vector2Property( new Vector2( x, y ), {
tandem: tandem.createTandem( 'sourcePositionProperty' ),
- phetioState: options.phetioState // in state only if containing Track is
+ phetioState: false
} );
// @public {ControlPoint} - Another ControlPoint that this ControlPoint is going to 'snap' to if released.
this.snapTargetProperty = new Property( null, {
tandem: tandem.createTandem( 'snapTargetProperty' ),
phetioValueType: NullableIO( ControlPoint.ControlPointIO ),
- phetioState: options.phetioState // in state only if containing Track is
+ phetioState: false
} );
// Where it is shown on the screen. Same as sourcePosition (if not snapped) or snapTarget.position (if snapped).
@@ -77,16 +77,16 @@
// connection is possible
// @public {Vector2}
this.positionProperty = new DerivedProperty( [ this.sourcePositionProperty, this.snapTargetProperty ],
- ( sourcePosition, snapTarget ) => snapTarget ? snapTarget.positionProperty.value : sourcePosition, {
+ ( sourcePosition, snapTarget ) => snapTarget ? sourcePosition : sourcePosition, {
tandem: tandem.createTandem( 'positionProperty' ),
phetioValueType: Vector2.Vector2IO,
- phetioState: options.phetioState
+ phetioState: false
} );
// @public {BooleanProperty} - whether the control point is currently being dragged
this.draggingProperty = new BooleanProperty( false, {
tandem: tandem.createTandem( 'draggingProperty' ),
- phetioState: options.phetioState
+ phetioState: false
} );
// @private
@@ -95,6 +95,7 @@
this.sourcePositionProperty.dispose();
this.snapTargetProperty.dispose();
this.draggingProperty.dispose();
+ console.log('disposed')
};
}
Index: js/common/model/EnergySkateParkModel.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/EnergySkateParkModel.js b/js/common/model/EnergySkateParkModel.js
--- a/js/common/model/EnergySkateParkModel.js (revision 07fe2891a653a93e0c2ca35b77ed7f145b82e10a)
+++ b/js/common/model/EnergySkateParkModel.js (date 1736386670173)
@@ -41,6 +41,7 @@
import TimeSpeed from '../../../../scenery-phet/js/TimeSpeed.js';
import PhetioGroup from '../../../../tandem/js/PhetioGroup.js';
import PhetioObject from '../../../../tandem/js/PhetioObject.js';
+import Tandem from '../../../../tandem/js/Tandem.js';
import IOType from '../../../../tandem/js/types/IOType.js';
import ReferenceIO from '../../../../tandem/js/types/ReferenceIO.js';
import energySkatePark from '../../energySkatePark.js';
@@ -90,7 +91,7 @@
super( {
phetioType: EnergySkateParkModel.EnergySkateParkModelIO,
tandem: tandem,
- phetioState: false
+ phetioState: true
} );
options = merge( {
@@ -133,7 +134,7 @@
assert && options && assert( !options.hasOwnProperty( 'tandem' ), 'tandem is managed by the PhetioGroup' );
return new ControlPoint( x, y, merge( {}, options, { tandem: tandem, phetioDynamicElement: true } ) );
}, [ 0, 0, {} ], {
- tandem: tandem.createTandem( 'controlPointGroup' ),
+ tandem: Tandem.OPT_OUT,
phetioType: PhetioGroup.PhetioGroupIO( ControlPoint.ControlPointIO ),
phetioDynamicElementName: 'controlPoint'
} );
@@ -144,14 +145,14 @@
this.trackGroup = new PhetioGroup( ( tandem, controlPoints, parents, options ) => {
assert && options && assert( !options.hasOwnProperty( 'tandem' ), 'tandem is managed by the PhetioGroup' );
return new Track( this, controlPoints, parents, merge( {}, options, {
- tandem: tandem,
+ tandem: Tandem.OPT_OUT,
phetioDynamicElement: true
} ) );
}, [ _.range( 20 ).map( n => this.controlPointGroup.createNextElement( n * 100, 0 ) ), [], {
draggable: true,
configurable: true
} ], {
- tandem: tandem.createTandem( 'trackGroup' ),
+ tandem: Tandem.OPT_OUT,
phetioType: PhetioGroup.PhetioGroupIO( Track.TrackIO ),
phetioDynamicElementName: 'track'
} );
@@ -282,7 +283,7 @@
// @public
this.tracks = createObservableArray( {
phetioType: createObservableArray.ObservableArrayIO( ReferenceIO( Track.TrackIO ) ),
- tandem: tandem.createTandem( 'tracks' )
+ tandem: Tandem.OPT_OUT
} );
// Determine when to show/hide the track edit buttons (cut track or delete control point)
@@ -1550,7 +1551,9 @@
removeAndDisposeTrack( trackToRemove ) {
assert && assert( this.tracks.includes( trackToRemove ), 'trying to remove track that is not in the list' );
this.tracks.remove( trackToRemove );
- this.trackGroup.disposeElement( trackToRemove );
+ if ( !trackToRemove.isDisposed ) {
+ this.trackGroup.disposeElement( trackToRemove );
+ }
}
/**
@@ -1883,6 +1886,143 @@
this.removeAndDisposeTrack( track );
}
}
+
+ /**
+ * @public
+ */
+ toStateObject() {
+
+ if ( this.tracksConfigurable && !this.tracksDraggable ) {
+ const result = {
+ controlPoints: [],
+ tracks: this.tracks.map( track => {
+ const map = track.controlPoints.map( controlPoint => {
+ return {
+ x: controlPoint.sourcePositionProperty.value.x,
+ y: controlPoint.sourcePositionProperty.value.y
+ };
+ } );
+ return map;
+ } )
+ };
+ return result;
+ }
+
+ else if ( this.tracksDraggable ) {
+ // 1. Gather all control points (we'll assign them numeric IDs).
+ const controlPoints = [];
+ const controlPointMap = new Map(); // so we can map "controlPoint" => its new integer ID
+
+ // go through our PhetioGroup of control points
+ for ( let i = 0; i < this.controlPointGroup.getArray().length; i++ ) {
+ const cp = this.controlPointGroup.getElement( i );
+ controlPoints.push( {
+ id: i,
+ x: cp.sourcePositionProperty.value.x,
+ y: cp.sourcePositionProperty.value.y
+ } );
+ controlPointMap.set( cp, i );
+ }
+
+ // 2. Gather all tracks, referencing the controlPointIDs
+ const tracks = [];
+ for ( let t = 0; t < this.tracks.length; t++ ) {
+ const track = this.tracks[ t ];
+ const controlPointIDs = track.controlPoints.map( cp => controlPointMap.get( cp ) );
+
+ tracks.push( {
+ id: t,
+ controlPointIDs: controlPointIDs,
+ physical: track.physicalProperty.value,
+ dropped: track.droppedProperty.value,
+ leftThePanel: track.leftThePanelProperty.value
+ } );
+ }
+
+ // Return the minimal JSON object
+ const myState = {
+ controlPoints: controlPoints,
+ tracks: tracks
+ };
+ return myState;
+ }
+ else {
+ return {
+ controlPoints: [],
+ tracks: []
+ };
+ }
+ }
+
+ /**
+ * Rebuild the control points and tracks from a minimal JSON object as produced by toStateObject().
+ *
+ * The incoming `state` should match the schema described in toStateObject().
+ * @public
+ */
+ applyState( state ) {
+ if ( this.tracksConfigurable && !this.tracksDraggable ) {
+
+ this.tracks.forEach( ( track, trackIndex ) => {
+ for ( let i = 0; i < track.controlPoints.length; i++ ) {
+ const controlPoint = state.tracks[ trackIndex ][ i ];
+ const vector2 = new Vector2( controlPoint.x, controlPoint.y );
+ console.log( `set track ${trackIndex} point ${i} to ${vector2.x}, ${vector2.y}` );
+ track.controlPoints[ i ].sourcePositionProperty.set( vector2 );
+ }
+ } );
+
+ return;
+ }
+
+ if ( !this.tracksDraggable ) {
+ return;
+ }
+
+ // this.removeAllTracks(); // custom method that removes & disposes all tracks
+ this.clearTracks(); // custom method that removes & disposes all tracks
+
+ const newControlPoints = {};
+ state.controlPoints.forEach( cpState => {
+
+ // TODO: Call with isFromStateSetting: true
+ const controlPoint = this.controlPointGroup.createNextElement(
+ cpState.x,
+ cpState.y
+ );
+ newControlPoints[ cpState.id ] = controlPoint;
+ } );
+
+ // 3. Re-create all tracks
+ // We look up each track's controlPointIDs and map them back to the actual controlPoint objects.
+ state.tracks.forEach( trackState => {
+ const trackControlPoints = trackState.controlPointIDs.map( id => newControlPoints[ id ] );
+
+ // The final arguments to createNextElement are the "parents" array and an options object.
+ // Minimal usage: pass empty arrays and the standard "draggable/configurable" options, or whatever is needed.
+ const newTrack = this.trackGroup.createNextElement(
+ trackControlPoints,
+ [], // parents
+ {
+ draggable: true,
+ configurable: true,
+ splittable: true,
+ attachable: true
+ }
+ );
+
+ // If you like, set newTrack.physicalProperty.value = true or any other track-level props
+ newTrack.physicalProperty.value = trackState.physical;
+ newTrack.droppedProperty.value = trackState.dropped;
+ newTrack.leftThePanelProperty.value = trackState.leftThePanel;
+
+ // Then add it to our main array
+ this.tracks.add( newTrack );
+
+ // Done! We’ve just replaced all control points and tracks with a fresh copy from state.
+ console.log( 'Finished applying state:', state );
+ } );
+ }
}
/**
@@ -1900,7 +2040,20 @@
EnergySkateParkModel.EnergySkateParkModelIO = new IOType( 'EnergySkateParkModelIO', {
valueType: EnergySkateParkModel,
- documentation: 'The model for the Skate Park.'
+ documentation: 'The model for the Skate Park.',
+ toStateObject: model => model.toStateObject(),
+ applyState: ( model, stateObject ) => {
+ model.applyState( stateObject );
+ },
+// This describes the high-level shape of the returned state object
+ stateSchema: {
+
+ // Array of controlPoint objects, each with id, x, y
+ controlPoints: IOType.ObjectIO,
+
+ // Array of tracks, each with id and an array of controlPointIDs
+ tracks: IOType.ObjectIO
+ }
} );
energySkatePark.register( 'EnergySkateParkModel', EnergySkateParkModel ); |
Even though the patch above is just a proposal and not fully complete, I think we should commit it before working on #387, otherwise we will have to rewrite most of it afterwards. |
Also: * Update Spline Typescript Type * Remove unused "parents" for Track
Patch that eliminates the tracks observableArray: Subject: [PATCH] Address ui interaction corner cases for tracks and control points, see https://github.com/phetsims/energy-skate-park/issues/385
---
Index: js/common/view/EnergySkateParkControlPanel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/EnergySkateParkControlPanel.ts b/js/common/view/EnergySkateParkControlPanel.ts
--- a/js/common/view/EnergySkateParkControlPanel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/EnergySkateParkControlPanel.ts (date 1736957318449)
@@ -76,8 +76,8 @@
let trackRadioButtons = null;
if ( options.showTrackButtons ) {
- trackRadioButtons = new SceneSelectionRadioButtonGroup( model, screenView, tandem.createTandem( 'sceneSelectionRadioButtonGroup' ) );
- children.push( trackRadioButtons );
+ // trackRadioButtons = new SceneSelectionRadioButtonGroup( model, screenView, tandem.createTandem( 'sceneSelectionRadioButtonGroup' ) );
+ // children.push( trackRadioButtons );
}
let frictionControls = null;
Index: js/playground/view/EnergySkateParkPlaygroundScreenView.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/playground/view/EnergySkateParkPlaygroundScreenView.ts b/js/playground/view/EnergySkateParkPlaygroundScreenView.ts
--- a/js/playground/view/EnergySkateParkPlaygroundScreenView.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/playground/view/EnergySkateParkPlaygroundScreenView.ts (date 1736957770659)
@@ -58,7 +58,7 @@
} );
this.bottomLayer.addChild( this.trackToolbox );
- model.tracks.addItemAddedListener( this.addTrackNode.bind( this ) );
+ model.trackGroup.elementCreatedEmitter.addListener( track => this.addTrackNode( track ) );
this.clearButton = new EraserButton( {
iconWidth: 30,
@@ -71,7 +71,7 @@
this.addChild( this.clearButton );
// add any other TrackNodes eagerly in case model has some initial Tracks, like when we are debugging
- model.tracks.map( this.addTrackNode.bind( this ) );
+ model.trackGroup.forEach( this.addTrackNode.bind( this ) );
this.timeControlNode.left = this.modelViewTransform.modelToViewX( 0.5 );
this.trackToolbox.right = this.modelViewTransform.modelToViewX( -0.5 );
@@ -83,7 +83,8 @@
* handle disposal.
*/
public addTrackNode( track: Track ): TrackNode {
- const trackNode = this.trackNodeGroup.createNextElement( track, this.modelViewTransform, this.availableModelBoundsProperty );
+ // new TrackNode( track, modelViewTransform, availableBoundsProperty, Tandem.OPT_OUT, options )
+ const trackNode = new TrackNode( track, this.modelViewTransform, this.availableModelBoundsProperty, Tandem.OPT_OUT );
this.trackNodes.push( trackNode );
this.trackLayer.addChild( trackNode );
@@ -96,11 +97,11 @@
this.trackNodes.splice( index, 1 );
// Clean up memory leak
- this.model.tracks.removeItemRemovedListener( itemRemovedListener );
+ this.model.trackGroup.elementDisposedEmitter.removeListener( itemRemovedListener );
trackNode.dispose();
}
};
- this.model.tracks.addItemRemovedListener( itemRemovedListener );
+ this.model.trackGroup.elementDisposedEmitter.addListener( itemRemovedListener );
return trackNode;
}
Index: js/playground/model/EnergySkateParkPlaygroundModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/playground/model/EnergySkateParkPlaygroundModel.ts b/js/playground/model/EnergySkateParkPlaygroundModel.ts
--- a/js/playground/model/EnergySkateParkPlaygroundModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/playground/model/EnergySkateParkPlaygroundModel.ts (date 1736955879092)
@@ -69,7 +69,6 @@
*/
public clearTracks(): void {
- this.tracks.clear();
this.trackGroup.clear();
this.controlPointGroup.clear();
Index: js/common/view/TrackNode.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/TrackNode.ts b/js/common/view/TrackNode.ts
--- a/js/common/view/TrackNode.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/TrackNode.ts (date 1736954495470)
@@ -120,11 +120,13 @@
// only "configurable" tracks have draggable control points, and individual control points may have dragging
// disabled - also, "icon" TrackNodes do not display ControlPoints
- if ( track.configurable && !options.isIcon ) {
+
+ console.log( 'creating track node, number of control points is ' + track.controlPoints.length );
+ if ( ( track.configurable || true ) && !options.isIcon ) {
for ( let i = 0; i < track.controlPoints.length; i++ ) {
const controlPoint = track.controlPoints[ i ];
- if ( controlPoint.visible ) {
+ if ( controlPoint.visible || true ) {
const isEndPoint = i === 0 || i === track.controlPoints.length - 1;
const controlPointNode = new ControlPointNode( this, this.trackDragHandler, i, isEndPoint, tandem.createTandem( `controlPointNode${i}` ) );
this.addChild( controlPointNode );
Index: js/common/view/EnergySkateParkTrackSetScreenView.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/EnergySkateParkTrackSetScreenView.ts b/js/common/view/EnergySkateParkTrackSetScreenView.ts
--- a/js/common/view/EnergySkateParkTrackSetScreenView.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/EnergySkateParkTrackSetScreenView.ts (date 1736964502723)
@@ -13,14 +13,15 @@
import energySkatePark from '../../energySkatePark.js';
import EnergySkateParkTrackSetModel from '../model/EnergySkateParkTrackSetModel.js';
import EnergySkateParkSaveSampleScreenView from './EnergySkateParkSaveSampleScreenView.js';
+import TrackNode from './TrackNode.js';
export default class EnergySkateParkTrackSetScreenView extends EnergySkateParkSaveSampleScreenView {
public constructor( model: EnergySkateParkTrackSetModel, tandem: Tandem, options?: IntentionalAny ) {
super( model, tandem, options );
- const trackNodes = model.tracks.map( track => {
- return this.trackNodeGroup.createNextElement( track, this.modelViewTransform, this.availableModelBoundsProperty );
+ const trackNodes = model.trackGroup.map( track => {
+ return new TrackNode( track, this.modelViewTransform, this.availableModelBoundsProperty, Tandem.OPT_OUT );
} );
trackNodes.forEach( trackNode => {
@@ -28,7 +29,7 @@
} );
model.sceneProperty.link( scene => {
- _.forEach( model.tracks, ( track, i ) => {
+ _.forEach( model.trackGroup.getArray(), ( track, i ) => {
trackNodes[ i ].visible = scene === i;
} );
Index: js/common/view/ControlPointNode.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/ControlPointNode.ts b/js/common/view/ControlPointNode.ts
--- a/js/common/view/ControlPointNode.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/ControlPointNode.ts (date 1736954674458)
@@ -79,6 +79,8 @@
}
controlPoint.positionProperty.link( position => {
+
+ console.log( phet.preloads.phetio.queryParameters.frameTitle, 'control point position changed' );
this.translation = modelViewTransform.modelToViewPosition( position );
} );
Index: js/common/model/PremadeTracks.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/PremadeTracks.ts b/js/common/model/PremadeTracks.ts
--- a/js/common/model/PremadeTracks.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/model/PremadeTracks.ts (date 1736962728896)
@@ -295,7 +295,9 @@
* Create a track from the provided control points.
*/
createTrack( model: EnergySkateParkModel, controlPoints: ControlPoint[], options: IntentionalAny ): Track {
- return new Track( model, controlPoints, options );
+ options && delete options.tandem;
+ return model.trackGroup.createNextElement( controlPoints, options );
+ // return new Track( model, controlPoints, options );
},
TrackType: TrackType as IntentionalAny
Index: js/common/model/EnergySkateParkTrackSetModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/EnergySkateParkTrackSetModel.ts b/js/common/model/EnergySkateParkTrackSetModel.ts
--- a/js/common/model/EnergySkateParkTrackSetModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/model/EnergySkateParkTrackSetModel.ts (date 1736955879118)
@@ -74,8 +74,8 @@
* @param sceneIndex - index identifying the scene
*/
private updateActiveTrack( sceneIndex: number ): void {
- for ( let i = 0; i < this.tracks.length; i++ ) {
- const track = this.tracks.get( i );
+ for ( let i = 0; i < this.trackGroup.getArray().length; i++ ) {
+ const track = this.trackGroup.getArray()[i];
track.physicalProperty.value = ( i === sceneIndex );
// Reset the skater position when the track is changed, see #179
@@ -93,7 +93,7 @@
// During state set, nodes can temporarily go below ground, but it will be above ground after the state is
// fully set.
if ( !isSettingPhetioStateProperty.value ) {
- this.tracks.get( i ).bumpAboveGround();
+ this.trackGroup.getArray()[ i ].bumpAboveGround();
}
this.availableModelBoundsProperty.unlink( bumpListener );
}
@@ -177,7 +177,7 @@
* @param tracks - The tracks to add.
*/
public addTrackSet( tracks: Track[] ): void {
- this.tracks.addAll( tracks );
+ // this.tracks.addAll( tracks );
this.updateActiveTrack( this.sceneProperty.get() );
}
@@ -187,7 +187,8 @@
*/
public override reset(): void {
super.reset();
- this.tracks.forEach( track => {
+
+ this.trackGroup.forEach( track => {
if ( track.configurable ) {
track.reset();
}
Index: js/common/view/TrackToolboxPanel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/TrackToolboxPanel.ts b/js/common/view/TrackToolboxPanel.ts
--- a/js/common/view/TrackToolboxPanel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/TrackToolboxPanel.ts (date 1736955879102)
@@ -44,7 +44,7 @@
iconNode.addInputListener( DragListener.createForwardingListener( event => {
const track = model.createDraggableTrack();
- model.tracks.add( track );
+ // model.trackGroup.add( track );
// all in ScreenView coordinates
const viewPoint = view.globalToLocalPoint( event.pointer.point );
@@ -63,8 +63,8 @@
const updateIconVisibility = () => {
iconNode.visible = model.getNumberOfControlPoints() <= EnergySkateParkConstants.MAX_NUMBER_CONTROL_POINTS - 3;
};
- model.tracks.addItemAddedListener( updateIconVisibility );
- model.tracks.addItemRemovedListener( updateIconVisibility );
+ model.trackGroup.elementCreatedEmitter.addListener( updateIconVisibility );
+ model.trackGroup.elementDisposedEmitter.addListener( updateIconVisibility );
super( iconNode, options );
}
Index: js/common/model/EnergySkateParkModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/EnergySkateParkModel.ts b/js/common/model/EnergySkateParkModel.ts
--- a/js/common/model/EnergySkateParkModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/model/EnergySkateParkModel.ts (date 1736955628550)
@@ -24,7 +24,6 @@
*/
import BooleanProperty from '../../../../axon/js/BooleanProperty.js';
-import createObservableArray, { ObservableArray } from '../../../../axon/js/createObservableArray.js';
import DerivedProperty from '../../../../axon/js/DerivedProperty.js';
import Emitter from '../../../../axon/js/Emitter.js';
import EnumerationProperty from '../../../../axon/js/EnumerationProperty.js';
@@ -46,7 +45,6 @@
import PhetioObject, { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js';
import Tandem from '../../../../tandem/js/Tandem.js';
import IOType from '../../../../tandem/js/types/IOType.js';
-import ReferenceIO from '../../../../tandem/js/types/ReferenceIO.js';
import energySkatePark from '../../energySkatePark.js';
import EnergySkateParkConstants from '../EnergySkateParkConstants.js';
import EnergySkateParkQueryParameters from '../EnergySkateParkQueryParameters.js';
@@ -185,7 +183,7 @@
// - signify that the model has successfully been reset to initial state
public resetEmitter: Emitter;
- public readonly tracks: ObservableArray<Track>;
+ // public readonly tracks: ObservableArray<Track>;
// Required for PhET-iO state wrapper
public readonly updateEmitter: Emitter;
@@ -244,6 +242,14 @@
phetioDynamicElementName: 'track'
} );
+ setInterval( () => {
+ // console.log( phet.preloads.phetio.queryParameters.frameTitle, this.controlPointGroup.getArray().map( e => e.tandem.name ) );
+ console.log( phet.preloads.phetio.queryParameters.frameTitle );
+ console.log( 'number of tracks: ' + this.trackGroup.getArray().length )
+ // console.log('number of tracks: '+this.tracks.length)
+ // this.trackGroup.getArray().forEach( e => e.controlPoints.map(c=>c.tandem.name) )
+ }, 1000 );
+
this.pieChartVisibleProperty = new BooleanProperty( false, {
tandem: tandem.createTandem( 'pieChartVisibleProperty' )
} );
@@ -341,10 +347,10 @@
}
} );
- this.tracks = createObservableArray( {
- phetioType: createObservableArray.ObservableArrayIO( ReferenceIO( Track.TrackIO ) ),
- tandem: tandem.createTandem( 'tracks' )
- } );
+ // this.tracks = createObservableArray( {
+ // phetioType: createObservableArray.ObservableArrayIO( ReferenceIO( Track.TrackIO ) ),
+ // tandem: tandem.createTandem( 'tracks' )
+ // } );
// Determine when to show/hide the track edit buttons (cut track or delete control point)
const updateTrackEditingButtonProperties = () => {
@@ -361,8 +367,8 @@
this.editButtonEnabledProperty.value = editEnabled;
this.clearButtonEnabledProperty.value = clearEnabled;
};
- this.tracks.addItemAddedListener( updateTrackEditingButtonProperties );
- this.tracks.addItemRemovedListener( updateTrackEditingButtonProperties );
+ this.trackGroup.elementCreatedEmitter.addListener( updateTrackEditingButtonProperties );
+ this.trackGroup.elementDisposedEmitter.addListener( updateTrackEditingButtonProperties );
this.updateEmitter = new Emitter();
this.trackChangedEmitter.addListener( updateTrackEditingButtonProperties );
@@ -1492,32 +1498,21 @@
* Get all tracks in the model that are marked as physical (they can interact with the Skater in some way).
*/
public getPhysicalTracks(): Track[] {
-
- // Use vanilla instead of lodash for speed since this is in an inner loop
- const physicalTracks = [];
- for ( let i = 0; i < this.tracks.length; i++ ) {
- const track = this.tracks.get( i );
-
- if ( track.physicalProperty.value ) {
- physicalTracks.push( track );
- }
- }
- return physicalTracks;
+ return this.trackGroup.filter( track => track.physicalProperty.value );
}
/**
* Get all tracks that the skater cannot interact with.
*/
public getNonPhysicalTracks(): Track[] {
- return this.tracks.filter( track => !track.physicalProperty.get() );
+ return this.trackGroup.filter( track => !track.physicalProperty.value );
}
/**
* Remove a track from the observable array of tracks and dispose it.
*/
public removeAndDisposeTrack( trackToRemove: Track ): void {
- assert && assert( this.tracks.includes( trackToRemove ), 'trying to remove track that is not in the list' );
- this.tracks.remove( trackToRemove );
+ assert && assert( this.trackGroup.includes( trackToRemove ), 'trying to remove track that is not in the list' );
this.trackGroup.disposeElement( trackToRemove );
}
@@ -1559,8 +1554,6 @@
// Make sure the new track doesn't go underground after a control point is deleted, see #174
newTrack.bumpAboveGround();
-
- this.tracks.add( newTrack );
}
else {
@@ -1612,9 +1605,6 @@
track.removeEmitter.emit();
this.removeAndDisposeTrack( track );
- this.tracks.add( newTrack1 );
- this.tracks.add( newTrack2 );
-
// Smooth the new tracks, see #177
newTrack1.smooth( controlPointIndex - 1 );
newTrack2.smooth( 0 );
@@ -1701,20 +1691,19 @@
a.disposeControlPoints();
a.removeEmitter.emit();
- if ( this.tracks.includes( a ) ) {
+ if ( this.trackGroup.includes( a ) ) {
this.removeAndDisposeTrack( a );
}
b.disposeControlPoints();
b.removeEmitter.emit();
- if ( this.tracks.includes( b ) ) {
+ if ( this.trackGroup.includes( b ) ) {
this.removeAndDisposeTrack( b );
}
// When tracks are joined, bump the new track above ground so the y value (and potential energy) cannot go negative,
// and so it won't make the "return skater" button get bigger, see #158
newTrack.bumpAboveGround();
- this.tracks.add( newTrack );
// Move skater to new track if he was on the old track, by searching for the best fit point on the new track
// Note: Energy is not conserved when tracks joined since the user has added or removed energy from the system
@@ -1786,7 +1775,7 @@
* ones in the toolbox)
*/
public getNumberOfControlPoints(): number {
- return this.tracks.reduce( ( total, track ) => total + track.controlPoints.length, 0 );
+ return this.trackGroup.getArray().reduce( ( total, track ) => total + track.controlPoints.length, 0 );
}
/**
@@ -1802,18 +1791,23 @@
* See #230
*/
public containsTrack( track: Track ): boolean {
- return this.tracks.includes( track );
+ return this.trackGroup.includes( track );
}
/**
* Called by phet-io to clear out the model state before restoring child tracks.
*/
public removeAllTracks(): void {
- while ( this.tracks.length > 0 ) {
- const track = this.tracks.get( 0 );
+
+ // while ( this.tracks.length > 0 ) {
+ // const track = this.tracks.get( 0 );
+ // track.disposeControlPoints();
+ // this.removeAndDisposeTrack( track );
+ // }
+ this.trackGroup.getArrayCopy().forEach( track => {
track.disposeControlPoints();
this.removeAndDisposeTrack( track );
- }
+ } );
}
public static readonly EnergySkateParkModelIO = new IOType( 'EnergySkateParkModelIO', {
Index: js/common/view/SceneSelectionRadioButtonGroup.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/SceneSelectionRadioButtonGroup.ts b/js/common/view/SceneSelectionRadioButtonGroup.ts
--- a/js/common/view/SceneSelectionRadioButtonGroup.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/SceneSelectionRadioButtonGroup.ts (date 1736955879098)
@@ -61,7 +61,7 @@
// produces spacing of ~5 when there are 4 premade tracks which is the usual case and looks nice, and provides
// more spacing if there are fewer tracks
assert && assert( options.spacing === undefined, 'SceneSelectionRadioButtonGroup sets spacing from number of premade tracks' );
- options.spacing = 20 / model.tracks.length;
+ options.spacing = 20 / model.trackGroup.getArray().length;
// Create a track to be used specifically for an icon - must be one of the premade tracks defined in
// PremadeTracks.TrackType. These Tracks are a bit different from the actual tracks used in the model
@@ -136,7 +136,7 @@
// create the contents for the radio buttons
const contents: Node[] = [];
- _.forEach( model.tracks, ( track, i ) => {
+ _.forEach( model.trackGroup.getArray(), ( track, i ) => {
const contentNode = createNode( i );
contents.push( contentNode );
} );
Index: js/common/view/EnergySkateParkScreenView.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/EnergySkateParkScreenView.ts b/js/common/view/EnergySkateParkScreenView.ts
--- a/js/common/view/EnergySkateParkScreenView.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/EnergySkateParkScreenView.ts (date 1736957633000)
@@ -103,7 +103,7 @@
export default class EnergySkateParkScreenView extends ScreenView {
public readonly modelViewTransform: ModelViewTransform2;
public readonly availableModelBoundsProperty: Property<Bounds2>;
- public readonly trackNodeGroup: { createNextElement( track: Track, modelViewTransform: ModelViewTransform2, availableBoundsProperty: IntentionalAny, options?: IntentionalAny ): TrackNode };
+ // public readonly trackNodeGroup: { createNextElement( track: Track, modelViewTransform: ModelViewTransform2, availableBoundsProperty: IntentionalAny, options?: IntentionalAny ): TrackNode };
protected readonly model: EnergySkateParkModel;
// whether or not this screen view should include a measuring tape
@@ -201,12 +201,12 @@
} );
// Mimic the PhetioGroup API until we implement the full instrumentation
- this.trackNodeGroup = {
- createNextElement( track, modelViewTransform, availableBoundsProperty, options ) {
- assert && options && assert( !options.hasOwnProperty( 'tandem' ), 'tandem is managed by the PhetioGroup' );
- return new TrackNode( track, modelViewTransform, availableBoundsProperty, Tandem.OPT_OUT, options );
- }
- };
+ // this.trackNodeGroup = {
+ // createNextElement( track, modelViewTransform, availableBoundsProperty, options ) {
+ // assert && options && assert( !options.hasOwnProperty( 'tandem' ), 'tandem is managed by the PhetioGroup' );
+ // return new TrackNode( track, modelViewTransform, availableBoundsProperty, Tandem.OPT_OUT, options );
+ // }
+ // };
this.model = model;
this.showToolbox = options.showToolbox;
Index: js/measure/model/MeasureModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/measure/model/MeasureModel.ts b/js/measure/model/MeasureModel.ts
--- a/js/measure/model/MeasureModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/measure/model/MeasureModel.ts (date 1736955879108)
@@ -50,7 +50,7 @@
// Don't save any EnergySkateParkDataSamples while control points are being dragged. This can be done during construction
// because MeasureModel tracks are static and no new tracks are introduced. For the same reason disposal
// of these listeners is not necessary.
- this.tracks.forEach( track => {
+ this.trackGroup.forEach( track => {
track.controlPointDraggingProperty.link( anyPointDragging => {
this.preventSampleSave = anyPointDragging;
} ); |
Better one: Subject: [PATCH] Address ui interaction corner cases for tracks and control points, see https://github.com/phetsims/energy-skate-park/issues/385
---
Index: js/playground/view/EnergySkateParkPlaygroundScreenView.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/playground/view/EnergySkateParkPlaygroundScreenView.ts b/js/playground/view/EnergySkateParkPlaygroundScreenView.ts
--- a/js/playground/view/EnergySkateParkPlaygroundScreenView.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/playground/view/EnergySkateParkPlaygroundScreenView.ts (date 1736976593473)
@@ -58,7 +58,7 @@
} );
this.bottomLayer.addChild( this.trackToolbox );
- model.tracks.addItemAddedListener( this.addTrackNode.bind( this ) );
+ model.trackGroup.elementCreatedEmitter.addListener( track => this.addTrackNode( track ) );
this.clearButton = new EraserButton( {
iconWidth: 30,
@@ -71,7 +71,7 @@
this.addChild( this.clearButton );
// add any other TrackNodes eagerly in case model has some initial Tracks, like when we are debugging
- model.tracks.map( this.addTrackNode.bind( this ) );
+ model.trackGroup.forEach( this.addTrackNode.bind( this ) );
this.timeControlNode.left = this.modelViewTransform.modelToViewX( 0.5 );
this.trackToolbox.right = this.modelViewTransform.modelToViewX( -0.5 );
@@ -83,7 +83,7 @@
* handle disposal.
*/
public addTrackNode( track: Track ): TrackNode {
- const trackNode = this.trackNodeGroup.createNextElement( track, this.modelViewTransform, this.availableModelBoundsProperty );
+ const trackNode = new TrackNode( track, this.modelViewTransform, this.availableModelBoundsProperty, Tandem.OPT_OUT );
this.trackNodes.push( trackNode );
this.trackLayer.addChild( trackNode );
@@ -96,11 +96,11 @@
this.trackNodes.splice( index, 1 );
// Clean up memory leak
- this.model.tracks.removeItemRemovedListener( itemRemovedListener );
+ this.model.trackGroup.elementDisposedEmitter.removeListener( itemRemovedListener );
trackNode.dispose();
}
};
- this.model.tracks.addItemRemovedListener( itemRemovedListener );
+ this.model.trackGroup.elementDisposedEmitter.addListener( itemRemovedListener );
return trackNode;
}
Index: js/playground/model/EnergySkateParkPlaygroundModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/playground/model/EnergySkateParkPlaygroundModel.ts b/js/playground/model/EnergySkateParkPlaygroundModel.ts
--- a/js/playground/model/EnergySkateParkPlaygroundModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/playground/model/EnergySkateParkPlaygroundModel.ts (date 1736976354224)
@@ -69,7 +69,6 @@
*/
public clearTracks(): void {
- this.tracks.clear();
this.trackGroup.clear();
this.controlPointGroup.clear();
Index: js/graphs/model/GraphsModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/graphs/model/GraphsModel.ts b/js/graphs/model/GraphsModel.ts
--- a/js/graphs/model/GraphsModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/graphs/model/GraphsModel.ts (date 1736978391961)
@@ -83,8 +83,8 @@
},
doubleWellTrackOptions: {
configurable: tracksConfigurable,
- tandem: tandem.createTandem( 'doubleWellTrack' ),
- phetioState: false
+ // tandem: tandem.createTandem( 'doubleWellTrack' ),
+ // phetioState: false
},
parabolaControlPointOptions: {
@@ -95,8 +95,8 @@
},
parabolaTrackOptions: {
configurable: tracksConfigurable,
- tandem: tandem.createTandem( 'parabolaTrack' ),
- phetioState: false
+ // tandem: tandem.createTandem( 'parabolaTrack' ),
+ // phetioState: false
}
},
@@ -328,8 +328,8 @@
const parabolaTrack = PremadeTracks.createTrack( this, parabolaControlPoints, {
configurable: this.tracksConfigurable,
- tandem: tandem.createTandem( 'parabolaTrack' ),
- phetioState: false
+ // // tandem: tandem.createTandem( 'parabolaTrack' ),
+ // phetioState: false
} );
const doubleWellControlPoints = PremadeTracks.createDoubleWellControlPoints( this, {
@@ -353,8 +353,8 @@
} );
const doubleWellTrack = PremadeTracks.createTrack( this, doubleWellControlPoints, {
configurable: this.tracksConfigurable,
- tandem: tandem.createTandem( 'doubleWellTrack' ),
- phetioState: false
+ // // tandem: tandem.createTandem( 'doubleWellTrack' ),
+ // phetioState: false
} );
return [ parabolaTrack, doubleWellTrack ];
Index: js/common/view/EnergySkateParkTrackSetScreenView.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/EnergySkateParkTrackSetScreenView.ts b/js/common/view/EnergySkateParkTrackSetScreenView.ts
--- a/js/common/view/EnergySkateParkTrackSetScreenView.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/EnergySkateParkTrackSetScreenView.ts (date 1736976354161)
@@ -13,14 +13,15 @@
import energySkatePark from '../../energySkatePark.js';
import EnergySkateParkTrackSetModel from '../model/EnergySkateParkTrackSetModel.js';
import EnergySkateParkSaveSampleScreenView from './EnergySkateParkSaveSampleScreenView.js';
+import TrackNode from './TrackNode.js';
export default class EnergySkateParkTrackSetScreenView extends EnergySkateParkSaveSampleScreenView {
public constructor( model: EnergySkateParkTrackSetModel, tandem: Tandem, options?: IntentionalAny ) {
super( model, tandem, options );
- const trackNodes = model.tracks.map( track => {
- return this.trackNodeGroup.createNextElement( track, this.modelViewTransform, this.availableModelBoundsProperty );
+ const trackNodes = model.trackGroup.map( track => {
+ return new TrackNode( track, this.modelViewTransform, this.availableModelBoundsProperty, Tandem.OPT_OUT );
} );
trackNodes.forEach( trackNode => {
@@ -28,7 +29,7 @@
} );
model.sceneProperty.link( scene => {
- _.forEach( model.tracks, ( track, i ) => {
+ _.forEach( model.trackGroup.getArray(), ( track, i ) => {
trackNodes[ i ].visible = scene === i;
} );
Index: js/common/view/ControlPointNode.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/ControlPointNode.ts b/js/common/view/ControlPointNode.ts
--- a/js/common/view/ControlPointNode.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/ControlPointNode.ts (date 1736976354117)
@@ -79,6 +79,8 @@
}
controlPoint.positionProperty.link( position => {
+
+ console.log( phet.preloads.phetio.queryParameters.frameTitle, 'control point position changed' );
this.translation = modelViewTransform.modelToViewPosition( position );
} );
Index: js/common/model/PremadeTracks.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/PremadeTracks.ts b/js/common/model/PremadeTracks.ts
--- a/js/common/model/PremadeTracks.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/model/PremadeTracks.ts (date 1736978189988)
@@ -16,10 +16,11 @@
import EnumerationDeprecated from '../../../../phet-core/js/EnumerationDeprecated.js';
import merge from '../../../../phet-core/js/merge.js';
import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
+import StrictOmit from '../../../../phet-core/js/types/StrictOmit.js';
import energySkatePark from '../../energySkatePark.js';
import ControlPoint from './ControlPoint.js';
import EnergySkateParkModel from './EnergySkateParkModel.js';
-import Track from './Track.js';
+import Track, { TrackOptions } from './Track.js';
// limiting bounds for dragging control points
const END_BOUNDS_WIDTH = 2.5;
@@ -95,17 +96,17 @@
model.controlPointGroup.createNextElement( p1.x, p1.y, {
visible: options.p1Visible,
limitBounds: p1Bounds,
- phetioState: false
+ // // phetioState: false
} ),
model.controlPointGroup.createNextElement( p2.x, p2.y, {
visible: options.p2Visible,
limitBounds: p2Bounds,
- phetioState: false
+ // // phetioState: false
} ),
model.controlPointGroup.createNextElement( p3.x, p3.y, {
visible: options.p3Visible,
limitBounds: p3Bounds,
- phetioState: false
+ // // phetioState: false // TEST 1
} )
];
},
@@ -134,15 +135,15 @@
return [
model.controlPointGroup.createNextElement( p1.x, p1.y, {
limitBounds: p1Bounds,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p2.x, p2.y, {
limitBounds: p2Bounds,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p3.x, p3.y, {
limitBounds: p3Bounds,
- phetioState: false
+ // phetioState: false
} )
];
},
@@ -196,27 +197,27 @@
model.controlPointGroup.createNextElement( p1.x, p1.y, {
limitBounds: p1Bounds,
visible: options.p1Visible,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p2.x, p2.y, {
limitBounds: p2Bounds,
visible: options.p2Visible,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p3.x, p3.y, {
limitBounds: p3Bounds,
visible: options.p3Visible,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p4.x, p4.y, {
limitBounds: p4Bounds,
visible: options.p4Visible,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p5.x, p5.y, {
limitBounds: p5Bounds,
visible: options.p5Visible,
- phetioState: false
+ // phetioState: false
} )
];
},
@@ -262,31 +263,31 @@
return [
model.controlPointGroup.createNextElement( p1.x, p1.y, {
limitBounds: p1Bounds,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p2.x, p2.y, {
limitBounds: p2Bounds,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p3.x, p3.y, {
limitBounds: p3Bounds,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p4.x, p4.y, {
limitBounds: p4Bounds,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p5.x, p5.y, {
limitBounds: p5Bounds,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p6.x, p6.y, {
limitBounds: p6Bounds,
- phetioState: false
+ // phetioState: false
} ),
model.controlPointGroup.createNextElement( p7.x, p7.y, {
limitBounds: p7Bounds,
- phetioState: false
+ // phetioState: false
} )
];
},
@@ -294,8 +295,8 @@
/**
* Create a track from the provided control points.
*/
- createTrack( model: EnergySkateParkModel, controlPoints: ControlPoint[], options: IntentionalAny ): Track {
- return new Track( model, controlPoints, options );
+ createTrack( model: EnergySkateParkModel, controlPoints: ControlPoint[], options: StrictOmit<TrackOptions, 'tandem'> ): Track {
+ return model.trackGroup.createNextElement( controlPoints, options );
},
TrackType: TrackType as IntentionalAny
Index: js/common/model/EnergySkateParkTrackSetModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/EnergySkateParkTrackSetModel.ts b/js/common/model/EnergySkateParkTrackSetModel.ts
--- a/js/common/model/EnergySkateParkTrackSetModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/model/EnergySkateParkTrackSetModel.ts (date 1736979895092)
@@ -74,8 +74,8 @@
* @param sceneIndex - index identifying the scene
*/
private updateActiveTrack( sceneIndex: number ): void {
- for ( let i = 0; i < this.tracks.length; i++ ) {
- const track = this.tracks.get( i );
+ for ( let i = 0; i < this.trackGroup.getArray().length; i++ ) {
+ const track = this.trackGroup.getArray()[ i ];
track.physicalProperty.value = ( i === sceneIndex );
// Reset the skater position when the track is changed, see #179
@@ -93,7 +93,7 @@
// During state set, nodes can temporarily go below ground, but it will be above ground after the state is
// fully set.
if ( !isSettingPhetioStateProperty.value ) {
- this.tracks.get( i ).bumpAboveGround();
+ this.trackGroup.getArray()[ i ].bumpAboveGround();
}
this.availableModelBoundsProperty.unlink( bumpListener );
}
@@ -133,9 +133,7 @@
this.trackTypes.forEach( trackType => {
if ( trackType === PremadeTracks.TrackType.PARABOLA ) {
const parabolaControlPoints = PremadeTracks.createParabolaControlPoints( this, options.parabolaControlPointOptions );
- const parabolaTrack = EnergySkateParkTrackSetModel.createPremadeTrack( this, parabolaControlPoints, merge( {
- tandem: tandem.createTandem( 'parabolaTrack' )
- }, options.parabolaTrackOptions ) );
+ const parabolaTrack = EnergySkateParkTrackSetModel.createPremadeTrack( this, parabolaControlPoints, options.parabolaTrackOptions );
tracks.push( parabolaTrack );
}
@@ -145,24 +143,18 @@
// Flag to indicate whether the skater transitions from the right edge of this track directly to the ground
// see #164
- slopeToGround: true,
- tandem: tandem.createTandem( 'slopeTrack' )
+ slopeToGround: true
}, options.slopeTrackOptions ) );
tracks.push( slopeTrack );
}
else if ( trackType === PremadeTracks.TrackType.DOUBLE_WELL ) {
const doubleWellControlPoints = PremadeTracks.createDoubleWellControlPoints( this, options.doubleWellControlPointOptions );
- const doubleWellTrack = EnergySkateParkTrackSetModel.createPremadeTrack( this, doubleWellControlPoints, merge( {
- tandem: tandem.createTandem( 'doubleWellTrack' )
- }, options.doubleWellTrackOptions ) );
+ const doubleWellTrack = EnergySkateParkTrackSetModel.createPremadeTrack( this, doubleWellControlPoints, options.doubleWellTrackOptions );
tracks.push( doubleWellTrack );
}
else if ( trackType === PremadeTracks.TrackType.LOOP ) {
const loopControlPoints = PremadeTracks.createLoopControlPoints( this, options.loopControlPointOptions );
- const loopTrack = EnergySkateParkTrackSetModel.createPremadeTrack( this, loopControlPoints, merge( {
- draggable: this.tracksDraggable,
- tandem: tandem.createTandem( 'loopTrack' )
- }, options.loopTrackOptions ) );
+ const loopTrack = EnergySkateParkTrackSetModel.createPremadeTrack( this, loopControlPoints, options.loopTrackOptions );
tracks.push( loopTrack );
}
} );
@@ -176,8 +168,7 @@
*
* @param tracks - The tracks to add.
*/
- public addTrackSet( tracks: Track[] ): void {
- this.tracks.addAll( tracks );
+ public addTrackSet( tracks: Track[] ): void { // TODO: remove tracks arg? what is this method for? https://github.com/phetsims/energy-skate-park/issues/385
this.updateActiveTrack( this.sceneProperty.get() );
}
@@ -187,7 +178,8 @@
*/
public override reset(): void {
super.reset();
- this.tracks.forEach( track => {
+
+ this.trackGroup.forEach( track => {
if ( track.configurable ) {
track.reset();
}
@@ -201,7 +193,7 @@
public static createPremadeTrack( model: IntentionalAny, controlPoints: ControlPoint[], options?: TrackOptions ): Track {
options = combineOptions<TrackOptions>( {
configurable: model.tracksConfigurable,
- phetioState: false
+ // phetioState: false // TEST 1
}, options );
return PremadeTracks.createTrack( model, controlPoints, options );
Index: js/common/view/TrackToolboxPanel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/TrackToolboxPanel.ts b/js/common/view/TrackToolboxPanel.ts
--- a/js/common/view/TrackToolboxPanel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/TrackToolboxPanel.ts (date 1736977298403)
@@ -9,7 +9,7 @@
import merge from '../../../../phet-core/js/merge.js';
import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
-import { DragListener } from '../../../../scenery/js/imports.js';
+import { DragListener, Node } from '../../../../scenery/js/imports.js';
import Panel from '../../../../sun/js/Panel.js';
import Tandem from '../../../../tandem/js/Tandem.js';
import energySkatePark from '../../energySkatePark.js';
@@ -34,6 +34,8 @@
interactive: false
}
} );
+
+
const iconNode = new TrackNode( iconTrack, view.modelViewTransform, model.availableModelBoundsProperty, tandem.createTandem( 'iconNode' ), {
// want the icon to look pickable, even though it isn't really draggable (forwarding listener makes the new
@@ -41,14 +43,21 @@
roadCursorOverride: 'cursor'
} );
- iconNode.addInputListener( DragListener.createForwardingListener( event => {
+ const rasterizedTrackNode = new Node( {
+ children: [ iconNode.rasterized() ],
+ pickable: true,
+ cursor: 'pointer'
+ } );
+
+ model.removeAndDisposeTrack( iconTrack );
+
+ rasterizedTrackNode.addInputListener( DragListener.createForwardingListener( event => {
const track = model.createDraggableTrack();
- model.tracks.add( track );
// all in ScreenView coordinates
const viewPoint = view.globalToLocalPoint( event.pointer.point );
- const iconViewCenter = view.globalToLocalPoint( iconNode.parentToGlobalPoint( iconNode.center ) );
+ const iconViewCenter = view.globalToLocalPoint( rasterizedTrackNode.parentToGlobalPoint( rasterizedTrackNode.center ) );
const offset = viewPoint.minus( iconViewCenter );
const viewPointWithOffset = viewPoint.minus( offset );
@@ -61,12 +70,12 @@
} ) );
const updateIconVisibility = () => {
- iconNode.visible = model.getNumberOfControlPoints() <= EnergySkateParkConstants.MAX_NUMBER_CONTROL_POINTS - 3;
+ rasterizedTrackNode.visible = model.getNumberOfControlPoints() <= EnergySkateParkConstants.MAX_NUMBER_CONTROL_POINTS - 3;
};
- model.tracks.addItemAddedListener( updateIconVisibility );
- model.tracks.addItemRemovedListener( updateIconVisibility );
+ model.trackGroup.elementCreatedEmitter.addListener( updateIconVisibility );
+ model.trackGroup.elementDisposedEmitter.addListener( updateIconVisibility );
- super( iconNode, options );
+ super( rasterizedTrackNode, options );
}
}
Index: js/common/model/EnergySkateParkModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/EnergySkateParkModel.ts b/js/common/model/EnergySkateParkModel.ts
--- a/js/common/model/EnergySkateParkModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/model/EnergySkateParkModel.ts (date 1736979895083)
@@ -24,7 +24,6 @@
*/
import BooleanProperty from '../../../../axon/js/BooleanProperty.js';
-import createObservableArray, { ObservableArray } from '../../../../axon/js/createObservableArray.js';
import DerivedProperty from '../../../../axon/js/DerivedProperty.js';
import Emitter from '../../../../axon/js/Emitter.js';
import EnumerationProperty from '../../../../axon/js/EnumerationProperty.js';
@@ -46,7 +45,6 @@
import PhetioObject, { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js';
import Tandem from '../../../../tandem/js/Tandem.js';
import IOType from '../../../../tandem/js/types/IOType.js';
-import ReferenceIO from '../../../../tandem/js/types/ReferenceIO.js';
import energySkatePark from '../../energySkatePark.js';
import EnergySkateParkConstants from '../EnergySkateParkConstants.js';
import EnergySkateParkQueryParameters from '../EnergySkateParkQueryParameters.js';
@@ -185,8 +183,6 @@
// - signify that the model has successfully been reset to initial state
public resetEmitter: Emitter;
- public readonly tracks: ObservableArray<Track>;
-
// Required for PhET-iO state wrapper
public readonly updateEmitter: Emitter;
@@ -226,23 +222,46 @@
}, [ 0, 0, {} ], {
tandem: tandem.createTandem( 'controlPointGroup' ),
phetioType: PhetioGroup.PhetioGroupIO( ControlPoint.ControlPointIO ),
- phetioDynamicElementName: 'controlPoint'
+ phetioDynamicElementName: 'controlPoint',
+ phetioState: true // TODO: Probably does nothing, remove, see https://github.com/phetsims/energy-skate-park/issues/385
} );
this.trackGroup = new PhetioGroup<Track, [ ControlPoint[], TrackOptions ]>( ( tandem, controlPoints, options ) => {
assert && options && assert( !options.hasOwnProperty( 'tandem' ), 'tandem is managed by the PhetioGroup' );
return new Track( this, controlPoints, merge( {}, options, {
tandem: tandem,
- phetioDynamicElement: true
+ phetioDynamicElement: true,
+ phetioState: true
} ) );
- }, [ _.range( 20 ).map( n => this.controlPointGroup.createNextElement( n * 100, 0, {} ) ), {
+ }, [ [ 0, 1 ].map( n => this.controlPointGroup.createNextElement( n * 100, 0, {} ) ), { // TODO: use create archetype? see https://github.com/phetsims/energy-skate-park/issues/385
draggable: true,
configurable: true
} ], {
tandem: tandem.createTandem( 'trackGroup' ),
phetioType: PhetioGroup.PhetioGroupIO( Track.TrackIO ),
- phetioDynamicElementName: 'track'
+ phetioDynamicElementName: 'track',
+ phetioState: true // TODO: Probably does nothing, see https://github.com/phetsims/energy-skate-park/issues/385
+ } );
+
+ this.trackGroup.elementCreatedEmitter.addListener( track => {
+ console.log( phet.preloads.phetio.queryParameters.frameTitle, 'track created' );
+ console.log( 'number of tracks: ' + this.trackGroup.getArray().length );
+ console.log( new Error().stack );
} );
+
+ this.trackGroup.elementDisposedEmitter.addListener( track => {
+ console.log( phet.preloads.phetio.queryParameters.frameTitle, 'track disposed' );
+ console.log( 'number of tracks: ' + this.trackGroup.getArray().length )
+ console.log( new Error().stack );
+ } );
+
+ setInterval( () => {
+ // console.log( phet.preloads.phetio.queryParameters.frameTitle, this.controlPointGroup.getArray().map( e => e.tandem.name ) );
+ console.log( phet.preloads.phetio.queryParameters.frameTitle );
+ console.log( 'number of tracks: ' + this.trackGroup.getArray().length )
+ // console.log('number of tracks: '+this.tracks.length)
+ // this.trackGroup.getArray().forEach( e => e.controlPoints.map(c=>c.tandem.name) )
+ }, 1000 );
this.pieChartVisibleProperty = new BooleanProperty( false, {
tandem: tandem.createTandem( 'pieChartVisibleProperty' )
@@ -341,11 +360,6 @@
}
} );
- this.tracks = createObservableArray( {
- phetioType: createObservableArray.ObservableArrayIO( ReferenceIO( Track.TrackIO ) ),
- tandem: tandem.createTandem( 'tracks' )
- } );
-
// Determine when to show/hide the track edit buttons (cut track or delete control point)
const updateTrackEditingButtonProperties = () => {
let editEnabled = false;
@@ -361,8 +375,8 @@
this.editButtonEnabledProperty.value = editEnabled;
this.clearButtonEnabledProperty.value = clearEnabled;
};
- this.tracks.addItemAddedListener( updateTrackEditingButtonProperties );
- this.tracks.addItemRemovedListener( updateTrackEditingButtonProperties );
+ this.trackGroup.elementCreatedEmitter.addListener( updateTrackEditingButtonProperties );
+ this.trackGroup.elementDisposedEmitter.addListener( updateTrackEditingButtonProperties );
this.updateEmitter = new Emitter();
this.trackChangedEmitter.addListener( updateTrackEditingButtonProperties );
@@ -1492,32 +1506,21 @@
* Get all tracks in the model that are marked as physical (they can interact with the Skater in some way).
*/
public getPhysicalTracks(): Track[] {
-
- // Use vanilla instead of lodash for speed since this is in an inner loop
- const physicalTracks = [];
- for ( let i = 0; i < this.tracks.length; i++ ) {
- const track = this.tracks.get( i );
-
- if ( track.physicalProperty.value ) {
- physicalTracks.push( track );
- }
- }
- return physicalTracks;
+ return this.trackGroup.filter( track => track.physicalProperty.value );
}
/**
* Get all tracks that the skater cannot interact with.
*/
public getNonPhysicalTracks(): Track[] {
- return this.tracks.filter( track => !track.physicalProperty.get() );
+ return this.trackGroup.filter( track => !track.physicalProperty.value );
}
/**
* Remove a track from the observable array of tracks and dispose it.
*/
public removeAndDisposeTrack( trackToRemove: Track ): void {
- assert && assert( this.tracks.includes( trackToRemove ), 'trying to remove track that is not in the list' );
- this.tracks.remove( trackToRemove );
+ assert && assert( this.trackGroup.includes( trackToRemove ), 'trying to remove track that is not in the list' );
this.trackGroup.disposeElement( trackToRemove );
}
@@ -1559,8 +1562,6 @@
// Make sure the new track doesn't go underground after a control point is deleted, see #174
newTrack.bumpAboveGround();
-
- this.tracks.add( newTrack );
}
else {
@@ -1612,9 +1613,6 @@
track.removeEmitter.emit();
this.removeAndDisposeTrack( track );
- this.tracks.add( newTrack1 );
- this.tracks.add( newTrack2 );
-
// Smooth the new tracks, see #177
newTrack1.smooth( controlPointIndex - 1 );
newTrack2.smooth( 0 );
@@ -1701,20 +1699,19 @@
a.disposeControlPoints();
a.removeEmitter.emit();
- if ( this.tracks.includes( a ) ) {
+ if ( this.trackGroup.includes( a ) ) {
this.removeAndDisposeTrack( a );
}
b.disposeControlPoints();
b.removeEmitter.emit();
- if ( this.tracks.includes( b ) ) {
+ if ( this.trackGroup.includes( b ) ) {
this.removeAndDisposeTrack( b );
}
// When tracks are joined, bump the new track above ground so the y value (and potential energy) cannot go negative,
// and so it won't make the "return skater" button get bigger, see #158
newTrack.bumpAboveGround();
- this.tracks.add( newTrack );
// Move skater to new track if he was on the old track, by searching for the best fit point on the new track
// Note: Energy is not conserved when tracks joined since the user has added or removed energy from the system
@@ -1786,7 +1783,7 @@
* ones in the toolbox)
*/
public getNumberOfControlPoints(): number {
- return this.tracks.reduce( ( total, track ) => total + track.controlPoints.length, 0 );
+ return this.trackGroup.getArray().reduce( ( total, track ) => total + track.controlPoints.length, 0 );
}
/**
@@ -1802,18 +1799,18 @@
* See #230
*/
public containsTrack( track: Track ): boolean {
- return this.tracks.includes( track );
+ return this.trackGroup.includes( track );
}
/**
* Called by phet-io to clear out the model state before restoring child tracks.
*/
public removeAllTracks(): void {
- while ( this.tracks.length > 0 ) {
- const track = this.tracks.get( 0 );
+
+ this.trackGroup.getArrayCopy().forEach( track => {
track.disposeControlPoints();
this.removeAndDisposeTrack( track );
- }
+ } );
}
public static readonly EnergySkateParkModelIO = new IOType( 'EnergySkateParkModelIO', {
Index: js/common/view/SceneSelectionRadioButtonGroup.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/SceneSelectionRadioButtonGroup.ts b/js/common/view/SceneSelectionRadioButtonGroup.ts
--- a/js/common/view/SceneSelectionRadioButtonGroup.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/SceneSelectionRadioButtonGroup.ts (date 1736977405101)
@@ -61,7 +61,7 @@
// produces spacing of ~5 when there are 4 premade tracks which is the usual case and looks nice, and provides
// more spacing if there are fewer tracks
assert && assert( options.spacing === undefined, 'SceneSelectionRadioButtonGroup sets spacing from number of premade tracks' );
- options.spacing = 20 / model.tracks.length;
+ options.spacing = 20 / model.trackGroup.getArray().length;
// Create a track to be used specifically for an icon - must be one of the premade tracks defined in
// PremadeTracks.TrackType. These Tracks are a bit different from the actual tracks used in the model
@@ -125,6 +125,8 @@
const iconNode = trackNode.rasterized();
children.push( iconNode );
+ model.removeAndDisposeTrack( track );
+
// Fixes: Cursor turns into a hand over the track in the track selection panel, see #204
iconNode.pickable = false;
@@ -136,7 +138,7 @@
// create the contents for the radio buttons
const contents: Node[] = [];
- _.forEach( model.tracks, ( track, i ) => {
+ _.forEach( model.trackGroup.getArray(), ( track, i ) => {
const contentNode = createNode( i );
contents.push( contentNode );
} );
Index: js/common/view/EnergySkateParkScreenView.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/view/EnergySkateParkScreenView.ts b/js/common/view/EnergySkateParkScreenView.ts
--- a/js/common/view/EnergySkateParkScreenView.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/view/EnergySkateParkScreenView.ts (date 1736978278919)
@@ -32,7 +32,6 @@
import EnergySkateParkStrings from '../../EnergySkateParkStrings.js';
import EnergySkateParkConstants from '../EnergySkateParkConstants.js';
import EnergySkateParkModel from '../model/EnergySkateParkModel.js';
-import Track from '../model/Track.js';
import AttachDetachToggleButtons from './AttachDetachToggleButtons.js';
import BackgroundNode from './BackgroundNode.js';
import EnergyBarGraphAccordionBox from './EnergyBarGraphAccordionBox.js';
@@ -44,7 +43,6 @@
import ReferenceHeightLine from './ReferenceHeightLine.js';
import SkaterNode from './SkaterNode.js';
import ToolboxPanel from './ToolboxPanel.js';
-import TrackNode from './TrackNode.js';
import VisibilityControlsPanel from './VisibilityControlsPanel.js';
const controlsRestartSkaterStringProperty = EnergySkateParkStrings.skaterControls.restartSkaterStringProperty;
@@ -103,7 +101,6 @@
export default class EnergySkateParkScreenView extends ScreenView {
public readonly modelViewTransform: ModelViewTransform2;
public readonly availableModelBoundsProperty: Property<Bounds2>;
- public readonly trackNodeGroup: { createNextElement( track: Track, modelViewTransform: ModelViewTransform2, availableBoundsProperty: IntentionalAny, options?: IntentionalAny ): TrackNode };
protected readonly model: EnergySkateParkModel;
// whether or not this screen view should include a measuring tape
@@ -200,14 +197,6 @@
model.availableModelBoundsProperty.set( bounds );
} );
- // Mimic the PhetioGroup API until we implement the full instrumentation
- this.trackNodeGroup = {
- createNextElement( track, modelViewTransform, availableBoundsProperty, options ) {
- assert && options && assert( !options.hasOwnProperty( 'tandem' ), 'tandem is managed by the PhetioGroup' );
- return new TrackNode( track, modelViewTransform, availableBoundsProperty, Tandem.OPT_OUT, options );
- }
- };
-
this.model = model;
this.showToolbox = options.showToolbox;
this.showBarGraph = options.showBarGraph;
Index: js/common/model/DebugTracks.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/DebugTracks.ts b/js/common/model/DebugTracks.ts
--- a/js/common/model/DebugTracks.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/model/DebugTracks.ts (date 1736979895070)
@@ -38,7 +38,6 @@
controlPoints = [ createPoint( 3.9238282647584946, 3.1917866726296955 ), createPoint( 2.043971377459748, 4.847851073345259 ), createPoint( -1.116994633273702, 3.686296958855098 ), createPoint( -3.5806797853309487, 1.8639512522361352 ), createPoint( -5.982719141323793, 6.235364490161 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
// Skater stutters and slows going over the hump
@@ -52,7 +51,6 @@
controlPoints = [ createPoint( 3.9238282647584946, 3.1917866726296955 ), createPoint( 2.043971377459748, 4.847851073345259 ), createPoint( -1.116994633273702, 3.686296958855098 ), createPoint( -3.5806797853309487, 1.8639512522361352 ), createPoint( -5.982719141323793, 6.235364490161 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
// Tricky one--handled OK
@@ -66,7 +64,6 @@
controlPoints = [ createPoint( -1.8031842576028616, 3.53633273703041 ), createPoint( 1.7306618962432907, 2.8187991949910547 ), createPoint( 1.9246153846153842, 4.3405881037567084 ), createPoint( 3.834311270125223, 4.907529069767442 ), createPoint( 3.491162790697672, 1.0732177996422188 ), createPoint( -2.760107334525939, 1.461124776386404 ), createPoint( -5.162146690518783, 5.832538014311269 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
// Wide loop, OK
@@ -80,7 +77,6 @@
controlPoints = [ createPoint( 4.639964221824686, 6.68294946332737 ), createPoint( 1.4173524150268335, 0.938942307692308 ), createPoint( -3.207692307692308, 3.997439624329159 ), createPoint( 3.2524508050089445, 3.9079226296958858 ), createPoint( 3.491162790697672, 1.0732177996422188 ), createPoint( -2.760107334525939, 1.461124776386404 ), createPoint( -5.162146690518783, 5.832538014311269 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
// Flickering return skater button, OK (see https://github.com/phetsims/energy-skate-park-basics/issues/121)
@@ -94,7 +90,6 @@
controlPoints = [ createPoint( 4.431091234347049, 7.9252447313977665 ), createPoint( 2.4169588550983896, 7.975935759156005 ), createPoint( -1.9874106197862114, 4.75700797278857 ), createPoint( 0.13992761930286512, 6.207060140642635 ), createPoint( 1.447191413237924, 1.0090653610430707 ), createPoint( -1.7008228980322002, 1.0717102008522177 ), createPoint( -5.37101967799642, 7.0748332823816655 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
// Passes through track, OK
@@ -108,7 +103,6 @@
controlPoints = [ createPoint( 5.147227191413236, 6.57851296958855 ), createPoint( 0.05887058823529401, 1.0476264705882334 ), createPoint( -1.9427294117647067, 2.637132352941175 ), createPoint( -3.1201411764705886, 6.404849999999999 ), createPoint( 0.5690823529411766, 6.071249999999999 ), createPoint( -2.3940705882352944, 1.3419794117647044 ), createPoint( -5.474964705882353, 6.5029676470588225 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
// Falls through bottom, OK
@@ -122,7 +116,6 @@
controlPoints = [ createPoint( 5.147227191413236, 6.57851296958855 ), createPoint( -0.43896196231781204, 1.7569427657305372 ), createPoint( -1.1787355229664587, 2.807585005572261 ), createPoint( -3.1201411764705886, 6.404849999999999 ), createPoint( 0.5690823529411766, 6.071249999999999 ), createPoint( -2.3940705882352944, 1.3419794117647044 ), createPoint( -5.474964705882353, 6.5029676470588225 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
// Falls through loop, PROBLEM
@@ -136,7 +129,6 @@
controlPoints = [ createPoint( 5.07086859688196, 6.925682071269487 ), createPoint( 2.061781737193762, 0.7625271732714408 ), createPoint( 0.09287305122494338, 0.7625271732714408 ), createPoint( -3.287706013363029, 3.0472042334050697 ), createPoint( -2.2289532293986642, 4.399535077951003 ), createPoint( -0.6129621380846331, 4.306662026726059 ), createPoint( 0.7429844097995542, 3.3629726075698803 ), createPoint( 0.14859688195991083, 2.3227944338505053 ), createPoint( -1.4302449888641426, 1.4159674088426304 ), createPoint( -4.532204899777283, 0.580109947818132 ), createPoint( -6.1185746102449885, 7.75698912376468 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
// Pops upside down in loop, PROBLEM
@@ -151,7 +143,6 @@
controlPoints = [ createPoint( 5.516659242761692, 5.458287861915368 ), createPoint( 2.061781737193762, 0.7625271732714408 ), createPoint( 0.09287305122494338, 0.7625271732714408 ), createPoint( -3.287706013363029, 3.0472042334050697 ), createPoint( -2.2289532293986642, 4.399535077951003 ), createPoint( -0.6129621380846331, 4.306662026726059 ), createPoint( 0.7429844097995542, 3.3629726075698803 ), createPoint( 0.14859688195991083, 2.3227944338505053 ), createPoint( -1.4302449888641426, 1.4159674088426304 ), createPoint( -4.532204899777283, 0.580109947818132 ), createPoint( -6.1185746102449885, 7.75698912376468 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
if ( EnergySkateParkQueryParameters.testTrackIndex === 10 ) {
@@ -165,7 +156,6 @@
controlPoints = [ createPoint( 5.07086859688196, 6.925682071269487 ), createPoint( 2.061781737193762, 0.7625271732714408 ), createPoint( 0.09287305122494338, 0.7625271732714408 ), createPoint( -3.287706013363029, 3.0472042334050697 ), createPoint( -2.2289532293986642, 4.399535077951003 ), createPoint( -0.6129621380846331, 4.306662026726059 ), createPoint( 0.7429844097995542, 3.3629726075698803 ), createPoint( 0.14859688195991083, 2.3227944338505053 ), createPoint( -1.4302449888641426, 1.4159674088426304 ), createPoint( -4.532204899777283, 0.580109947818132 ), createPoint( -6.1185746102449885, 7.75698912376468 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
if ( EnergySkateParkQueryParameters.testTrackIndex === 11 ) {
@@ -179,7 +169,6 @@
controlPoints = [ createPoint( 7.049477756286265, 5.232410541586074 ), createPoint( 1.8198088164974369, 1.7349575399795614 ), createPoint( -0.14909986947138165, 1.7349575399795614 ), createPoint( 0.5162088974854928, 1.8286581237911035 ), createPoint( -0.4516827852998073, 11.657297387984716 ), createPoint( 2.0970986460348158, 5.6886320108087025 ), createPoint( -1.8000003436635232, 4.708138438138744 ), createPoint( -0.43555125725338684, 5.914473403458605 ), createPoint( -2.500386847195358, 4.849792552394775 ), createPoint( -4.774177820473608, 1.5525403145262526 ), createPoint( -6.339690522243714, 8.797478239845262 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
if ( EnergySkateParkQueryParameters.testTrackIndex === 12 ) {
@@ -193,7 +182,6 @@
controlPoints = [ createPoint( 0.8301088646967347, 3.5809234059097967 ), createPoint( 3.411228615863142, 2.4784350699844477 ), createPoint( 5.29194401244168, 5.928575038880248 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
if ( EnergySkateParkQueryParameters.testTrackIndex === 13 ) {
@@ -207,7 +195,6 @@
controlPoints = [ createPoint( 0.8301088646967347, 3.5809234059097967 ), createPoint( 3.411228615863142, 2.4784350699844477 ), createPoint( 5.29194401244168, 5.928575038880248 ) ];
track = createTrack( controlPoints );
track.physicalProperty.value = true;
- model.tracks.add( track );
}
if ( EnergySkateParkQueryParameters.testTrackIndex === 14 ) {
@@ -223,7 +210,6 @@
];
const track1 = createTrack( controlPoints1 );
track1.physicalProperty.value = false;
- model.tracks.add( track1 );
const controlPoints2 = [
createPoint( -6.23, -0.85 ),
@@ -232,7 +218,6 @@
];
const track2 = createTrack( controlPoints2 );
track2.physicalProperty.value = false;
- model.tracks.add( track2 );
const controlPoints3 = [
createPoint( -0.720977917981072, 1.6368312846731214 ),
@@ -244,7 +229,6 @@
const track3 = createTrack( controlPoints3 );
track3.physicalProperty.value = true;
- model.tracks.add( track3 );
}
//Test decrease in thermal energy, see https://github.com/phetsims/energy-skate-park-basics/issues/141#issuecomment-59395426
@@ -261,7 +245,6 @@
createPoint( -7.310629722921914, 7.457748740554157 )
] );
track15.physicalProperty.value = true;
- model.tracks.add( track15 );
}
if ( EnergySkateParkQueryParameters.testTrackIndex === 16 ) {
@@ -284,7 +267,6 @@
configurable: true
} );
track16.physicalProperty.value = true;
- model.tracks.add( track16 );
}
}
}
Index: js/measure/model/MeasureModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/measure/model/MeasureModel.ts b/js/measure/model/MeasureModel.ts
--- a/js/measure/model/MeasureModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/measure/model/MeasureModel.ts (date 1736976354209)
@@ -50,7 +50,7 @@
// Don't save any EnergySkateParkDataSamples while control points are being dragged. This can be done during construction
// because MeasureModel tracks are static and no new tracks are introduced. For the same reason disposal
// of these listeners is not necessary.
- this.tracks.forEach( track => {
+ this.trackGroup.forEach( track => {
track.controlPointDraggingProperty.link( anyPointDragging => {
this.preventSampleSave = anyPointDragging;
} ); |
Control points configurable work with this patch: Subject: [PATCH] ControlPoints should not be dynamic if the Track they are used in are also not dynamic, https://github.com/phetsims/energy-skate-park/issues/385#issuecomment-2594074224
---
Index: js/graphs/model/GraphsModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/graphs/model/GraphsModel.ts b/js/graphs/model/GraphsModel.ts
--- a/js/graphs/model/GraphsModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/graphs/model/GraphsModel.ts (date 1736981921030)
@@ -83,8 +83,7 @@
},
doubleWellTrackOptions: {
configurable: tracksConfigurable,
- tandem: tandem.createTandem( 'doubleWellTrack' ),
- phetioState: false
+ tandem: tandem.createTandem( 'doubleWellTrack' )
},
parabolaControlPointOptions: {
@@ -95,8 +94,7 @@
},
parabolaTrackOptions: {
configurable: tracksConfigurable,
- tandem: tandem.createTandem( 'parabolaTrack' ),
- phetioState: false
+ tandem: tandem.createTandem( 'parabolaTrack' )
}
},
@@ -328,8 +326,7 @@
const parabolaTrack = PremadeTracks.createTrack( this, parabolaControlPoints, {
configurable: this.tracksConfigurable,
- tandem: tandem.createTandem( 'parabolaTrack' ),
- phetioState: false
+ tandem: tandem.createTandem( 'parabolaTrack' )
} );
const doubleWellControlPoints = PremadeTracks.createDoubleWellControlPoints( this, {
@@ -353,8 +350,7 @@
} );
const doubleWellTrack = PremadeTracks.createTrack( this, doubleWellControlPoints, {
configurable: this.tracksConfigurable,
- tandem: tandem.createTandem( 'doubleWellTrack' ),
- phetioState: false
+ tandem: tandem.createTandem( 'doubleWellTrack' )
} );
return [ parabolaTrack, doubleWellTrack ];
Index: js/common/model/EnergySkateParkTrackSetModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/EnergySkateParkTrackSetModel.ts b/js/common/model/EnergySkateParkTrackSetModel.ts
--- a/js/common/model/EnergySkateParkTrackSetModel.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/model/EnergySkateParkTrackSetModel.ts (date 1736981921034)
@@ -200,8 +200,7 @@
public static createPremadeTrack( model: IntentionalAny, controlPoints: ControlPoint[], options?: TrackOptions ): Track {
options = combineOptions<TrackOptions>( {
- configurable: model.tracksConfigurable,
- phetioState: false
+ configurable: model.tracksConfigurable
}, options );
return PremadeTracks.createTrack( model, controlPoints, options );
Index: js/common/model/PremadeTracks.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/PremadeTracks.ts b/js/common/model/PremadeTracks.ts
--- a/js/common/model/PremadeTracks.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/model/PremadeTracks.ts (date 1736981921020)
@@ -16,6 +16,7 @@
import EnumerationDeprecated from '../../../../phet-core/js/EnumerationDeprecated.js';
import merge from '../../../../phet-core/js/merge.js';
import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
+import Tandem from '../../../../tandem/js/Tandem.js';
import energySkatePark from '../../energySkatePark.js';
import ControlPoint from './ControlPoint.js';
import EnergySkateParkModel from './EnergySkateParkModel.js';
@@ -25,6 +26,9 @@
const END_BOUNDS_WIDTH = 2.5;
const END_BOUNDS_HEIGHT = 4;
+// TODO: tandems inside of actual screens, for reset support
+const controlPointTandem = Tandem.GLOBAL_MODEL.createTandem( 'controlPoints');
+let controlPointCounter = 0;
// the supported premade tracks, used in EnegySkateParkTrackSetModels
const TrackType = EnumerationDeprecated.byKeys( [ 'PARABOLA', 'SLOPE', 'DOUBLE_WELL', 'LOOP' ] );
@@ -92,20 +96,20 @@
const p3Bounds = createCenteredLimitBounds( p3, END_BOUNDS_WIDTH, END_BOUNDS_HEIGHT );
return [
- model.controlPointGroup.createNextElement( p1.x, p1.y, {
+ new ControlPoint( p1.x, p1.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
visible: options.p1Visible,
- limitBounds: p1Bounds,
- phetioState: false
+ limitBounds: p1Bounds
} ),
- model.controlPointGroup.createNextElement( p2.x, p2.y, {
+ new ControlPoint( p2.x, p2.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
visible: options.p2Visible,
- limitBounds: p2Bounds,
- phetioState: false
+ limitBounds: p2Bounds
} ),
- model.controlPointGroup.createNextElement( p3.x, p3.y, {
+ new ControlPoint( p3.x, p3.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
visible: options.p3Visible,
- limitBounds: p3Bounds,
- phetioState: false
+ limitBounds: p3Bounds
} )
];
},
@@ -132,17 +136,17 @@
const p3Bounds = createRelativeSpaceBounds( p3, 0.5, 2.5, 3, 0 );
return [
- model.controlPointGroup.createNextElement( p1.x, p1.y, {
- limitBounds: p1Bounds,
- phetioState: false
+ new ControlPoint( p1.x, p1.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
+ limitBounds: p1Bounds
} ),
- model.controlPointGroup.createNextElement( p2.x, p2.y, {
- limitBounds: p2Bounds,
- phetioState: false
+ new ControlPoint( p2.x, p2.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
+ limitBounds: p2Bounds
} ),
- model.controlPointGroup.createNextElement( p3.x, p3.y, {
- limitBounds: p3Bounds,
- phetioState: false
+ new ControlPoint( p3.x, p3.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
+ limitBounds: p3Bounds
} )
];
},
@@ -193,30 +197,30 @@
const p5Bounds = createRelativeSpaceBounds( p5, 1.5, 1.0, options.p5UpSpacing, options.p5DownSpacing );
return [
- model.controlPointGroup.createNextElement( p1.x, p1.y, {
+ new ControlPoint( p1.x, p1.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
limitBounds: p1Bounds,
- visible: options.p1Visible,
- phetioState: false
+ visible: options.p1Visible
} ),
- model.controlPointGroup.createNextElement( p2.x, p2.y, {
+ new ControlPoint( p2.x, p2.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
limitBounds: p2Bounds,
- visible: options.p2Visible,
- phetioState: false
+ visible: options.p2Visible
} ),
- model.controlPointGroup.createNextElement( p3.x, p3.y, {
+ new ControlPoint( p3.x, p3.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
limitBounds: p3Bounds,
- visible: options.p3Visible,
- phetioState: false
+ visible: options.p3Visible
} ),
- model.controlPointGroup.createNextElement( p4.x, p4.y, {
+ new ControlPoint( p4.x, p4.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
limitBounds: p4Bounds,
- visible: options.p4Visible,
- phetioState: false
+ visible: options.p4Visible
} ),
- model.controlPointGroup.createNextElement( p5.x, p5.y, {
+ new ControlPoint( p5.x, p5.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
limitBounds: p5Bounds,
- visible: options.p5Visible,
- phetioState: false
+ visible: options.p5Visible
} )
];
},
@@ -260,33 +264,33 @@
const p7Bounds = createRelativeSpaceBounds( p7, 1.5, 0.5, 2, 3 );
return [
- model.controlPointGroup.createNextElement( p1.x, p1.y, {
- limitBounds: p1Bounds,
- phetioState: false
+ new ControlPoint( p1.x, p1.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
+ limitBounds: p1Bounds
} ),
- model.controlPointGroup.createNextElement( p2.x, p2.y, {
- limitBounds: p2Bounds,
- phetioState: false
+ new ControlPoint( p2.x, p2.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
+ limitBounds: p2Bounds
} ),
- model.controlPointGroup.createNextElement( p3.x, p3.y, {
- limitBounds: p3Bounds,
- phetioState: false
+ new ControlPoint( p3.x, p3.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
+ limitBounds: p3Bounds
} ),
- model.controlPointGroup.createNextElement( p4.x, p4.y, {
- limitBounds: p4Bounds,
- phetioState: false
+ new ControlPoint( p4.x, p4.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
+ limitBounds: p4Bounds
} ),
- model.controlPointGroup.createNextElement( p5.x, p5.y, {
- limitBounds: p5Bounds,
- phetioState: false
+ new ControlPoint( p5.x, p5.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
+ limitBounds: p5Bounds
} ),
- model.controlPointGroup.createNextElement( p6.x, p6.y, {
- limitBounds: p6Bounds,
- phetioState: false
+ new ControlPoint( p6.x, p6.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
+ limitBounds: p6Bounds
} ),
- model.controlPointGroup.createNextElement( p7.x, p7.y, {
- limitBounds: p7Bounds,
- phetioState: false
+ new ControlPoint( p7.x, p7.y, {
+ tandem: controlPointTandem.createTandem( `controlPoint${controlPointCounter++}` ),
+ limitBounds: p7Bounds
} )
];
},
Index: js/common/model/ControlPoint.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/common/model/ControlPoint.ts b/js/common/model/ControlPoint.ts
--- a/js/common/model/ControlPoint.ts (revision c39746dd28dd4565d5c468fceec79d3a8cdc7324)
+++ b/js/common/model/ControlPoint.ts (date 1736981921024)
@@ -69,11 +69,13 @@
tandem: Tandem.REQUIRED,
phetioType: ControlPoint.ControlPointIO,
+ // !!!!
phetioState: PhetioObject.DEFAULT_OPTIONS.phetioState
}, providedOptions );
const tandem = options.tandem;
// ControlPoints are always stateful, see https://github.com/phetsims/energy-skate-park/issues/385
+ // !!!!
options.phetioState = true;
super( options );
@@ -84,7 +86,7 @@
this.sourcePositionProperty = new Vector2Property( new Vector2( x, y ), {
tandem: tandem.createTandem( 'sourcePositionProperty' ),
- phetioState: options.phetioState // in state only if containing Track is
+ phetioState: true // in state only if containing Track is
} );
this.snapTargetProperty = new Property<ControlPoint | null>( null );
|
Current status:
@zepumph recommended creating a QA dev test, I can do that next. |
Sorry for miscommunication. I recommend creating a Dev version for use in PhET-iO meeting tomorrow. I don't think we are ready for QA just yet. |
Thanks for clarifying, sorry I misunderstood, I closed phetsims/qa#1196 (comment) |
The initial development has been completed, and remaining work is now tracked in issues discovered by QA. Closing. |
Reopening because there is a TODO marked for this issue. |
One theme from today's annual meeting was the difficulty and const in preparing a phet-io simulation for PhET Studio. @matthew-blackman and @LindaStegemann both indicated Energy Skate Park as a possibility, so my subteam wanted to quickly investigate what a minimal instrumentation could look like. This patch uninstruments the control points and tracks and uses an aggregate strategy for saving and restoring state:
This is for the playground screen only. Note that there is incorrect behavior about knowing which tracks are in the control panel. And character selection does not work.
The text was updated successfully, but these errors were encountered: