Skip to content

Commit

Permalink
node -> Node in comments and documentation, see phetsims/scenery#1661
Browse files Browse the repository at this point in the history
  • Loading branch information
jessegreenberg committed Nov 20, 2024
1 parent 257e714 commit 65f96e1
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 60 deletions.
10 changes: 4 additions & 6 deletions js/SoundDragListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,17 @@ export type SoundDragListenerOptions<Listener extends PressedSoundDragListener =

export default class SoundDragListener extends DragListener {
public constructor( providedOptions: SoundDragListenerOptions ) {

// Apply the sound options to the drag listener, wrapping start/end callbacks with functions that will
// play sounds on grab and release.
const soundClips = SoundRichDragListener.wireSoundsToDragCallbacks(
const [ pressedSoundClip, releasedSoundClip ] = SoundRichDragListener.createSoundClips(
SoundRichDragListener.DEFAULT_SOUND_OPTIONS,
providedOptions,
providedOptions
);

super( providedOptions );

const isPressedListener = SoundRichDragListener.linkSounds( this, pressedSoundClip, releasedSoundClip );

// When this listener is disposed, sound clips must be removed from the soundManager.
SoundRichDragListener.wireDisposeListener( this, soundClips[ 0 ], soundClips[ 1 ] );
SoundRichDragListener.wireDisposeListener( this, pressedSoundClip, releasedSoundClip, isPressedListener );
}
}

Expand Down
10 changes: 4 additions & 6 deletions js/SoundKeyboardDragListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,17 @@ export type SoundKeyboardDragListenerOptions = KeyboardDragListenerOptions & Ric

export default class SoundKeyboardDragListener extends KeyboardDragListener {
public constructor( providedOptions: SoundKeyboardDragListenerOptions ) {

// Apply the sound options to the drag listener, wrapping start/end callbacks with functions that will
// play sounds on grab and release.
const soundClips = SoundRichDragListener.wireSoundsToDragCallbacks(
const [ pressedSoundClip, releasedSoundClip ] = SoundRichDragListener.createSoundClips(
SoundRichDragListener.DEFAULT_SOUND_OPTIONS,
providedOptions,
providedOptions
);

super( providedOptions );

const isPressedListener = SoundRichDragListener.linkSounds( this, pressedSoundClip, releasedSoundClip );

// When this listener is disposed, sound clips must be removed from the soundManager.
SoundRichDragListener.wireDisposeListener( this, soundClips[ 0 ], soundClips[ 1 ] );
SoundRichDragListener.wireDisposeListener( this, pressedSoundClip, releasedSoundClip, isPressedListener );
}
}

Expand Down
88 changes: 40 additions & 48 deletions js/SoundRichDragListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
*/

import { combineOptions, optionize3 } from '../../phet-core/js/optionize.js';
import { DragListener, DragListenerOptions, KeyboardDragListener, KeyboardDragListenerOptions, RichDragListener, RichDragListenerOptions } from '../../scenery/js/imports.js';
import { DragListener, KeyboardDragListener, RichDragListener, RichDragListenerOptions } from '../../scenery/js/imports.js';
import SoundClip, { SoundClipOptions } from '../../tambo/js/sound-generators/SoundClip.js';
import SoundGenerator from '../../tambo/js/sound-generators/SoundGenerator.js';
import soundManager, { SoundGeneratorAddOptions } from '../../tambo/js/soundManager.js';
import TSoundPlayer from '../../tambo/js/TSoundPlayer.js';
import WrappedAudioBuffer from '../../tambo/js/WrappedAudioBuffer.js';
import grab_mp3 from '../../tambo/sounds/grab_mp3.js';
import release_mp3 from '../../tambo/sounds/release_mp3.js';
Expand Down Expand Up @@ -53,9 +55,6 @@ const DEFAULT_SOUND_OPTIONS = {
const SOUND_RICH_DRAG_LISTENER_DEFAULTS = _.assignIn( {
keyboardDragListenerSoundOptions: {},
dragListenerSoundOptions: {},

// Empty objects by default so we have a reference to the wrapped callbacks when we forward them to the drag
// listeners, see wireSoundsToDragCallbacks.
dragListenerOptions: {},
keyboardDragListenerOptions: {}
}, DEFAULT_SOUND_OPTIONS );
Expand All @@ -68,24 +67,25 @@ export default class SoundRichDragListener extends RichDragListener {
);

// Apply overrides for the KeyboardDragListener sounds and forward to the KeyboardDragListenerOptions drag callbacks.
const dragListenerClips = SoundRichDragListener.wireSoundsToDragCallbacks(
const [ dragListenerPressedSoundClip, dragListenerReleasedSoundClip ] = SoundRichDragListener.createSoundClips(
options,
options.keyboardDragListenerSoundOptions,
options.keyboardDragListenerOptions
options.dragListenerSoundOptions
);

// Apply overrides for the DragListener sounds and forward to the DragListenerOptions drag callbacks.
const keyboardDragListenerClips = SoundRichDragListener.wireSoundsToDragCallbacks(
const [ keyboardDragListenerPressedSoundClip, keyboardDragListenerReleasedSoundClip ] = SoundRichDragListener.createSoundClips(
options,
options.dragListenerSoundOptions,
options.dragListenerOptions
options.keyboardDragListenerSoundOptions
);

super( options );

const dragListenerPressedListener = SoundRichDragListener.linkSounds( this.dragListener, dragListenerPressedSoundClip, dragListenerReleasedSoundClip );
const keyboardDragListenerPressedListener = SoundRichDragListener.linkSounds( this.keyboardDragListener, keyboardDragListenerPressedSoundClip, keyboardDragListenerReleasedSoundClip );

// Dispose the grab and release clips when the listener is disposed.
SoundRichDragListener.wireDisposeListener( this.dragListener, dragListenerClips[ 0 ], dragListenerClips[ 1 ] );
SoundRichDragListener.wireDisposeListener( this.keyboardDragListener, keyboardDragListenerClips[ 0 ], keyboardDragListenerClips[ 1 ] );
SoundRichDragListener.wireDisposeListener( this.dragListener, dragListenerPressedSoundClip, dragListenerReleasedSoundClip, dragListenerPressedListener );
SoundRichDragListener.wireDisposeListener( this.keyboardDragListener, keyboardDragListenerPressedSoundClip, keyboardDragListenerReleasedSoundClip, keyboardDragListenerPressedListener );
}

/**
Expand All @@ -94,68 +94,58 @@ export default class SoundRichDragListener extends RichDragListener {
*
* @param soundOptions - A default set of sound options.
* @param listenerSoundOptions - Overriding sound options for a particular listener.
* @param listenerOptions - Listener specific options with start/end callbacks. Callbacks will be modified/wrapped
* to play sounds on grab and release. This object is modified, and so it is required.
*/
public static wireSoundsToDragCallbacks<T extends DragListener>(
public static createSoundClips(
soundOptions: RichDragListenerSoundOptions,
listenerSoundOptions: RichDragListenerSoundOptions | undefined,
listenerOptions: KeyboardDragListenerOptions | DragListenerOptions<T>
):
[ SoundClip | undefined, SoundClip | undefined ] {
listenerSoundOptions: RichDragListenerSoundOptions | undefined
): [ SoundClip | undefined, SoundClip | undefined ] {

const dragListenerSoundOptions = combineOptions<RichDragListenerSoundOptions>( {}, soundOptions, listenerSoundOptions );
listenerOptions = listenerOptions || {};

// Create the grab SoundClip and wire it into the start function for the drag cycle.
let dragClip: SoundClip | undefined;
if ( dragListenerSoundOptions.grabSound ) {
dragClip = new SoundClip( dragListenerSoundOptions.grabSound, dragListenerSoundOptions.grabSoundClipOptions );
soundManager.addSoundGenerator( dragClip, dragListenerSoundOptions.grabSoundGeneratorAddOptions );

const previousStart = listenerOptions.start;

// @ts-expect-error - The args have implicit any type because of the union of KeyboardDragListenerOptions and
// DragListenerOptions. I (JG) couldn't figure out how to type this properly, even defining the args.
listenerOptions.start = ( ...args ) => {

// @ts-expect-error - see above note.
previousStart && previousStart( ...args );
dragClip!.play();
};
}

// Create the release SoundClip and wire it into the end function for the drag cycle.
let releaseClip: SoundClip | undefined;
if ( dragListenerSoundOptions.releaseSound ) {
releaseClip = new SoundClip( dragListenerSoundOptions.releaseSound, dragListenerSoundOptions.releaseSoundClipOptions );
soundManager.addSoundGenerator( releaseClip, dragListenerSoundOptions.releaseSoundGeneratorAddOptions );

const previousEnd = listenerOptions.end;

// @ts-expect-error - The args have implicit any type because of the union of KeyboardDragListenerOptions and
// DragListenerOptions. I (JG) couldn't figure out how to type this properly, even defining the args.
listenerOptions.end = ( ...args ) => {

// @ts-expect-error - see above note.
previousEnd && previousEnd( ...args );

const listener = args[ 1 ] as DragListener | KeyboardDragListener;
assert && assert( listener instanceof DragListener || listener instanceof KeyboardDragListener, 'listener should be an instance of DragListener or KeyboardDragListener' );
!listener.interrupted && releaseClip!.play();
};
}

return [ dragClip, releaseClip ];
}

/**
* Dispose of the SoundClips and deregister them with soundManager when the listener is disposed.
* Plays the sounds when the drag listener is pressed or released. A reference to the listener is returned so that
* it can be removed for disposal.
*/
public static linkSounds( dragListener: DragListener | KeyboardDragListener, grabSound: TSoundPlayer | undefined, releaseSound: TSoundPlayer | undefined ): ( isPressed: boolean ) => void {
const isPressedListener = ( isPressed: boolean ) => {
if ( isPressed ) {
grabSound && grabSound.play();
}
else if ( !dragListener.interrupted ) {
releaseSound && releaseSound.play();
}
};
dragListener.isPressedProperty.link( isPressedListener );

return isPressedListener;
}

/**
* Handles disposal when the drag listener is disposed by removing sound clips from the sound manager and listeners on
* the DragListener.
*/
public static wireDisposeListener(
listener: DragListener | KeyboardDragListener,
grabClip: SoundClip | undefined,
releaseClip: SoundClip | undefined
grabClip: SoundGenerator | undefined,
releaseClip: SoundGenerator | undefined,
isPressedListener: ( isPressed: boolean ) => void
): void {
listener.disposeEmitter.addListener( () => {
if ( grabClip ) {
Expand All @@ -167,6 +157,8 @@ export default class SoundRichDragListener extends RichDragListener {
releaseClip.dispose();
soundManager.removeSoundGenerator( releaseClip );
}

listener.isPressedProperty.unlink( isPressedListener );
} );
}

Expand Down

1 comment on commit 65f96e1

@jessegreenberg
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was intended for #888.

Please sign in to comment.