Skip to content

Commit

Permalink
convert Representation from Enumeration to a collection of static ins…
Browse files Browse the repository at this point in the history
…tances, #217
  • Loading branch information
pixelzoom committed Nov 2, 2021
1 parent 1fbf479 commit 069f503
Show file tree
Hide file tree
Showing 16 changed files with 139 additions and 118 deletions.
9 changes: 5 additions & 4 deletions js/common/model/GeometricOpticsModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
* @author Chris Malley (PixelZoom, Inc.)
*/

import EnumerationProperty from '../../../../axon/js/EnumerationProperty.js';
import NumberProperty from '../../../../axon/js/NumberProperty.js';
import Property from '../../../../axon/js/Property.js';
import StringProperty from '../../../../axon/js/StringProperty.js';
import Range from '../../../../dot/js/Range.js';
import merge from '../../../../phet-core/js/merge.js';
Expand All @@ -35,7 +35,7 @@ class GeometricOpticsModel {
readonly optic: Optic;

// representation of the source object
readonly representationProperty: any; //TODO-TS any
readonly representationProperty: Property<Representation>;

// source object and first light source
readonly sourceObject: SourceObject;
Expand Down Expand Up @@ -85,7 +85,8 @@ class GeometricOpticsModel {
constructor( optic: Optic, options?: any ) { //TODO-TS any

options = merge( {
representations: Representation.VALUES,
representation: Representation.ALL_STATIC_INSTANCES[ 0 ],
representations: Representation.ALL_STATIC_INSTANCES,

// phet-io options
tandem: Tandem.REQUIRED
Expand All @@ -94,7 +95,7 @@ class GeometricOpticsModel {
this.optic = optic;

// @ts-ignore TODO-TS Property 'PENCIL' does not exist on type 'Enumeration'.
this.representationProperty = new EnumerationProperty( Representation, Representation.PENCIL, {
this.representationProperty = new Property<Representation>( options.representation, {
validValues: options.representations
} );

Expand Down
7 changes: 4 additions & 3 deletions js/common/model/LightRays.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Optic from './Optic.js';
import Ray from './Ray.js';
import RaysModeEnum from './RaysModeEnum.js';
import Target from './Target.js';
import Representation from './Representation.js';

class LightRays {

Expand All @@ -34,14 +35,14 @@ class LightRays {
/**
* @param {Property.<number>} timeProperty
* @param {Property.<RaysModeEnum>} raysModeProperty
* @param {EnumerationProperty.<Representation>} representationProperty
* @param {Property.<Representation>} representationProperty
* @param {Property.<Vector2>} sourceObjectPositionProperty
* @param {ProjectionScreen} projectionScreen
* @param {Optic} optic
* @param {Target} target - target model associated with this ray
*/
constructor( timeProperty: Property<number>, raysModeProperty: Property<RaysModeEnum>,
representationProperty: any, sourceObjectPositionProperty: Property<Vector2>, //TODO-TS any
representationProperty: Property<Representation>, sourceObjectPositionProperty: Property<Vector2>,
projectionScreen: ProjectionScreen, optic: Optic, target: Target ) {

this.realSegments = [];
Expand All @@ -59,7 +60,7 @@ class LightRays {
optic.diameterProperty,
optic.focalLengthProperty,
optic.opticShapeProperty ],
( sourcePosition: Vector2, raysMode: RaysModeEnum, time: number, representation: any ) => { //TODO-TS any
( sourcePosition: Vector2, raysMode: RaysModeEnum, time: number, representation: Representation ) => {

// Clear the arrays.
this.realSegments = [];
Expand Down
140 changes: 72 additions & 68 deletions js/common/model/Representation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

//TODO name is too vague, maybe SourceRepresentation?
/**
* Representation is a rich enumeration of the source objects and light sources.
* Representation is a set of static representation for source objects and light sources.
*
* @author Martin Veillette
* @author Chris Malley (PixelZoom, Inc.)
*/

import Vector2 from '../../../../dot/js/Vector2.js';
import Enumeration from '../../../../phet-core/js/Enumeration.js';
import merge from '../../../../phet-core/js/merge.js';
import required from '../../../../phet-core/js/required.js';
import lamp1_png from '../../../images/lamp1_png.js';
Expand Down Expand Up @@ -49,10 +49,7 @@ const OBJECT_OFFSET = new Vector2( -67, 100 );
// This is specific to the light-source PNG files, and must be uniform for all light-source PNG files.
const LIGHT_SOURCE_OFFSET = new Vector2( -62, 40 );

/**
* RepresentationValue is a value for this rich enumeration.
*/
class RepresentationValue {
class Representation {

/**
* @param {Object} config
Expand Down Expand Up @@ -112,69 +109,76 @@ class RepresentationValue {
}
}

const Representation = Enumeration.byMap( {

PENCIL: new RepresentationValue( {
label: geometricOpticsStrings.pencil,
icon: pencilIcon_png,
rightFacingUpright: pencilRightFacingUpright_png,
rightFacingInverted: pencilRightFacingInverted_png,
leftFacingUpright: pencilLeftFacingUpright_png,
leftFacingInverted: pencilLeftFacingInverted_png,
rightFacingUprightOffset: OBJECT_OFFSET,
isObject: true,
tandemPrefix: 'pencil'
} ),

PENGUIN: new RepresentationValue( {
label: geometricOpticsStrings.penguin,
icon: penguinIcon_png,
rightFacingUpright: penguinRightFacingUpright_png,
rightFacingInverted: penguinRightFacingInverted_png,
leftFacingUpright: penguinLeftFacingUpright_png,
leftFacingInverted: penguinLeftFacingInverted_png,
rightFacingUprightOffset: OBJECT_OFFSET,
isObject: true,
tandemPrefix: 'penguin'
} ),

PLANET: new RepresentationValue( {
label: geometricOpticsStrings.planet,
icon: planetIcon_png,
rightFacingUpright: planetRightFacingUpright_png,
rightFacingInverted: planetRightFacingInverted_png,
leftFacingUpright: planetLeftFacingUpright_png,
leftFacingInverted: planetLeftFacingInverted_png,
rightFacingUprightOffset: OBJECT_OFFSET,
isObject: true,
tandemPrefix: 'planet'
} ),

STAR: new RepresentationValue( {
label: geometricOpticsStrings.star,
icon: starIcon_png,
rightFacingUpright: starRightFacingUpright_png,
rightFacingInverted: starRightFacingInverted_png,
leftFacingUpright: starLeftFacingUpright_png,
leftFacingInverted: starLeftFacingInverted_png,
rightFacingUprightOffset: OBJECT_OFFSET,
isObject: true,
tandemPrefix: 'star'
} ),

LIGHT: new RepresentationValue( {
label: geometricOpticsStrings.light,
icon: lightIcon_png,
rightFacingUpright: lamp1_png,
rightFacingInverted: null,
leftFacingUpright: null,
leftFacingInverted: null,
rightFacingUprightOffset: LIGHT_SOURCE_OFFSET,
isObject: false,
secondLightSourceImage: lamp2_png,
tandemPrefix: 'light'
} )
// static instances
Representation.PENCIL = new Representation( {
label: geometricOpticsStrings.pencil,
icon: pencilIcon_png,
rightFacingUpright: pencilRightFacingUpright_png,
rightFacingInverted: pencilRightFacingInverted_png,
leftFacingUpright: pencilLeftFacingUpright_png,
leftFacingInverted: pencilLeftFacingInverted_png,
rightFacingUprightOffset: OBJECT_OFFSET,
isObject: true,
tandemPrefix: 'pencil'
} );

Representation.PENGUIN = new Representation( {
label: geometricOpticsStrings.penguin,
icon: penguinIcon_png,
rightFacingUpright: penguinRightFacingUpright_png,
rightFacingInverted: penguinRightFacingInverted_png,
leftFacingUpright: penguinLeftFacingUpright_png,
leftFacingInverted: penguinLeftFacingInverted_png,
rightFacingUprightOffset: OBJECT_OFFSET,
isObject: true,
tandemPrefix: 'penguin'
} );

Representation.PLANET = new Representation( {
label: geometricOpticsStrings.planet,
icon: planetIcon_png,
rightFacingUpright: planetRightFacingUpright_png,
rightFacingInverted: planetRightFacingInverted_png,
leftFacingUpright: planetLeftFacingUpright_png,
leftFacingInverted: planetLeftFacingInverted_png,
rightFacingUprightOffset: OBJECT_OFFSET,
isObject: true,
tandemPrefix: 'planet'
} );

Representation.STAR = new Representation( {
label: geometricOpticsStrings.star,
icon: starIcon_png,
rightFacingUpright: starRightFacingUpright_png,
rightFacingInverted: starRightFacingInverted_png,
leftFacingUpright: starLeftFacingUpright_png,
leftFacingInverted: starLeftFacingInverted_png,
rightFacingUprightOffset: OBJECT_OFFSET,
isObject: true,
tandemPrefix: 'star'
} );

Representation.LIGHT = new Representation( {
label: geometricOpticsStrings.light,
icon: lightIcon_png,
rightFacingUpright: lamp1_png,
rightFacingInverted: null,
leftFacingUpright: null,
leftFacingInverted: null,
rightFacingUprightOffset: LIGHT_SOURCE_OFFSET,
isObject: false, // this is what identifies it as a light source
secondLightSourceImage: lamp2_png,
tandemPrefix: 'light'
} );

// All of the above static instances.
Representation.ALL_STATIC_INSTANCES = [
Representation.PENCIL,
Representation.PENGUIN,
Representation.PLANET,
Representation.STAR,
Representation.LIGHT
];

geometricOptics.register( 'Representation', Representation );
export default Representation;
9 changes: 6 additions & 3 deletions js/common/model/SecondPoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import RangeWithValue from '../../../../dot/js/RangeWithValue.js';
import Vector2 from '../../../../dot/js/Vector2.js';
import Vector2Property from '../../../../dot/js/Vector2Property.js';
import geometricOptics from '../../geometricOptics.js';
import Representation from './Representation.js';

// initial position of the second light source, in cm
const INITIAL_LIGHT_SOURCE_POSITION = new Vector2( -150, -20 );
Expand All @@ -32,11 +33,13 @@ class SecondPoint {
private readonly sourceObjectPositionProperty: Property<Vector2>;

/**
* @param {EnumerationProperty.<Representation>} representationProperty
* @param {Property.<Representation>} representationProperty
* @param {Property.<Vector2>} sourceObjectPositionProperty
* @param {Object} [options]
*/
constructor( representationProperty: any, sourceObjectPositionProperty: Property<Vector2>, options?: any ) { //TODO-TS any any
// eslint-disable-next-line no-undef
constructor( representationProperty: Property<Representation>, sourceObjectPositionProperty: Property<Vector2>,
options?: any ) { //TODO-TS any any

this.lightSourcePositionProperty = new Vector2Property( INITIAL_LIGHT_SOURCE_POSITION );

Expand All @@ -46,7 +49,7 @@ class SecondPoint {

this.positionProperty = new DerivedProperty<Vector2>(
[ sourceObjectPositionProperty, this.verticalOffsetProperty, this.lightSourcePositionProperty, representationProperty ],
( sourceObjectPosition: Vector2, verticalOffset: number, lightSourcePosition: Vector2, representation: any ) => //TODO-TS any
( sourceObjectPosition: Vector2, verticalOffset: number, lightSourcePosition: Vector2, representation: Representation ) =>
representation.isObject ? sourceObjectPosition.plusXY( 0, verticalOffset ) : lightSourcePosition
);

Expand Down
10 changes: 6 additions & 4 deletions js/common/model/SourceObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import Vector2 from '../../../../dot/js/Vector2.js';
import Vector2Property from '../../../../dot/js/Vector2Property.js';
import geometricOptics from '../../geometricOptics.js';
import Bounds2 from '../../../../dot/js/Bounds2.js';
import Property from '../../../../axon/js/Property.js';
import Representation from './Representation.js';

// initial position of the source object, in cm
const INITIAL_POSITION = new Vector2( -170, 30 );
Expand All @@ -29,9 +31,9 @@ class SourceObject {
public readonly boundsProperty: DerivedProperty<Bounds2>;

/**
* @param {EnumerationProperty.<Representation>} representationProperty
* @param {Property.<Representation>} representationProperty
*/
constructor( representationProperty: any ) { //TODO any
constructor( representationProperty: Property<Representation> ) {

// {Vector2} displacement vector from the firstPosition to the left top, in cm - value depends on representation
//TODO this feels unnecessary, and causes ordering dependencies herein
Expand All @@ -51,15 +53,15 @@ class SourceObject {

this.boundsProperty = new DerivedProperty<Bounds2>(
[ this.leftTopProperty, representationProperty ],
( leftTop: Vector2, representation: any ) => { //TODO-TS any
( leftTop: Vector2, representation: Representation ) => {
const scaleFactor = representation.getScaleFactor();
const size = new Dimension2( representation.rightFacingUpright.width / scaleFactor,
representation.rightFacingUpright.height / scaleFactor );
return size.toBounds( leftTop.x, leftTop.y - size.height );
} );

// update the left top position when the representation changes
representationProperty.link( ( representation: any ) => { //TODO-TS any
representationProperty.link( ( representation: Representation ) => {

// {Vector2} update the value of the offset
offset = representation.rightFacingUprightOffset.dividedScalar( representation.getScaleFactor() );
Expand Down
9 changes: 5 additions & 4 deletions js/common/model/Target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Bounds2 from '../../../../dot/js/Bounds2.js';
import Vector2 from '../../../../dot/js/Vector2.js';
import geometricOptics from '../../geometricOptics.js';
import Optic from './Optic.js';
import Representation from './Representation.js';

class Target {

Expand Down Expand Up @@ -49,9 +50,9 @@ class Target {
/**
* @param {Property.<Vector2>} objectPositionProperty - position of the source object or light source
* @param {Optic} optic - model of the optic
* @param {EnumerationProperty.<Representation>} representationProperty
* @param {Property.<Representation>} representationProperty
*/
constructor( objectPositionProperty: Property<Vector2>, optic: Optic, representationProperty: any ) { //TODO-TS any
constructor( objectPositionProperty: Property<Vector2>, optic: Optic, representationProperty: Property<Representation> ) {

this.opticSign = optic.getSign();

Expand Down Expand Up @@ -119,7 +120,7 @@ class Target {
this.boundsProperty = new DerivedProperty<Bounds2>(
[ this.positionProperty, representationProperty, this.magnificationProperty, this.isInvertedProperty ],
//TODO isInverted is not used, is dependency needed?
( position: Vector2, representation: any, magnification: number, isInverted: boolean ) => { //TODO-TS any
( position: Vector2, representation: Representation, magnification: number, isInverted: boolean ) => {

const scaleFactor = representation.getScaleFactor();
const initialOffset = representation.rightFacingUprightOffset.timesScalar( 1 / scaleFactor );
Expand Down Expand Up @@ -159,7 +160,7 @@ class Target {

this.imageProperty = new DerivedProperty<HTMLImageElement|null>(
[ representationProperty, this.isVirtualProperty ],
( representation: any, isVirtual: boolean ) => { //TODO-TS any
( representation: Representation, isVirtual: boolean ) => {
const realImage = optic.isLens() ? representation.leftFacingInverted : representation.rightFacingInverted;
const virtualImage = optic.isLens() ? representation.rightFacingUpright : representation.leftFacingUpright;
return isVirtual ? virtualImage : realImage;
Expand Down
7 changes: 4 additions & 3 deletions js/common/view/GeometricOpticsControlPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import GeometricOpticsColors from '../GeometricOpticsColors.js';
import GeometricOpticsConstants from '../GeometricOpticsConstants.js';
import Optic from '../model/Optic.js';
import RaysModeEnum from '../model/RaysModeEnum.js';
import Representation from '../model/Representation.js';
import RaysRadioButtonGroup from './RaysRadioButtonGroup.js';
import VisibilityCheckboxGroup from './VisibilityCheckboxGroup.js';
import VisibleProperties from './VisibleProperties.js';
Expand All @@ -49,13 +50,13 @@ const NUMBER_CONTROL_OPTIONS = {
class GeometricOpticsControlPanel extends Panel {

/**
* @param {EnumerationProperty.<Representation>} representationProperty
* @param {Property.<Representation>} representationProperty
* @param {Optic} optic
* @param {EnumerationProperty.<RaysModeEnum>} raysModeProperty
* @param {Property.<RaysModeEnum>} raysModeProperty
* @param {VisibleProperties} visibleProperties
* @param {Object} [options]
*/
constructor( representationProperty: any, optic: Optic, raysModeProperty: Property<RaysModeEnum>, //TODO-TS any
constructor( representationProperty: Property<Representation>, optic: Optic, raysModeProperty: Property<RaysModeEnum>,
visibleProperties: VisibleProperties, options?: any ) { //TODO-TS any

options = merge( {
Expand Down
Loading

0 comments on commit 069f503

Please sign in to comment.