phetsims / energy-skate-park-basics

"Energy Skate Park: Basics" is an educational simulation in HTML5, by PhET Interactive Simulations.
http://phet.colorado.edu/en/simulation/energy-skate-park-basics
GNU General Public License v3.0
2 stars 9 forks source link

PhET-iO wrapper issue on Bayes CT: Changed state should now have one item in it. #452

Closed samreid closed 4 years ago

samreid commented 5 years ago

Bayes CT has been showing this issue for a while:

SimTests: energy-skate-park: iframe api failed:
Changed state should now have one item in it.
    at Object.callback (https://bayes.colorado.edu/continuous-testing/snapshot-1546216654533/phet-io-wrappers/js/tests/SimTests.js?bust=1546218925354:156:24)
    at dispatch (https://bayes.colorado.edu/continuous-testing/snapshot-1546216654533/phet-io-wrappers/common/js/Client.js:311:83)
    at windowMessageListener (https://bayes.colorado.edu/continuous-testing/snapshot-1546216654533/phet-io-wrappers/common/js/Client.js:348:15)

@zepumph can you please investigate?

zepumph commented 5 years ago

@samreid and I dove into this today. We found that there were two issues with this sim (and others) regarding PhET-iO:

  1. First is that ObservableArrayIO didn't clearly differentiate between serializing its values as references or values. This was remedied by adding an option to the already parametric type. Now serializing OberservaleArray can be more explicit.

  2. In recent state related changes to phetioEngine from https://github.com/phetsims/phet-io/issues/1420 there was a bug. When setting the state on a sim with dynamic instances (such that there were instances with the clearChildInstances method, you could call PhetioEngineIO.setStateFromObject (which may only set one or two items), but would still clear out all child instances. To fix this, take this line of old code:


      // Clear state from any containers that already exist
      for ( const key in this.phetioObjectMap ) {
        const wrapperType = this.getType( key );
        wrapperType.clearChildInstances && wrapperType.clearChildInstances( this.getInstance( key ) );
      }

Instead of iterating through all keys of the phetioObjectMap, I converted it to:

      // Clear state from any containers that already exist, only do so based on the state we are setting, not the whole
      // state, build into this iteration is the assumption that if you are setting the state on an instance that has
      // `clearChildInstances`, then you are also setting the state on the appropriate children that get cleared, see https://github.com/phetsims/energy-skate-park-basics/issues/452
      for ( const key in state ) {
        const wrapperType = this.getType( key );
        wrapperType && wrapperType.clearChildInstances && wrapperType.clearChildInstances( this.getInstance( key ) );
      }

which only looks at the keys from the state argument. Note that it is hard to do a complete and thorough regression test, since the state wrapper is broken in 3+ other sims regardless of these changes. (this is what we are trying to fix currently). No matter I feel like this is safe for master for now. I'm going to add the blocks publication label to https://github.com/phetsims/phet-io/issues/1420 so that we can sort all of this out thoroughly without bugs slipping though.

I'm going to commit the changes we currently have here, and I hope that @samreid can inspect them to see if we are in dangerous waters.

zepumph commented 5 years ago

Oh I should note another issue that we solved in the above commit. Now that we are gathering initialState, we have a better way to keep track of "out of place" properties that change after construction into their "initial state". Skater.headPositionProperty is an example of this, so we adapted it to initialize to the correct value on creation with a bit of refactoring. I hope soon to write a unit test to make sure that the "initialState" doesn't change between construction and a few seconds afterwards even with no fuzzing.

zepumph commented 4 years ago

I don't see any other work to be done in this issue. Closing