Closed zepumph closed 2 years ago
Or perhaps a way to bolster Utterance so that its timing variables were a map instead
Yes, that could work well too.
If we make Utterance supportive of multiple queues by creating a map of data, then perhaps the "numberOfTimesAlerted" can also be kept in that data, since it in a general case it would depend on what the specific queue context is to alert. This seems like it could be weird though:
const x = new Utterance( {
alert: [ 1, 2, 3, 4, 5, 6, 7 ]
} );
voicingUtterance.addToBack( x );
// announce 1
descriptionUtterance.addToBack( x );
// announce 1
voicingUtterance.addToBack( x );
// announce 2
descriptionUtterance.addToBack( x );
// announce 2
descriptionUtterance.addToBack( x );
// announce 3
descriptionUtterance.addToBack( x );
// announce 4
descriptionUtterance.addToBack( x );
// announce 5
descriptionUtterance.addToBack( x );
// announce 6
descriptionUtterance.addToBack( x );
// announce 7
voicingUtterance.addToBack( x );
// announce 3
I have a hard time feeling like this isn't overly specific to our case. Perhaps that is alright, because in general people shouldn't use the array alert feature unless they are very knowledgeable about why they need that. Also I feel like once we create a map, it would be pretty easy to create an option that asserts that an Utterance's alert is not changed from the time it enters the queue to the time it exists. That is likely quite important.
Assigning @jessegreenberg for comment.
I am a bit torn between what might be the best API for UtteranceQueue/Utterance and what is best for PhET's usage. https://github.com/phetsims/utterance-queue/issues/20#issuecomment-889881374 could be confusing, but it seems necessary to support putting an Utterance through more than one UtteranceQueue t a time.
I think ideally, Utterance should not be aware of the UtteranceQueue it is in. And creating a Map for Utterance that goes from UtteranceQueue to timing/alert counters/other variables adds complexity. But the current alternative of creating one Utterance per UtteranceQueue would add extra boilerplate for PhET.
Just brainstorming something else, what if we had a manager class for all UtteranceQueues like phetUtteranceQueueManager
with functions like addToBackOfDescriptionUtteranceQueue
, addToBackOfVoicingUtteranceQueue
, addToBackOfAllUtteranceQueues
.
The implementation of addToBackOfAllUtteranceQueues
might look like this (messy, untested, just for discussion):
I dunno, I liked it less as I typed it out. Now we need forwarding functions for each UtteranceQueue in phetUtteranceQueueManager. My hope was we had something more simple in utterance-queue while also having less boilerplate at call sites.
One side note, it seems like the incrementing side effect in getTextToAlert should be instead incremented in UtteranceQueue. That would be good to do no matter the outcome of this issue, but it seems related, so I am tagging a TODO in this issue as I work on https://github.com/phetsims/aqua/issues/127
@jessegreenberg and I discussed, and we like this sort of method, where instead of the queue objects being Utterances, we wrap them in data that is only for that single queue (and really for that single instance of the Utterance added to that queue.
UtteranceQueue.wrapUtterance( utterance ) {
return {
stableTime: 0,
timeInQueue: 0,
utterance: utterance
}
}
I made some good progress on this today, but I had to give up because I ran out of time just when I ran into a mistake I made about if removeUtterance takes an utterance or an utteranceWrapper. Likely I should make two different methods (and only one is public).
I had more luck this morning on this! I split out the removal methods to two different functions, one for utteranceWrapper and one for utterance.
This was a great first step for this issue, and tests are passing. My testing didn't show any differences (50 fuzzing frames of snapshot in molarity all had identical utterances emitted). From here we can work on the alert as an array/loopAlerts/numberOfTimesAlerted stuff.
Progress is looking good! With the movement of resetTimingVariables
this usage in AccessibleValueHandler https://github.com/phetsims/sun/blob/ca4c2fb861e678adc960a84f67b90875eaab3e1c/js/accessibility/AccessibleValueHandler.js#L414 is causing an error. That is the only usage of the function, is it safe to remove? I would think that alertStableDelay
would provide the delay we need each time it is added to back so it shouldn't need to be reset manually. But maybe I don't understand. I am going to remove it for now to suppress the error.
You did just great. Thanks for catching my error @jessegreenberg.
I ran into trouble with an Utterance that has an array as an alert (MovementDescriver.alert()
) when collecting responses for voicing. I think it is time to support this now.
I'm so torn about how to proceed here! I thought I would be ok with only supporting array alerts a single Utterance instance per queue (see patch below). It worked great for BookMovementDescriber, but then I got to BorderAlert.alert() and felt again like we should do a count per utteranceQueue, and support adding an Utterance to any queue, and the cycling will be unique to the queue it is added to (proposal from the snippet in https://github.com/phetsims/utterance-queue/issues/20#issuecomment-889881374).
I will need to come back to this, as I am worried I will make the wrong decision.
Index: js/friction/view/describers/BookMovementDescriber.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/friction/view/describers/BookMovementDescriber.js b/js/friction/view/describers/BookMovementDescriber.js
--- a/js/friction/view/describers/BookMovementDescriber.js (revision ae2f4a941a4c130a4f53323f0b72e4a7fb5656b3)
+++ b/js/friction/view/describers/BookMovementDescriber.js (date 1628728140842)
@@ -63,7 +63,13 @@
this.model = model;
// @private - special verbose alert for the first 2 times, then use the default
- this.bottomUtterance = new Utterance( {
+ this.bottomDescriptionUtterance = new Utterance( {
+ alert: [ downRubFastOrSlowString, downRubFastOrSlowString, DEFAULT_MOVEMENT_DESCRIPTIONS.DOWN ],
+ } );
+
+ // @private - special verbose alert for the first 2 times, then use the default. A separate Utterance is needed to
+ // support array alerts.
+ this.bottomVoicingUtterance = new Utterance( {
alert: [ downRubFastOrSlowString, downRubFastOrSlowString, DEFAULT_MOVEMENT_DESCRIPTIONS.DOWN ],
announcerOptions: {
cancelOther: false
@@ -132,7 +138,8 @@
// if contacted and DOWN, we have a special alert
else if ( this.model.contactProperty.get() && direction === DirectionEnum.DOWN ) {
- this.alert( this.bottomUtterance );
+ this.alert( this.bottomDescriptionUtterance );
+ this.alert( this.bottomVoicingUtterance );
}
// base case
@@ -169,7 +176,8 @@
*/
reset() {
super.reset();
- this.bottomUtterance.reset();
+ this.bottomDescriptionUtterance.reset();
+ this.bottomVoicingUtterance.reset();
this.contactedAlertPair.reset();
this.separatedAlertPair.reset();
}
@jessegreenberg and I discussed the above. Given BorderAlert.alert
and MovementDecriber.alert
, it seems like we should try hard to support 1 Utterance in 2 queues.
Some strategies that were hard for us to think through:
Utterance.perQueueData[utteranceQueue.uniqueID].numberOfTimesAlerted
, the biggest problem for this one was that now Utterance.getAlertText()
would need to have an instance of the utteranceQueue it applies to.UtteranceQueue.everyUtteranceEver[ utterance ].numberOfTimesAlerted
. This seems to have a memory leak, and strips array-supported Utterances from being able to access their own alert value without the UtteranceQueue instance at the ready.Lots has happened since the last time we had this discussion. I think that all usages of array-supported Utterance alerts has been deleted. I recommend that we get rid of that support. I think it will greatly improve the utterance-queue library. I'll touch base with @jessegreenberg on friday about this.
I discussed with @jessegreenberg, and we will remove the array-alert support. In the future if this comes up again, perhaps we can subtype or come up with another solution. Then I'll go over this issue, and mark it for review by @jessegreenberg.
Pinging my dang self on this again. As I hit it in https://github.com/phetsims/sun/issues/742
I will remove the array Utterance alerts in https://github.com/phetsims/utterance-queue/issues/67. @jessegreenberg this issue is now ready for review.
I reviewed the three commits in this issue that took the timing variables out of Utterance and put them in UtteranceWrapper so that Utterances can be in multiple queues at once. Changes make sense to me and this has been working well for us for some time.
I reviewed the other instance variables of Utterance and it still seems like all work if in multiple queues.
Only thing I spotted was an option that has since been removed from removeUtterance
called assertExists
, I removed its usage from MolarityAlertManager.
Otherwise I think this can be closed, thanks for making these improvements @zepumph!
Excellent! Thanks
Discovered while problem solving for https://github.com/phetsims/friction/issues/204 with @jessegreenberg. Basically this is how we wanted our voicing response + description alert pattern to be:
Here are all the reasons why this doesn't work. In general it is because Utterance stores data from being in the queue, and based on how many times it has been sent through a queue.
stableTime
andtimeInQueue
)There may be more!!
Thus, we decided that we should add in an assertion to Utterance that it is only added to a single UtteranceQueue at a time. This will most likely need a fair number of usage changes (for sims supporting voicing).
@jessegreenberg, another though here, could we prototype a subtype of Utterance that would support multiple queues? Or perhaps a way to bolster Utterance so that its timing variables were a map instead. I think if each utteranceQueue had a unique identifier, then it would be pretty easy to support. I'm not ready to implement anything here yet, I'm going to think about it and implement next week.