Skip to content

Commit

Permalink
Use array args instead of overloads, see #254
Browse files Browse the repository at this point in the history
  • Loading branch information
samreid committed Feb 11, 2022
1 parent 8e49619 commit 7d75309
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 34 deletions.
13 changes: 3 additions & 10 deletions js/PhetioCapsule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,16 @@ import PhetioObject from './PhetioObject.js';
// constants
const DEFAULT_CONTAINER_SUFFIX = 'Capsule';

class PhetioCapsule<T extends PhetioObject, A = never, B = never, C = never, D = never, E = never> extends PhetioDynamicElementContainer<T, A, B, C, D, E> {
class PhetioCapsule<T extends PhetioObject, P extends any[] = []> extends PhetioDynamicElementContainer<T, P> {
private element: T | null;
static PhetioCapsuleIO: ( parameterType: IOType ) => IOType;

// TODO: Should this use <T extends any[] = []> like TinyEmitter? see https://github.com/phetsims/tandem/issues/254
constructor( createElement: ( tandem: Tandem, a: A ) => T, defaultArguments: [ A ], options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B ) => T, defaultArguments: [ A, B ], options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B, c: C ) => T, defaultArguments: [ A, B, C ], options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B, c: C, d: D ) => T, defaultArguments: [ A, B, C, D ], options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B, c: C, d: D, e: E ) => T, defaultArguments: [ A, B, C, D, E ], options: any );

