Closed marlitas closed 2 weeks ago
Very nice summary @marlitas. Reminder to add a comment that links to this issue when you revert to making rightAddendNumberProperty
the derived Property. And again, apologies for sending you down this path. But I think we both ended up with a better understanding of the implementation requirements for the Sum screen.
@pixelzoom I dug into the model questions again specifically related to the number spinners and came up with the below patch.... Let me know what you think. Also curious about what you've been thinking about as well.
... Also curious about what you've been thinking about as well.
Sorry, I've been totally consumed with change requests for https://github.com/phetsims/models-of-the-hydrogen-atom/issues/67#issuecomment-2415033501. I'll try to spend some time and review the patch during Thursday meetings.
I just looked through your patch in https://github.com/phetsims/number-pairs/issues/17#issuecomment-2415505787. I think I have the general idea. And I had forgotten about the additional problem of range for NumberSpinner. This makes me more convinced that we should abandon NumberSpinner, and investigate what I described in standup — write our own UI component that consists of and icon + up/down arrows, and takes listeners for the up/down arrows.
Also noting that NumberSpinner is not particularly usable for this age group. The arrow buttons are too small. Something more like NumberPicker's UI would be more appropriate, with big arrow buttons. We have the real estate for this. And I don't think consistency with the other sims in this suite should be the main consideration.
For example... Here's a more age-appropriate UI component, from fraction-comparison:
@marlitas and I discussed this on Zoom.
Problems with using NumberSpinner:
cleverNumberProperty
).cleverNumberProperty
, which is not what we want.cleverNumberProperty
is not really what's relevant for the spinner.So while what we need can be thought of as a type of spinner, it's not Property-related, and not number-related. What we want to do is perform an action when the buttons are pressed. For the "left" spinner, something like:
incrementButtonListener: () => {
leftAddendProperty.value++;
totalProperty.value++;
},
decrementButtonListener: () => {
leftAddendProperty.value--;
totalProperty.value--;
}
For the "right" spinner, something like:
incrementButtonListener: () => {
totalProperty.value++;
},
decrementButtonListener: () => {
totalProperty.value--;
}
And for PhET-iO, we'd like to link the "left" spinner to leftAddendProperty
, and the "right" spinner to rightAddendProperty
.
Extending AccessibleNumberSpinner does not feel appropriate, because (again) we don't really have a NumberProperty. Yes we would get alt input behavior, but we'd get incorrect state description behavior. And not sure about context response behavior.
So... @marlitas is going to put together a quick-and-dirty UI component that consists of an icon (kitty, cube,...) and 2 arrow buttons, with an API for adding listeners to the buttons and providing enabledProperty for the buttons. Then we can evaluate whether this is a good path, and what features we'll need to add.
I added the new component above. I decided to name it CountingObjectControl, but I never feel confident about naming so happy to change it.
I believe this is the right way to go. It has simplified the model and is currently working with little to no elbow grease. I am running into assertions now and then, but these feel like edge cases we should address rather than foundational issues. Overall I think we have finally found the proper approach in the sim's model architecture.
I would like to discuss the below edge case issues with @pixelzoom to confirm that they are not a deal breaker for the overall implementation we have now.
@marlitas and I met about the edge cases described in https://github.com/phetsims/number-pairs/issues/17#issuecomment-2427514742.
- In the sum screen, when our total is maxed out (ie. 20) moving the numberline slider causes an assertion. ...
Two ideas: (1) When inactiveCountingObjects is empty, get the counting object from the array for the other addend. (2) Populate inactiveCountingObjects with 1 extra object. We prefer (1) because (2) seems clever and will be visible in PhET-iO.
- In all screens with a number line slider, moving the slider quickly back and forth lands the sim in a weird state ...
We suspect that this occurs when the distance that the slider thumb moves results in more than 1 object being added/removed from a ObservableArray
If this doesn't resolve the problem, consult with SR/MK on whether there might be a Timer deferring something to the next animation frame that causes things to get out of order when the thumb is moved rapidly.
I'm waiting until CT is back up and running to close this issue.
The model seems to be working well after weeks of working in it. CT is still not 100% clear, but I don't believe the errors are an indication of issues with the architecture. I believe we can close now.
After implementing recommendations from the code review in https://github.com/phetsims/number-pairs/issues/9 @pixelzoom and I noticed that the code was starting to become overly complex, and we were hitting reentrancy issues non-stop. This is specifically related to the following comment: https://github.com/phetsims/number-pairs/issues/9#issuecomment-2383771833
Although having the
totalNumberProperty
be derived more closely matches the UI experience users are having, it created havoc in the form of multiple proxy Properties, code comments issuing warnings, and non stop buggy interactions. The root cause of this lies in the Number Line Slider's dual behavior when interacting directly with the Slider, and when interacting with the number spinners on the right hand side.Required Slider Behavior:
Required Number Spinner Behavior:
By forcing a derived totalNumberProperty to cover the above requirements, along with the necessary model interface of ObservableArrays, reentrancy problems quickly become a blocker. One such reentrancy issue that commonly came up in the Cube Representation can be described below:
This is only one such example of reentrancy. We also hit similar problems that were triggered by the enabledPropertyRange for the Slider, Number Spinners, amongst others.
After discussing with @pixelzoom we determined that the increased complexity of the code, added effort to develop, maintain, and scale did not outweigh the benefit of having the implementation directly match the UI. This provides the largest hurdle in studio, but at best can be disguised with a bidirectional DynamicProperty that acts as a proxy, and at worst addressed via documentation in both studio and examples.md
Therefore we have decided to move forward with the following strategy:
This removes reentrancy issues, simplifies the relationship between NumberProperties and the ObservableArrays, and unites the implementation around most of the screens and representations.