Implement utterance_stop callback on most platforms.

This commit is contained in:
Nolan Darilek 2020-10-08 07:56:45 -05:00
parent 174011bbb4
commit 8c783205c3
5 changed files with 48 additions and 4 deletions

View File

@ -34,4 +34,4 @@ objc = "0.2"
[target.wasm32-unknown-unknown.dependencies]
wasm-bindgen = "0.2"
web-sys = { version = "0.3", features = ["EventTarget", "SpeechSynthesis", "SpeechSynthesisEvent", "SpeechSynthesisUtterance", "Window", ] }
web-sys = { version = "0.3", features = ["EventTarget", "SpeechSynthesis", "SpeechSynthesisErrorCode", "SpeechSynthesisErrorEvent", "SpeechSynthesisEvent", "SpeechSynthesisUtterance", "Window", ] }

View File

@ -46,9 +46,16 @@ impl SpeechDispatcher {
f(utterance_id);
}
})));
sd.0.on_cancel(Some(Box::new(|_msg_id, client_id| {
sd.0.on_cancel(Some(Box::new(|msg_id, client_id| {
let mut speaking = SPEAKING.lock().unwrap();
speaking.insert(client_id, false);
let mut callbacks = CALLBACKS.lock().unwrap();
let backend_id = BackendId::SpeechDispatcher(client_id);
let cb = callbacks.get_mut(&backend_id).unwrap();
let utterance_id = UtteranceId::SpeechDispatcher(msg_id);
if let Some(f) = cb.utterance_stop.as_mut() {
f(utterance_id);
}
})));
sd.0.on_pause(Some(Box::new(|_msg_id, client_id| {
let mut speaking = SPEAKING.lock().unwrap();

View File

@ -5,7 +5,10 @@ use lazy_static::lazy_static;
use log::{info, trace};
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::{SpeechSynthesisEvent, SpeechSynthesisUtterance};
use web_sys::{
SpeechSynthesisErrorCode, SpeechSynthesisErrorEvent, SpeechSynthesisEvent,
SpeechSynthesisUtterance,
};
use crate::{Backend, BackendId, Error, Features, UtteranceId, CALLBACKS};
@ -85,6 +88,18 @@ impl Backend for Web {
mappings.retain(|v| v.1 != utterance_id);
}) as Box<dyn Fn(_)>);
utterance.set_onend(Some(callback.as_ref().unchecked_ref()));
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisErrorEvent| {
if evt.error() == SpeechSynthesisErrorCode::Cancel {
let mut callbacks = CALLBACKS.lock().unwrap();
let callback = callbacks.get_mut(&id).unwrap();
if let Some(f) = callback.utterance_stop.as_mut() {
f(utterance_id);
}
}
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
mappings.retain(|v| v.1 != utterance_id);
}) as Box<dyn Fn(_)>);
utterance.set_onerror(Some(callback.as_ref().unchecked_ref()));
if interrupt {
self.stop()?;
}

View File

@ -76,7 +76,7 @@ impl WinRT {
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
let mut callbacks = CALLBACKS.lock().unwrap();
let callbacks = callbacks.get_mut(&self.id).unwrap();
if let Some(callback) = callbacks.utterance_end.as_mut() {
if let Some(callback) = callbacks.utterance_stop.as_mut() {
let mappings = UTTERANCE_MAPPINGS.lock().unwrap();
for mapping in &*mappings {
callback(mapping.2);

View File

@ -134,6 +134,7 @@ pub trait Backend {
struct Callbacks {
utterance_begin: Option<Box<dyn FnMut(UtteranceId)>>,
utterance_end: Option<Box<dyn FnMut(UtteranceId)>>,
utterance_stop: Option<Box<dyn FnMut(UtteranceId)>>,
}
unsafe impl Send for Callbacks {}
@ -474,6 +475,27 @@ impl TTS {
Err(Error::UnsupportedFeature)
}
}
/**
* Called when this speech synthesizer is stopped and still has utterances in its queue.
*/
pub fn on_utterance_stop(
&self,
callback: Option<Box<dyn FnMut(UtteranceId)>>,
) -> Result<(), Error> {
let Features {
utterance_callbacks,
..
} = self.supported_features();
if utterance_callbacks {
let mut callbacks = CALLBACKS.lock().unwrap();
let id = self.0.id().unwrap();
let mut callbacks = callbacks.get_mut(&id).unwrap();
callbacks.utterance_stop = callback;
Ok(())
} else {
Err(Error::UnsupportedFeature)
}
}
}
impl Drop for TTS {