Skip to content

Commit

Permalink
convert ParticleAtom to typescript, phetsims/shred#38
Browse files Browse the repository at this point in the history
  • Loading branch information
zepumph committed Jul 12, 2023
1 parent da516de commit f84a13a
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 49 deletions.
2 changes: 1 addition & 1 deletion js/chart-intro/model/ChartIntroModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class ChartIntroModel extends BANModel<ParticleNucleus> {
* Create model for particle in mini-nucleus.
*/
public createMiniParticleModel( particleType: ParticleType ): Particle {
const particle = new Particle( particleType.name.toLowerCase() );
const particle = new Particle( particleType.particleTypeString );
this.miniParticleAtom.addParticle( particle );
return particle;
}
Expand Down
2 changes: 1 addition & 1 deletion js/chart-intro/model/ParticleNucleus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class ParticleNucleus extends ParticleAtom {
}

public override removeParticle( particle: Particle ): void {
const nucleonShellPositions = particle.type === ParticleType.PROTON.name.toLowerCase() ? this.protonShellPositions : this.neutronShellPositions;
const nucleonShellPositions = particle.type === ParticleType.PROTON.particleTypeString ? this.protonShellPositions : this.neutronShellPositions;
nucleonShellPositions.forEach( nucleonShellRow => {
nucleonShellRow.forEach( nucleonShellPosition => {
if ( nucleonShellPosition.particle === particle ) {
Expand Down
10 changes: 5 additions & 5 deletions js/chart-intro/view/ChartIntroScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class ChartIntroScreenView extends BANScreenView<ChartIntroModel> {
else if ( nucleonDelta > 0 ) {
_.times( nucleonDelta, () => {
if ( !this.decaying ) {
const particle = model.miniParticleAtom.extractParticle( particleType.name.toLowerCase() );
const particle = model.miniParticleAtom.extractParticle( particleType.particleTypeString );
const particleView = this.findParticleView( particle );
delete this.particleViewMap[ particleView.particle.id ];

Expand Down Expand Up @@ -252,7 +252,7 @@ class ChartIntroScreenView extends BANScreenView<ChartIntroModel> {
this.decaying = true;

// Handle the animation for the mini ParticleAtom
const miniNucleon = this.model.miniParticleAtom.extractParticle( particleType.name.toLowerCase() );
const miniNucleon = this.model.miniParticleAtom.extractParticle( particleType.particleTypeString );

// animate the particle to a random destination outside the model
const destination = this.getRandomExternalModelPosition();
Expand Down Expand Up @@ -305,14 +305,14 @@ class ChartIntroScreenView extends BANScreenView<ChartIntroModel> {
let newNucleonType;
if ( betaDecayType === DecayType.BETA_MINUS_DECAY ) {
particleArray = this.model.miniParticleAtom.neutrons;
particleToEmit = new Particle( ParticleType.ELECTRON.name.toLowerCase() );
particleToEmit = new Particle( ParticleType.ELECTRON.particleTypeString );
nucleonTypeCountValue = this.model.miniParticleAtom.neutronCountProperty.value;
nucleonTypeToChange = ParticleType.NEUTRON;
newNucleonType = ParticleType.PROTON;
}
else {
particleArray = this.model.miniParticleAtom.protons;
particleToEmit = new Particle( ParticleType.POSITRON.name.toLowerCase() );
particleToEmit = new Particle( ParticleType.POSITRON.particleTypeString );
nucleonTypeCountValue = this.model.miniParticleAtom.protonCountProperty.value;
nucleonTypeToChange = ParticleType.PROTON;
newNucleonType = ParticleType.NEUTRON;
Expand All @@ -325,7 +325,7 @@ class ChartIntroScreenView extends BANScreenView<ChartIntroModel> {

// the particle that will change its nucleon type will be the one closest to the center of the atom
const closestParticle = _.sortBy( [ ...particleArray ],
closestParticle => closestParticle.positionProperty.value.distance( this.model.miniParticleAtom.positionProperty.value ) ).shift();
closestParticle => closestParticle.positionProperty.value.distance( this.model.miniParticleAtom.positionProperty.value ) ).shift()!;

// place the particleToEmit in the same position and behind the particle that is changing its nucleon type
particleToEmit.positionProperty.value = closestParticle.positionProperty.value;
Expand Down
4 changes: 2 additions & 2 deletions js/common/model/BANModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class BANModel<T extends ParticleAtom> {
*/
public getParticlesByType( particleType: ParticleType ): Particle[] {
const filteredParticles = _.filter( this.particles, particle => {
return this.particleAtom.containsParticle( particle ) && particle.type === particleType.name.toLowerCase();
return this.particleAtom.containsParticle( particle ) && particle.type === particleType.particleTypeString;
} );

assert && assert( filteredParticles.length !== 0, 'No particles of particleType ' + particleType.name + ' are in the particleAtom.' );
Expand All @@ -134,7 +134,7 @@ class BANModel<T extends ParticleAtom> {
*/
public addParticle( particle: Particle ): void {
assert && assert( _.some( ParticleType.enumeration.values, particleType => {
return particle.type === particleType.name.toLowerCase();
return particle.type === particleType.particleTypeString;
} ),
'Particles must be one of the types in ParticleType ' + particle.type );
this.particles.push( particle );
Expand Down
19 changes: 8 additions & 11 deletions js/common/model/ParticleType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,25 @@ import Enumeration from '../../../../phet-core/js/Enumeration.js';
import { ProfileColorProperty } from '../../../../scenery/js/imports.js';
import BuildANucleusStrings from '../../BuildANucleusStrings.js';
import BANColors from '../BANColors.js';
import { ParticleTypeString } from '../../../../shred/js/model/ParticleAtom.js';

class ParticleType extends EnumerationValue {

public static readonly PROTON = new ParticleType( BuildANucleusStrings.proton, BANColors.protonColorProperty );
public static readonly PROTON = new ParticleType( 'proton', BuildANucleusStrings.proton, BANColors.protonColorProperty );

public static readonly NEUTRON = new ParticleType( BuildANucleusStrings.neutronUppercase, BANColors.neutronColorProperty );
public static readonly NEUTRON = new ParticleType( 'neutron', BuildANucleusStrings.neutronUppercase, BANColors.neutronColorProperty );

public static readonly ELECTRON = new ParticleType( BuildANucleusStrings.electron, BANColors.electronColorProperty );
public static readonly ELECTRON = new ParticleType( 'electron', BuildANucleusStrings.electron, BANColors.electronColorProperty );

public static readonly POSITRON = new ParticleType( BuildANucleusStrings.positron, BANColors.positronColorProperty );
public static readonly POSITRON = new ParticleType( 'positron', BuildANucleusStrings.positron, BANColors.positronColorProperty );

public static readonly enumeration = new Enumeration( ParticleType );

public readonly label: string;
public readonly colorProperty: ProfileColorProperty;

public constructor( label: string, colorProperty: ProfileColorProperty ) {
public constructor( public readonly particleTypeString: ParticleTypeString,
public readonly label: string,
public readonly colorProperty: ProfileColorProperty ) {
super();

this.label = label;
this.colorProperty = colorProperty;

}
}

Expand Down
28 changes: 14 additions & 14 deletions js/common/view/BANScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,26 +368,26 @@ abstract class BANScreenView<M extends BANModel<ParticleAtom | ParticleNucleus>>
this.model.particleAtom.removeParticle( particle );
}

if ( isUserControlled && particle.type === ParticleType.PROTON.name.toLowerCase() && !this.model.userControlledProtons.includes( particle ) ) {
if ( isUserControlled && particle.type === ParticleType.PROTON.particleTypeString && !this.model.userControlledProtons.includes( particle ) ) {
this.model.userControlledProtons.add( particle );
}
else if ( !isUserControlled && particle.type === ParticleType.PROTON.name.toLowerCase() && this.model.userControlledProtons.includes( particle ) ) {
else if ( !isUserControlled && particle.type === ParticleType.PROTON.particleTypeString && this.model.userControlledProtons.includes( particle ) ) {
this.model.userControlledProtons.remove( particle );
}
else if ( isUserControlled && particle.type === ParticleType.NEUTRON.name.toLowerCase() && !this.model.userControlledNeutrons.includes( particle ) ) {
else if ( isUserControlled && particle.type === ParticleType.NEUTRON.particleTypeString && !this.model.userControlledNeutrons.includes( particle ) ) {
this.model.userControlledNeutrons.add( particle );
}
else if ( !isUserControlled && particle.type === ParticleType.NEUTRON.name.toLowerCase() && this.model.userControlledNeutrons.includes( particle ) ) {
else if ( !isUserControlled && particle.type === ParticleType.NEUTRON.particleTypeString && this.model.userControlledNeutrons.includes( particle ) ) {
this.model.userControlledNeutrons.remove( particle );
}
};

// convert string particle type to a ParticleType
const getParticleTypeFromStringType = ( particleTypeString: string ) => {
const particleType = particleTypeString === ParticleType.PROTON.name.toLowerCase() ? ParticleType.PROTON :
particleTypeString === ParticleType.NEUTRON.name.toLowerCase() ? ParticleType.NEUTRON :
particleTypeString === ParticleType.ELECTRON.name.toLowerCase() ? ParticleType.ELECTRON :
particleTypeString === ParticleType.POSITRON.name.toLowerCase() ? ParticleType.POSITRON :
const particleType = particleTypeString === ParticleType.PROTON.particleTypeString ? ParticleType.PROTON :
particleTypeString === ParticleType.NEUTRON.particleTypeString ? ParticleType.NEUTRON :
particleTypeString === ParticleType.ELECTRON.particleTypeString ? ParticleType.ELECTRON :
particleTypeString === ParticleType.POSITRON.particleTypeString ? ParticleType.POSITRON :
null;
assert && assert( particleType !== null, `Particle type ${particleTypeString} is not a valid particle type.` );
return particleType;
Expand Down Expand Up @@ -471,9 +471,9 @@ abstract class BANScreenView<M extends BANModel<ParticleAtom | ParticleNucleus>>
const maxCount = particleType === ParticleType.PROTON ? this.model.protonCountRange.max : this.model.neutronCountRange.max;
const creatorNode = particleType === ParticleType.PROTON ? this.protonsCreatorNode : this.neutronsCreatorNode;
const numberOfNucleons = [ ...this.model.particles ]
.filter( particle => particle.type === particleType.name.toLowerCase() ).length;
.filter( particle => particle.type === particleType.particleTypeString ).length;
const outgoingNucleons = [ ...this.model.outgoingParticles ]
.filter( particle => particle.type === particleType.name.toLowerCase() ).length;
.filter( particle => particle.type === particleType.particleTypeString ).length;

return {
maxCount: maxCount,
Expand Down Expand Up @@ -509,7 +509,7 @@ abstract class BANScreenView<M extends BANModel<ParticleAtom | ParticleNucleus>>
* Create and add a nucleon of particleType immediately to the particleAtom.
*/
public addNucleonImmediatelyToAtom( particleType: ParticleType ): void {
const particle = new Particle( particleType.name.toLowerCase(), {
const particle = new Particle( particleType.particleTypeString, {
maxZLayer: BANConstants.NUMBER_OF_NUCLEON_LAYERS - 1
} );

Expand All @@ -535,7 +535,7 @@ abstract class BANScreenView<M extends BANModel<ParticleAtom | ParticleNucleus>>
public createParticleFromStack( particleType: ParticleType ): Particle {

// create a particle at the center of its creator node
const particle = new Particle( particleType.name.toLowerCase(), {
const particle = new Particle( particleType.particleTypeString, {
maxZLayer: BANConstants.NUMBER_OF_NUCLEON_LAYERS - 1
} );
particle.animationVelocityProperty.value = BANConstants.PARTICLE_ANIMATION_SPEED;
Expand Down Expand Up @@ -741,7 +741,7 @@ abstract class BANScreenView<M extends BANModel<ParticleAtom | ParticleNucleus>>
* Define a function that will decide where to put nucleons.
*/
protected dragEndedListener( nucleon: Particle, atom: ParticleAtom ): void {
const particleCreatorNodeCenter = nucleon.type === ParticleType.PROTON.name.toLowerCase() ?
const particleCreatorNodeCenter = nucleon.type === ParticleType.PROTON.particleTypeString ?
this.protonsCreatorNode.center : this.neutronsCreatorNode.center;

if ( this.isNucleonInCaptureArea( nucleon, atom ) ||
Expand Down Expand Up @@ -821,7 +821,7 @@ abstract class BANScreenView<M extends BANModel<ParticleAtom | ParticleNucleus>>
this.model.particleAtom.neutronCountProperty.value >= 1,
'The particleAtom needs a ' + particleType.name + ' to emit it. The decay: ' + fromDecay + ' cannot occur.' );

const nucleon = this.model.particleAtom.extractParticle( particleType.name.toLowerCase() );
const nucleon = this.model.particleAtom.extractParticle( particleType.particleTypeString );
this.model.outgoingParticles.add( nucleon );
return nucleon;
}
Expand Down
2 changes: 1 addition & 1 deletion js/common/view/NucleonCountPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class NucleonCountPanel extends Panel {
nucleonCountProperty: TReadOnlyProperty<number>, nucleonCountRange: Range ): NucleonLabel => {

const nucleonTitle = new Text( nucleonString, { font: LABEL_FONT, maxWidth: MAX_TITLE_WIDTH } );
const nucleonParticleNode = new ParticleNode( nucleonType.name.toLowerCase(), NUCLEON_PARTICLE_RADIUS );
const nucleonParticleNode = new ParticleNode( nucleonType.particleTypeString, NUCLEON_PARTICLE_RADIUS );
const nucleonContents = new HBox( { spacing: 5, children: [ nucleonParticleNode, nucleonTitle ] } );
nucleonTitle.left = nucleonParticleNode.right + nucleonParticleNode.width / 2;
nucleonTitle.top = nucleonContents.top;
Expand Down
4 changes: 2 additions & 2 deletions js/common/view/NucleonCreatorNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ class NucleonCreatorNode<T extends ParticleAtom> extends Node {
public constructor( particleType: ParticleType, screenView: BANScreenView<BANModel<T>>, particleViewPositionVector: Vector2 ) {
super();

const targetNode = new ParticleNode( particleType.name.toLowerCase(), BANConstants.PARTICLE_RADIUS );
const targetNode = new ParticleNode( particleType.particleTypeString, BANConstants.PARTICLE_RADIUS );
this.addChild( targetNode );
this.touchArea = this.localBounds.dilated( 10 );

this.addInputListener( DragListener.createForwardingListener( event => {

// We want this relative to the screen view, so it is guaranteed to be the proper view coordinates.
const viewPosition = screenView.globalToLocalPoint( event.pointer.point );
const particle = new Particle( particleType.name.toLowerCase(), {
const particle = new Particle( particleType.particleTypeString, {
maxZLayer: BANConstants.NUMBER_OF_NUCLEON_LAYERS - 1
} );
particle.animationVelocityProperty.value = BANConstants.PARTICLE_ANIMATION_SPEED;
Expand Down
2 changes: 1 addition & 1 deletion js/decay/view/AvailableDecaysPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class AvailableDecaysPanel extends Panel {
const createParticleLabel = ( particleType: ParticleType ): Node => {
return new HBox( {
children: [
new ParticleNode( particleType.name.toLowerCase(), particleType === ParticleType.PROTON || particleType === ParticleType.NEUTRON ? NUCLEON_PARTICLE_RADIUS : ELECTRON_PARTICLE_RADIUS ),
new ParticleNode( particleType.particleTypeString, particleType === ParticleType.PROTON || particleType === ParticleType.NEUTRON ? NUCLEON_PARTICLE_RADIUS : ELECTRON_PARTICLE_RADIUS ),
new Text( particleType.label, { font: LABEL_FONT, maxWidth: 100 } )
],
spacing: SPACING
Expand Down
19 changes: 10 additions & 9 deletions js/decay/view/DecayScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ class DecayScreenView extends BANScreenView<DecayModel> {

// remove a nucleon of a given particleType from the atom immediately
const removeNucleonImmediatelyFromAtom = ( particleType: ParticleType ) => {
const particleToRemove = this.model.particleAtom.extractParticle( particleType.name.toLowerCase() );

const particleToRemove = this.model.particleAtom.extractParticle( particleType.particleTypeString );
this.animateAndRemoveParticle( particleToRemove );
};

Expand Down Expand Up @@ -378,13 +379,13 @@ class DecayScreenView extends BANScreenView<DecayModel> {
let nucleonTypeToChange;
if ( betaDecayType === DecayType.BETA_MINUS_DECAY ) {
particleArray = this.model.particleAtom.neutrons;
particleToEmit = new Particle( ParticleType.ELECTRON.name.toLowerCase() );
particleToEmit = new Particle( ParticleType.ELECTRON.particleTypeString );
nucleonTypeCountValue = this.model.particleAtom.neutronCountProperty.value;
nucleonTypeToChange = ParticleType.NEUTRON.name;
}
else {
particleArray = this.model.particleAtom.protons;
particleToEmit = new Particle( ParticleType.POSITRON.name.toLowerCase() );
particleToEmit = new Particle( ParticleType.POSITRON.particleTypeString );
nucleonTypeCountValue = this.model.particleAtom.protonCountProperty.value;
nucleonTypeToChange = ParticleType.PROTON.name;
}
Expand All @@ -395,7 +396,7 @@ class DecayScreenView extends BANScreenView<DecayModel> {

// the particle that will change its nucleon type will be the one closest to the center of the atom
const particle = _.sortBy( [ ...particleArray ],
particle => particle.positionProperty.value.distance( this.model.particleAtom.positionProperty.value ) ).shift();
particle => particle.positionProperty.value.distance( this.model.particleAtom.positionProperty.value ) ).shift()!;

// place the particleToEmit in the same position and behind the particle that is changing its nucleon type
particleToEmit.positionProperty.value = particle.positionProperty.value;
Expand All @@ -405,11 +406,11 @@ class DecayScreenView extends BANScreenView<DecayModel> {
this.model.addParticle( particleToEmit );
const initialColorChangeAnimation = this.model.particleAtom.changeNucleonType( particle, () => {
if ( this.model.particles.includes( particleToEmit ) ) {
this.animateAndRemoveParticle( particleToEmit, this.getRandomExternalModelPosition() );
this.checkIfCreatorNodeShouldBeInvisible( ParticleType.PROTON );
this.checkIfCreatorNodeShouldBeInvisible( ParticleType.NEUTRON );
this.checkIfCreatorNodeShouldBeVisible( ParticleType.PROTON );
this.checkIfCreatorNodeShouldBeVisible( ParticleType.NEUTRON );
this.animateAndRemoveParticle( particleToEmit, this.getRandomExternalModelPosition() );
this.checkIfCreatorNodeShouldBeInvisible( ParticleType.PROTON );
this.checkIfCreatorNodeShouldBeInvisible( ParticleType.NEUTRON );
this.checkIfCreatorNodeShouldBeVisible( ParticleType.PROTON );
this.checkIfCreatorNodeShouldBeVisible( ParticleType.NEUTRON );
}
} );
this.model.particleAnimations.add( initialColorChangeAnimation );
Expand Down
4 changes: 2 additions & 2 deletions js/decay/view/IconFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class IconFactory {
* Function to create a particle node ( a circle with a specific color ), make it bigger if the particle is a nucleon
*/
private static createParticleNode( particleType: ParticleType ): ParticleNode {
return new ParticleNode( particleType.name.toLowerCase(),
return new ParticleNode( particleType.particleTypeString,
particleType === ParticleType.PROTON || particleType === ParticleType.NEUTRON ? NUCLEON_PARTICLE_RADIUS : ELECTRON_PARTICLE_RADIUS
);
}
Expand Down Expand Up @@ -68,7 +68,7 @@ class IconFactory {
return new HBox( {
children: [
IconFactory.createMotionLines( 4 ),
new ParticleNode( particleType.name.toLowerCase(), NUCLEON_PARTICLE_RADIUS )
new ParticleNode( particleType.particleTypeString, NUCLEON_PARTICLE_RADIUS )
],
spacing: SPACING / 4
} );
Expand Down

0 comments on commit f84a13a

Please sign in to comment.