-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IO Type factory based on methods from the core type? #188
Comments
It seems like we should coordinate this work with the other IO type work proposed in https://github.com/phetsims/phet-io/issues/1657#issuecomment-646735445 Do we need an IO type label? Unassigning and adding to Wednesday agenda. |
In https://github.com/phetsims/phet-io/issues/1683#issuecomment-646229929 @pixelzoom said:
|
Here's a patch that introduces a new function createIOType( Bunny, 'BunnyIO', 'IO Type for Bunny', {} ) All validation & forwarding is set up automatically. If there are any methods, they can be supplied in the options. Additionally, if we declare it within the during the declaration for Bunny.js, we can have direct type checks without using the namespace and without any circular module loading problems:
I'd like to get feedback from @pixelzoom and/or @zepumph before moving more in this direction, but it looks promising to me. Index: main/natural-selection/js/common/model/BunnyIO.js
===================================================================
--- main/natural-selection/js/common/model/BunnyIO.js (revision 9bb444d45c9657de620916ab4162c9874ce1c973)
+++ main/natural-selection/js/common/model/BunnyIO.js (revision 9bb444d45c9657de620916ab4162c9874ce1c973)
@@ -1,58 +0,0 @@
-// Copyright 2020, University of Colorado Boulder
-
-/**
- * BunnyIO is the IO Type for Bunny. It delegates most of its implementation to Bunny.
- *
- * @author Chris Malley (PixelZoom, Inc.)
- */
-
-import validate from '../../../../axon/js/validate.js';
-import ObjectIO from '../../../../tandem/js/types/ObjectIO.js';
-import naturalSelection from '../../naturalSelection.js';
-import Bunny from './Bunny.js';
-
-class BunnyIO extends ObjectIO {
-
- /**
- * Serializes a Bunny instance.
- * @param {Bunny} bunny
- * @returns {Object}
- * @public
- * @override
- */
- static toStateObject( bunny ) {
- validate( bunny, this.validator );
- return bunny.toStateObject();
- }
-
- /**
- * Creates the args to BunnyGroup.createNextElement that creates Bunny instances.
- * @param state
- * @returns {Object[]}
- * @public
- * @override
- */
- static stateToArgsForConstructor( state ) {
- return Bunny.stateToArgsForConstructor( state );
- }
-
- /**
- * Restores Bunny state after instantiation.
- * @param {Bunny} bunny
- * @param {Object} state
- * @public
- * @override
- */
- static applyState( bunny, state ) {
- validate( bunny, this.validator );
- bunny.applyState( state );
- }
-}
-
-BunnyIO.documentation = 'IO Type for Bunny';
-BunnyIO.validator = { isValidValue: value => value instanceof Bunny };
-BunnyIO.typeName = 'BunnyIO';
-ObjectIO.validateSubtype( BunnyIO );
-
-naturalSelection.register( 'BunnyIO', BunnyIO );
-export default BunnyIO;
\ No newline at end of file
Index: main/natural-selection/js/common/model/BunnyGroup.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- main/natural-selection/js/common/model/BunnyGroup.js (revision 9bb444d45c9657de620916ab4162c9874ce1c973)
+++ main/natural-selection/js/common/model/BunnyGroup.js (date 1598296691115)
@@ -15,7 +15,7 @@
import Tandem from '../../../../tandem/js/Tandem.js';
import naturalSelection from '../../naturalSelection.js';
import Bunny from './Bunny.js';
-import BunnyIO from './BunnyIO.js';
+// import BunnyIO from './BunnyIO.js';
import EnvironmentModelViewTransform from './EnvironmentModelViewTransform.js';
import GenePool from './GenePool.js';
@@ -37,7 +37,7 @@
// phet-io
tandem: Tandem.REQUIRED,
- phetioType: PhetioGroupIO( BunnyIO ),
+ phetioType: PhetioGroupIO( Bunny.BunnyIO ),
phetioDocumentation: 'manages dynamic PhET-iO elements of type Bunny, including live and dead bunnies'
}, options );
Index: main/natural-selection/js/common/model/BunnyArray.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- main/natural-selection/js/common/model/BunnyArray.js (revision 9bb444d45c9657de620916ab4162c9874ce1c973)
+++ main/natural-selection/js/common/model/BunnyArray.js (date 1598297648845)
@@ -13,9 +13,9 @@
import Tandem from '../../../../tandem/js/Tandem.js';
import ReferenceIO from '../../../../tandem/js/types/ReferenceIO.js';
import naturalSelection from '../../naturalSelection.js';
+import Bunny from './Bunny.js';
import BunnyCounts from './BunnyCounts.js';
import BunnyCountsIO from './BunnyCountsIO.js';
-import BunnyIO from './BunnyIO.js';
class BunnyArray extends AxonArray {
@@ -34,7 +34,7 @@
// phet-io
tandem: Tandem.REQUIRED,
- phetioElementType: ReferenceIO( BunnyIO ),
+ phetioElementType: ReferenceIO( Bunny.BunnyIO ),
phetioState: false
}, options );
Index: main/natural-selection/js/common/model/Bunny.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- main/natural-selection/js/common/model/Bunny.js (revision 9bb444d45c9657de620916ab4162c9874ce1c973)
+++ main/natural-selection/js/common/model/Bunny.js (date 1598296717518)
@@ -17,12 +17,12 @@
import AssertUtils from '../../../../phetcommon/js/AssertUtils.js';
import Tandem from '../../../../tandem/js/Tandem.js';
import BooleanIO from '../../../../tandem/js/types/BooleanIO.js';
+import createIOType from '../../../../tandem/js/types/createIOType.js';
import NullableIO from '../../../../tandem/js/types/NullableIO.js';
import NumberIO from '../../../../tandem/js/types/NumberIO.js';
import ReferenceIO from '../../../../tandem/js/types/ReferenceIO.js';
import naturalSelection from '../../naturalSelection.js';
import NaturalSelectionUtils from '../NaturalSelectionUtils.js';
-import BunnyIO from './BunnyIO.js';
import EnvironmentModelViewTransform from './EnvironmentModelViewTransform.js';
import GenePool from './GenePool.js';
import Genotype from './Genotype.js';
@@ -48,6 +48,8 @@
*/
constructor( genePool, modelViewTransform, bunnyRestRangeProperty, options ) {
+ console.log( Bunny );
+
assert && assert( genePool instanceof GenePool, 'invalid genePool' );
assert && assert( modelViewTransform instanceof EnvironmentModelViewTransform, 'invalid modelViewTransform' );
assert && AssertUtils.assertPropertyOf( bunnyRestRangeProperty, Range );
@@ -431,5 +433,8 @@
return new Vector3( dx, dy, dz );
}
+const BunnyIO = createIOType( Bunny, 'BunnyIO', 'IO Type for Bunny', {} );
+Bunny.BunnyIO = BunnyIO;
+
naturalSelection.register( 'Bunny', Bunny );
export default Bunny;
\ No newline at end of file
Index: main/tandem/js/types/createIOType.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- main/tandem/js/types/createIOType.js (date 1598297605863)
+++ main/tandem/js/types/createIOType.js (date 1598297605863)
@@ -0,0 +1,61 @@
+// Copyright 2020, University of Colorado Boulder
+
+import validate from '../../../axon/js/validate.js';
+import tandemNamespace from '../tandemNamespace.js';
+import ObjectIO from './ObjectIO.js';
+
+const createIOType = ( CoreType, typeName, documentation, options ) => {
+ class IOType extends ObjectIO {
+
+ /**
+ * @param {PhetioObject} phetioObject
+ * @returns {Object}
+ * @public
+ * @override
+ */
+ static toStateObject( phetioObject ) {
+ validate( phetioObject, this.validator );
+ return phetioObject.toStateObject();
+ }
+
+ // @public
+ static fromStateObject( stateObject ) {
+ return CoreType.fromStateObject( stateObject );
+ }
+
+ /**
+ * @param state
+ * @returns {Object[]}
+ * @public
+ * @override
+ */
+ static stateToArgsForConstructor( state ) {
+ return CoreType.stateToArgsForConstructor( state );
+ }
+
+ /**
+ * Restores CoreType state after instantiation.
+ * @param {PhetioObject} phetioObject
+ * @param {Object} state
+ * @public
+ * @override
+ */
+ static applyState( phetioObject, state ) {
+ validate( phetioObject, this.validator );
+ phetioObject.applyState( state );
+ }
+ }
+
+ IOType.documentation = documentation;
+ IOType.validator = { valueType: CoreType };
+ IOType.typeName = typeName;
+ if ( options.methods ) {
+ IOType.methods = options.methods;
+ }
+ ObjectIO.validateSubtype( IOType );
+
+ return IOType;
+};
+
+tandemNamespace.register( 'createIOType', createIOType );
+export default createIOType;
\ No newline at end of file
Index: main/natural-selection/js/common/model/SelectedBunnyProperty.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- main/natural-selection/js/common/model/SelectedBunnyProperty.js (revision 9bb444d45c9657de620916ab4162c9874ce1c973)
+++ main/natural-selection/js/common/model/SelectedBunnyProperty.js (date 1598296691109)
@@ -14,7 +14,7 @@
import NullableIO from '../../../../tandem/js/types/NullableIO.js';
import ReferenceIO from '../../../../tandem/js/types/ReferenceIO.js';
import naturalSelection from '../../naturalSelection.js';
-import BunnyIO from './BunnyIO.js';
+import Bunny from './Bunny.js';
class SelectedBunnyProperty extends Property {
@@ -30,7 +30,7 @@
// phet-io
tandem: Tandem.REQUIRED,
- phetioType: PropertyIO( NullableIO( ReferenceIO( BunnyIO ) ) ),
+ phetioType: PropertyIO( NullableIO( ReferenceIO( Bunny.BunnyIO ) ) ),
phetioDocumentation: 'the selected bunny, null if no bunny is selected'
}, options );
|
I couldn't apply the patch to natural-selection master HEAD for some reason, lots of merge conflicts. But I inspected the code and I like this direction. A few suggestions RE
|
I addressed the review comments and committed PhetioObject.createIOType. One recommendation I did not complete is:
The This was far enough along that I was comfortable committing it, but one deficiency that will need to be addressed, is that several times in the PhET-iO engine it checks the existence of a method to decide what to do. In this commit, every IO type provides an implementation for all methods, like
UPDATE: Also reassigning @pixelzoom in case he wants to review the parts I addressed. UPDATE 2: I'd like to check in with @zepumph about the bullet points above, unassigning for now. |
This is looking good. Can we move I don't fully understand the implications of the remaining phetioEngine "deficiency". Is there a performance impact? |
Thanks, I moved
There are several places where we check the existence of a method to determine how to proceed. For instance, phetioCommandProcessor.js // Serialize the result if possible.
return methodSignature.returnType.toStateObject ?
methodSignature.returnType.toStateObject( result ) :
result; With I think we should move toward a pattern where |
Beginning of review:
|
This reverts commit 56a9c22
…ype, see phetsims/tandem#188" This reverts commit 27fded7
I reverted usages of Summarizing results from this issue:
class BunnyIO extends ObjectIO {
/**
* Serializes a Bunny instance.
* @param {Bunny} bunny
* @returns {Object}
* @public
* @override
*/
static toStateObject( bunny ) {
validate( bunny, this.validator );
return bunny.toStateObject();
}
/**
* Creates the args to BunnyGroup.createNextElement that creates Bunny instances.
* @param state
* @returns {Object[]}
* @public
* @override
*/
static stateToArgsForConstructor( state ) {
return Bunny.stateToArgsForConstructor( state );
}
/**
* Restores Bunny state after instantiation.
* @param {Bunny} bunny
* @param {Object} state
* @public
* @override
*/
static applyState( bunny, state ) {
validate( bunny, this.validator );
bunny.applyState( state );
}
} This has been compressed to: class BunnyIO extends ObjectIO {
// @public @override
static toStateObject( bunny ) { return bunny.toStateObject(); }
// @public @override
static stateToArgsForConstructor( state ) { return Bunny.stateToArgsForConstructor( state ); }
// @public @override
static applyState( bunny, stateObject ) { bunny.applyState( stateObject ); }
} |
@samreid said:
There's not any real compression here. The compression is due to 3 questionable things in the example:
So the code is essentially identical, and there's really no difference here. Any compression was actually achieved in definition of static fields. For example this: BunnyIO.documentation = 'IO Type for Bunny';
BunnyIO.validator = { isValidValue: value => value instanceof Bunny };
BunnyIO.typeName = 'BunnyIO';
ObjectIO.validateSubtype( BunnyIO ); was replaced with: ObjectIO.setIOTypeFields( BunnyIO, 'BunnyIO', Bunny ); Otherwise the IO Types were just moved to the same .js file as their associated Core Type. And they could just as easily have been left in their own .js files. It's really only necessary to move the IO Type definition into the Core Type .js file if you need to avoid circular references between IO Type and Core Type. EDIT: But I think it improves maintainability by defining the Core Type and IO Type in the same .js file. |
I've written a proposal in #211 (comment) which I think we should pursue. It automatically includes the |
Given the comment over in #211 (comment), this doesn't seem to block publication. @samreid, does this block NS? |
This issue is definitely not blocking for the 10/1 RC deliverable, the subject of phetsims/natural-selection#208. As soon as that RC has been delivered, then this issue will immediately becoming blocking for the next NS milestone (which is production RC). I don't know about the blocking status for other sims. |
Let's put this on hold pending work in #211. |
Some brainstorming in #211 revolved around automatically leveraging |
The latest proposal for this step is in #213, let's close this and continue there. |
Based on patterns that are getting established for IO Types in natural-selection and MultipleParticleModelIO, most of the logic in an IO Type is actually getting defined in the core type, and so IO Types often are mostly boilerplate:
In those cases, it could be nice to have an IO Type factory that can just wrap the core type.
The text was updated successfully, but these errors were encountered: