diff --git a/js/charges-and-fields/model/ChargedParticle.js b/js/charges-and-fields/model/ChargedParticle.js index e8022a4f..f1d8768c 100644 --- a/js/charges-and-fields/model/ChargedParticle.js +++ b/js/charges-and-fields/model/ChargedParticle.js @@ -7,9 +7,11 @@ */ import merge from '../../../../phet-core/js/merge.js'; +import PhetioObject from '../../../../tandem/js/PhetioObject.js'; import Tandem from '../../../../tandem/js/Tandem.js'; +import NumberIO from '../../../../tandem/js/types/NumberIO.js'; +import VoidIO from '../../../../tandem/js/types/VoidIO.js'; import chargesAndFields from '../../chargesAndFields.js'; -import ChargedParticleIO from './ChargedParticleIO.js'; import ModelElement from './ModelElement.js'; class ChargedParticle extends ModelElement { @@ -25,7 +27,7 @@ class ChargedParticle extends ModelElement { // {Tandem} tandem: Tandem.REQUIRED, - phetioType: ChargedParticleIO, + phetioType: ChargedParticle.ChargedParticleIO, phetioDynamicElement: true }, options ); super( initialPosition, options ); @@ -34,7 +36,51 @@ class ChargedParticle extends ModelElement { // @public (read-only) {number} - a charge of one corresponds to one nano Coulomb this.charge = charge; } + + // @public + applyState( stateObject ) { + super.applyState( stateObject ); + this.charge = stateObject.charge; + } + + /** + * @public + * @returns {Object} + * @override + */ + toStateObject() { + const parentStateObject = super.toStateObject(); + parentStateObject.charge = this.charge; + return parentStateObject; + } + + /** + * @override + * @param {Object} stateObject - see ChargedParticleIO.toStateObject + * @returns {Array.<*>} + * @public + */ + static stateToArgsForConstructor( stateObject ) { + assert && assert( stateObject.charge === 1 || stateObject.charge === -1 ); + // Put charge first for the chargedParticleGroup create function api. + return [ stateObject.charge ].concat( ModelElement.ModelElementIO.stateToArgsForConstructor( stateObject ) ); + } } +ChargedParticle.ChargedParticleIO = PhetioObject.createIOType( ChargedParticle, 'ChargedParticleIO', ModelElement.ModelElementIO, { + documentation: 'A Charged Particle', + methods: { + setCharge: { + returnType: VoidIO, + parameterTypes: [ NumberIO ], + implementation: function( value ) { + this.phetioObject.charge = value.charge; + }, + documentation: 'Set charge (in units of e)', + invocableForReadOnlyElements: false + } + } +} ); + chargesAndFields.register( 'ChargedParticle', ChargedParticle ); export default ChargedParticle; \ No newline at end of file diff --git a/js/charges-and-fields/model/ChargedParticleIO.js b/js/charges-and-fields/model/ChargedParticleIO.js deleted file mode 100644 index 20f3d47a..00000000 --- a/js/charges-and-fields/model/ChargedParticleIO.js +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2017-2020, University of Colorado Boulder - -/** - * IO type for ChargedParticle - * - * @author Sam Reid (PhET Interactive Simulations) - * @author Andrew Adare (PhET Interactive Simulations) - */ - -import validate from '../../../../axon/js/validate.js'; -import NumberIO from '../../../../tandem/js/types/NumberIO.js'; -import ObjectIO from '../../../../tandem/js/types/ObjectIO.js'; -import VoidIO from '../../../../tandem/js/types/VoidIO.js'; -import chargesAndFields from '../../chargesAndFields.js'; -import ModelElementIO from './ModelElementIO.js'; - -class ChargedParticleIO extends ModelElementIO { - - /** - * @public - * @param {ChargedParticle} chargedParticle - * @returns {Object} - * @override - */ - static toStateObject( chargedParticle ) { - validate( chargedParticle, this.validator ); - const parentStateObject = ModelElementIO.toStateObject( chargedParticle ); - parentStateObject.charge = chargedParticle.charge; - return parentStateObject; - } - - /** - * @override - * @param {Object} stateObject - see ChargedParticleIO.toStateObject - * @returns {Array.<*>} - * @public - */ - static stateToArgsForConstructor( stateObject ) { - - // Put charge first for the chargedParticleGroup create function api. - return [ stateObject.charge ].concat( ModelElementIO.stateToArgsForConstructor( stateObject ) ); - } -} - -ChargedParticleIO.methods = { - setCharge: { - returnType: VoidIO, - parameterTypes: [ NumberIO ], - implementation: function( value ) { - this.phetioObject.charge = value.charge; - }, - documentation: 'Set charge (in units of e)', - invocableForReadOnlyElements: false - } -}; -ChargedParticleIO.documentation = 'A Charged Particle'; -ChargedParticleIO.validator = { isValidValue: v => v instanceof phet.chargesAndFields.ChargedParticle }; -ChargedParticleIO.typeName = 'ChargedParticleIO'; -ObjectIO.validateSubtype( ChargedParticleIO ); - -chargesAndFields.register( 'ChargedParticleIO', ChargedParticleIO ); -export default ChargedParticleIO; \ No newline at end of file diff --git a/js/charges-and-fields/model/ChargesAndFieldsModel.js b/js/charges-and-fields/model/ChargesAndFieldsModel.js index a843de6c..2c7dde9a 100644 --- a/js/charges-and-fields/model/ChargesAndFieldsModel.js +++ b/js/charges-and-fields/model/ChargesAndFieldsModel.js @@ -21,13 +21,12 @@ import Tandem from '../../../../tandem/js/Tandem.js'; import chargesAndFields from '../../chargesAndFields.js'; import ChargesAndFieldsConstants from '../ChargesAndFieldsConstants.js'; import ChargedParticle from './ChargedParticle.js'; -import ChargedParticleIO from './ChargedParticleIO.js'; import ElectricFieldSensor from './ElectricFieldSensor.js'; import ElectricPotentialLine from './ElectricPotentialLine.js'; import ElectricPotentialLineIO from './ElectricPotentialLineIO.js'; import ElectricPotentialSensor from './ElectricPotentialSensor.js'; import MeasuringTape from './MeasuringTape.js'; -import ModelElementIO from './ModelElementIO.js'; +import ModelElement from './ModelElement.js'; // constants const GRID_MINOR_SPACING = ChargesAndFieldsConstants.GRID_MAJOR_SPACING / ChargesAndFieldsConstants.MINOR_GRIDLINES_PER_MAJOR_GRIDLINE; @@ -136,7 +135,7 @@ class ChargesAndFieldsModel extends PhetioObject { return chargedParticle; }, [ 1, Vector2.ZERO ], { tandem: tandem.createTandem( 'chargedParticleGroup' ), - phetioType: PhetioGroupIO( ChargedParticleIO ), + phetioType: PhetioGroupIO( ChargedParticle.ChargedParticleIO ), phetioDynamicElementName: 'particle' } ); const chargedParticleGroup = this.chargedParticleGroup; @@ -145,7 +144,7 @@ class ChargesAndFieldsModel extends PhetioObject { // This is the relevant array to calculate the electric field, and electric potential // @public {ObservableArray.} this.activeChargedParticles = new ObservableArray( { - phetioType: PropertyIO( ChargedParticleIO ) + phetioType: PropertyIO( ChargedParticle.ChargedParticleIO ) } ); // @public {PhetioGroup.} Observable group of electric field sensors @@ -155,7 +154,7 @@ class ChargesAndFieldsModel extends PhetioObject { return sensor; }, [ Vector2.ZERO ], { tandem: tandem.createTandem( 'electricFieldSensorGroup' ), - phetioType: PhetioGroupIO( ModelElementIO ) + phetioType: PhetioGroupIO( ModelElement.ModelElementIO ) } ); // {ObservableArray.} const electricFieldSensorGroup = this.electricFieldSensorGroup; diff --git a/js/charges-and-fields/model/ElectricPotentialLineIO.js b/js/charges-and-fields/model/ElectricPotentialLineIO.js index e434b7e2..b7a80bb6 100644 --- a/js/charges-and-fields/model/ElectricPotentialLineIO.js +++ b/js/charges-and-fields/model/ElectricPotentialLineIO.js @@ -10,9 +10,9 @@ import validate from '../../../../axon/js/validate.js'; import Vector2IO from '../../../../dot/js/Vector2IO.js'; import ObjectIO from '../../../../tandem/js/types/ObjectIO.js'; import chargesAndFields from '../../chargesAndFields.js'; -import ModelElementIO from './ModelElementIO.js'; +import ModelElement from './ModelElement.js'; -class ElectricPotentialLineIO extends ModelElementIO { +class ElectricPotentialLineIO extends ModelElement.ModelElementIO { /** * @public diff --git a/js/charges-and-fields/model/ModelElement.js b/js/charges-and-fields/model/ModelElement.js index 0c386d01..2e702fd6 100644 --- a/js/charges-and-fields/model/ModelElement.js +++ b/js/charges-and-fields/model/ModelElement.js @@ -9,12 +9,17 @@ import BooleanProperty from '../../../../axon/js/BooleanProperty.js'; import Emitter from '../../../../axon/js/Emitter.js'; import Vector2 from '../../../../dot/js/Vector2.js'; +import Vector2IO from '../../../../dot/js/Vector2IO.js'; import Vector2Property from '../../../../dot/js/Vector2Property.js'; import merge from '../../../../phet-core/js/merge.js'; import PhetioObject from '../../../../tandem/js/PhetioObject.js'; +import NullableIO from '../../../../tandem/js/types/NullableIO.js'; +import ObjectIO from '../../../../tandem/js/types/ObjectIO.js'; import chargesAndFields from '../../chargesAndFields.js'; import ChargesAndFieldsConstants from '../ChargesAndFieldsConstants.js'; -import ModelElementIO from './ModelElementIO.js'; + +// constants +const NullableIOVector2IO = NullableIO( Vector2IO ); class ModelElement extends PhetioObject { @@ -26,7 +31,7 @@ class ModelElement extends PhetioObject { options = merge( { - phetioType: ModelElementIO + phetioType: ModelElement.ModelElementIO }, options ); super( options ); @@ -119,7 +124,48 @@ class ModelElement extends PhetioObject { this.animationTween.start( phet.joist.elapsedTime ); } + + /** + * @public + * @returns {Object} + * @override + */ + toStateObject() { + return { + initialPosition: NullableIOVector2IO.toStateObject( this.initialPosition ) + }; + } + + // @private + static fromStateObject( stateObject ) { + return { + initialPosition: NullableIOVector2IO.fromStateObject( stateObject.initialPosition ) + }; + } + + /** + * @param {Object} stateObject + * @public + */ + applyState( stateObject ) { + const s = ModelElement.fromStateObject( stateObject ); + this.initialPosition = s.initialPosition; + } + + /** + * @public + * @override + * @param {Object} stateObject + * @returns {Array.<*>} + */ + static stateToArgsForConstructor( stateObject ) { + return [ NullableIOVector2IO.fromStateObject( stateObject.initialPosition ) ]; + } } +ModelElement.ModelElementIO = PhetioObject.createIOType( ModelElement, 'ModelElementIO', ObjectIO, { + documentation: 'A Model Element' +} ); + chargesAndFields.register( 'ModelElement', ModelElement ); export default ModelElement; \ No newline at end of file diff --git a/js/charges-and-fields/model/ModelElementIO.js b/js/charges-and-fields/model/ModelElementIO.js deleted file mode 100644 index abaa7aee..00000000 --- a/js/charges-and-fields/model/ModelElementIO.js +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017-2020, University of Colorado Boulder - -/** - * IO type for ModelElement - * - * @author Sam Reid (PhET Interactive Simulations) - * @author Andrew Adare (PhET Interactive Simulations) - */ - -import validate from '../../../../axon/js/validate.js'; -import Vector2IO from '../../../../dot/js/Vector2IO.js'; -import NullableIO from '../../../../tandem/js/types/NullableIO.js'; -import ObjectIO from '../../../../tandem/js/types/ObjectIO.js'; -import chargesAndFields from '../../chargesAndFields.js'; - -const NullableIOVector2IO = NullableIO( Vector2IO ); - -class ModelElementIO extends ObjectIO { - - /** - * @public - * @param {ModelElement} modelElement - * @returns {Object} - * @override - */ - static toStateObject( modelElement ) { - validate( modelElement, this.validator ); - return { - initialPosition: NullableIOVector2IO.toStateObject( modelElement.initialPosition ) - }; - } - - /** - * @public - * @override - * @param {Object} stateObject - see ModelElementIO.toStateObject - * @returns {Array.<*>} - */ - static stateToArgsForConstructor( stateObject ) { - return [ NullableIOVector2IO.fromStateObject( stateObject.initialPosition ) ]; - } -} - -ModelElementIO.validator = { isValidValue: e => e instanceof phet.chargesAndFields.ModelElement }; -ModelElementIO.documentation = 'A Model Element'; -ModelElementIO.typeName = 'ModelElementIO'; -ObjectIO.validateSubtype( ModelElementIO ); - -chargesAndFields.register( 'ModelElementIO', ModelElementIO ); -export default ModelElementIO; \ No newline at end of file