/**
* @param {function(Tandem, ...):PhetioObject} createElement - function that creates the encapsulated element
* @param {Array.<*>|function():Array.<*>} defaultArguments - arguments passed to createElement when creating the archetype
* @param {Object} [options]
*/
constructor( createElement: any, defaultArguments: any, options?: any ) {
constructor( createElement: ( t: Tandem, ...p: P ) => T, defaultArguments: P | ( () => P ), options?: any ) {

options = merge( {
tandem: Tandem.OPTIONAL,
Expand Down Expand Up @@ -73,7 +66,7 @@ class PhetioCapsule<T extends PhetioObject, A = never, B = never, C = never, D =
* @returns {Object}
* @public
*/
getElement( ...argsForCreateFunction: any ) {
getElement( ...argsForCreateFunction: P ) {
if ( !this.element ) {
this.create( argsForCreateFunction );
}
Expand Down
13 changes: 3 additions & 10 deletions js/PhetioDynamicElementContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import IOType from './types/IOType.js';
// constants
const DEFAULT_CONTAINER_SUFFIX = 'Container';

class PhetioDynamicElementContainer<T extends PhetioObject, A = never, B = never, C = never, D = never, E = never> extends PhetioObject {
class PhetioDynamicElementContainer<T extends PhetioObject, P extends any[] = []> extends PhetioObject {
readonly archetype: T;
elementCreatedEmitter: Emitter<[ T ]>;
elementDisposedEmitter: Emitter<[ T ]>;
Expand All @@ -38,21 +38,14 @@ class PhetioDynamicElementContainer<T extends PhetioObject, A = never, B = never
createElement: any;
defaultArguments: any;

// TODO: Should this use <T extends any[] = []> like TinyEmitter? see https://github.com/phetsims/tandem/issues/254
constructor( createElement: ( tandem: Tandem, a: A ) => T, defaultArguments: [ A ], options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B ) => T, defaultArguments: [ A, B ], options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B, c: C ) => T, defaultArguments: [ A, B, C ], options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B, c: C, d: D ) => T, defaultArguments: [ A, B, C, D ], options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B, c: C, d: D, e: E ) => T, defaultArguments: [ A, B, C, D, E ], options: any );

/**
* @param {function(Tandem,...args):PhetioObject} createElement - function that creates a dynamic element to be housed in
* this container. All of this dynamic element container's elements will be created from this function, including the
* archetype.
* @param {Array.<*>|function():Array.<*>} defaultArguments - arguments passed to createElement when creating the archetype
* @param {Object} [options] - describe the Group itself
*/
constructor( createElement: any, defaultArguments: any, options?: any ) {
constructor( createElement: ( t: Tandem, ...args: P ) => T, defaultArguments: P | ( () => P ), options?: any ) {

options = merge( {
phetioState: false, // elements are included in state, but the container will exist in the downstream sim.
Expand Down Expand Up @@ -235,7 +228,7 @@ class PhetioDynamicElementContainer<T extends PhetioObject, A = never, B = never
* @param {Array.<*>} argsForCreateFunction
* @param {IOType|null} containerParameterType - null in PhET brand
*/
createDynamicElement( componentName: string, argsForCreateFunction: any, containerParameterType: any ): T {
createDynamicElement( componentName: string, argsForCreateFunction: P, containerParameterType: any ): T {
assert && assert( Array.isArray( argsForCreateFunction ), 'should be array' );

// create with default state and substructure, details will need to be set by setter methods.
Expand Down
21 changes: 7 additions & 14 deletions js/PhetioGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,12 @@ const DEFAULT_CONTAINER_SUFFIX = 'Group';
// type Derivation<T, Parameters extends any[]> = ( ...params: Parameters ) => T;

// A extends ( ...args: any[] ) => any, B extends Parameters<A>
class PhetioGroup<T extends PhetioObject, A = never, B = never, C = never, D = never, E = never> extends PhetioDynamicElementContainer<T, A, B, C, D, E> {
_array: T[];
class PhetioGroup<T extends PhetioObject, P extends any[] = []> extends PhetioDynamicElementContainer<T, P> {
private readonly _array: T[];
groupElementIndex: number;
countProperty: NumberProperty;
readonly countProperty: NumberProperty;
static PhetioGroupIO: ( parameterType: any ) => any;

// TODO: Should this use <T extends any[] = []> like TinyEmitter? see https://github.com/phetsims/tandem/issues/254
constructor( createElement: ( tandem: Tandem, a: A ) => T, defaultArguments: [ A ] | ( () => [ A ] ), options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B ) => T, defaultArguments: [ A, B ] | ( () => [ A, B ] ), options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B, c: C ) => T, defaultArguments: [ A, B, C ] | ( () => [ A, B, C ] ), options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B, c: C, d: D ) => T, defaultArguments: [ A, B, C, D ] | ( () => [ A, B, C, D ] ), options: any );
constructor( createElement: ( tandem: Tandem, a: A, b: B, c: C, d: D, e: E ) => T, defaultArguments: [ A, B, C, D, E ] | ( () => [ A, B, C, D, E ] ), options: any );

/**
* @param {function(Tandem,...):PhetioObject} createElement - function that creates a dynamic element to be housed in
* this container. All of this dynamic element container's elements will be created from this function, including the
Expand All @@ -52,7 +45,7 @@ class PhetioGroup<T extends PhetioObject, A = never, B = never, C = never, D = n
* defaults array, you should pass an empty object here anyways.
* @param {Object} [options] - describe the Group itself
*/
constructor( createElement: any, defaultArguments: any, options?: any ) {
constructor( createElement: ( t: Tandem, ...p: P ) => T, defaultArguments: P | ( () => P ), options?: any ) {

options = merge( {
tandem: Tandem.OPTIONAL,
Expand Down Expand Up @@ -225,7 +218,7 @@ class PhetioGroup<T extends PhetioObject, A = never, B = never, C = never, D = n
* @param argsForCreateFunction - args to be passed to the create function, specified there are in the IO Type
* `stateToArgsForConstructor` method
*/
createCorrespondingGroupElement( tandemName: string, ...argsForCreateFunction: any[] ) {
createCorrespondingGroupElement( tandemName: string, ...argsForCreateFunction: P ) {

// @ts-ignore
const index = window.phetio.PhetioIDUtils.getGroupElementIndex( tandemName );
Expand All @@ -243,7 +236,7 @@ class PhetioGroup<T extends PhetioObject, A = never, B = never, C = never, D = n
* @param argsForCreateFunction - args to be passed to the create function, specified there are in the IO Type
* `stateToArgsForConstructor` method
*/
createNextElement( ...argsForCreateFunction: any[] ): T {
createNextElement( ...argsForCreateFunction: P ): T {
return this.createIndexedElement( this.groupElementIndex++, argsForCreateFunction );
}

Expand All @@ -260,7 +253,7 @@ class PhetioGroup<T extends PhetioObject, A = never, B = never, C = never, D = n
* @param [fromStateSetting] - Used for validation during state setting. See PhetioDynamicElementContainer.disposeElement() for documentation
* @public (PhetioGroupIO)
*/
createIndexedElement( index: number, argsForCreateFunction: any[], fromStateSetting = false ): T {
createIndexedElement( index: number, argsForCreateFunction: P, fromStateSetting = false ): T {
assert && Tandem.VALIDATION && assert( this.isPhetioInstrumented(), 'TODO: support uninstrumented PhetioGroups? see https://github.com/phetsims/tandem/issues/184' );

assert && this.supportsDynamicState && _.hasIn( window, 'phet.joist.sim' ) &&
Expand Down

0 comments on commit 7d75309

Please sign in to comment.