Refactor Linux, Windows, and Wasm platforms to use FnMut for callbacks, and bump version.

This commit is contained in:
Nolan Darilek 2020-09-25 11:08:19 -05:00
parent 2c70f77a15
commit 1f22843086
6 changed files with 40 additions and 30 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "tts"
version = "0.7.0"
version = "0.8.0"
authors = ["Nolan Darilek <nolan@thewordnerd.info>"]
repository = "https://github.com/ndarilek/tts-rs"
description = "High-level Text-To-Speech (TTS) interface"
@ -25,7 +25,7 @@ winrt = "0.7"
tts_winrt_bindings = { version = "0.1", path="winrt_bindings" }
[target.'cfg(target_os = "linux")'.dependencies]
speech-dispatcher = "0.6"
speech-dispatcher = "0.7"
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
cocoa-foundation = "0.1"

View File

@ -17,12 +17,12 @@ fn main() -> Result<(), Error> {
..
} = tts.supported_features();
if utterance_callbacks {
tts.on_utterance_begin(Some(|utterance| {
tts.on_utterance_begin(Some(Box::new(|utterance| {
println!("Started speaking {:?}", utterance)
}))?;
tts.on_utterance_end(Some(|utterance| {
})))?;
tts.on_utterance_end(Some(Box::new(|utterance| {
println!("Finished speaking {:?}", utterance)
}))?;
})))?;
}
tts.speak("Hello, world.", false)?;
let Features { rate, .. } = tts.supported_features();

View File

@ -28,22 +28,22 @@ impl SpeechDispatcher {
sd.0.on_begin(Some(|msg_id, client_id| {
let mut speaking = SPEAKING.lock().unwrap();
speaking.insert(client_id, true);
let callbacks = CALLBACKS.lock().unwrap();
let mut callbacks = CALLBACKS.lock().unwrap();
let backend_id = BackendId::SpeechDispatcher(client_id);
let cb = callbacks.get(&backend_id).unwrap();
let cb = callbacks.get_mut(&backend_id).unwrap();
let utterance_id = UtteranceId::SpeechDispatcher(msg_id);
if let Some(f) = cb.utterance_begin {
if let Some(f) = cb.utterance_begin.as_mut() {
f(utterance_id);
}
}));
sd.0.on_end(Some(|msg_id, client_id| {
let mut speaking = SPEAKING.lock().unwrap();
speaking.insert(client_id, false);
let callbacks = CALLBACKS.lock().unwrap();
let mut callbacks = CALLBACKS.lock().unwrap();
let backend_id = BackendId::SpeechDispatcher(client_id);
let cb = callbacks.get(&backend_id).unwrap();
let cb = callbacks.get_mut(&backend_id).unwrap();
let utterance_id = UtteranceId::SpeechDispatcher(msg_id);
if let Some(f) = cb.utterance_end {
if let Some(f) = cb.utterance_end.as_mut() {
f(utterance_id);
}
}));

View File

@ -60,18 +60,18 @@ impl Backend for Web {
let id = self.id().unwrap();
let utterance_id = UtteranceId::Web(utterance.clone());
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisEvent| {
let callbacks = CALLBACKS.lock().unwrap();
let callback = callbacks.get(&id).unwrap();
if let Some(f) = callback.utterance_begin {
let mut callbacks = CALLBACKS.lock().unwrap();
let callback = callbacks.get_mut(&id).unwrap();
if let Some(f) = callback.utterance_begin.as_mut() {
let utterance_id = UtteranceId::Web(evt.utterance());
f(utterance_id);
}
}) as Box<dyn Fn(_)>);
utterance.set_onstart(Some(callback.as_ref().unchecked_ref()));
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisEvent| {
let callbacks = CALLBACKS.lock().unwrap();
let callback = callbacks.get(&id).unwrap();
if let Some(f) = callback.utterance_end {
let mut callbacks = CALLBACKS.lock().unwrap();
let callback = callbacks.get_mut(&id).unwrap();
if let Some(f) = callback.utterance_end.as_mut() {
let utterance_id = UtteranceId::Web(evt.utterance());
f(utterance_id);
}

View File

@ -83,9 +83,9 @@ impl WinRT {
let id = backend_to_media_player.iter().find(|v| v.1 == sender);
if let Some(id) = id {
let id = id.0;
let callbacks = CALLBACKS.lock().unwrap();
let callbacks = callbacks.get(&id).unwrap();
if let Some(callback) = callbacks.utterance_end {
let mut callbacks = CALLBACKS.lock().unwrap();
let callbacks = callbacks.get_mut(&id).unwrap();
if let Some(callback) = callbacks.utterance_end.as_mut() {
let last_spoken_utterance = LAST_SPOKEN_UTTERANCE.lock().unwrap();
if let Some(utterance_id) = last_spoken_utterance.get(&id) {
callback(utterance_id.clone());
@ -103,20 +103,20 @@ impl WinRT {
let id = backend_to_playback_list.iter().find(|v| v.1 == sender);
if let Some(id) = id {
let id = id.0;
let callbacks = CALLBACKS.lock().unwrap();
let callbacks = callbacks.get(&id).unwrap();
let mut callbacks = CALLBACKS.lock().unwrap();
let callbacks = callbacks.get_mut(&id).unwrap();
let old_item = args.old_item()?;
if !old_item.is_null() {
if let Some(callback) = callbacks.utterance_end {
if let Some(callback) = callbacks.utterance_end.as_mut() {
callback(UtteranceId::WinRT(old_item));
}
}
let new_item = args.new_item()?;
if !new_item.is_null() {
let utterance_id = UtteranceId::WinRT(new_item);
let mut last_spoken_utterance = LAST_SPOKEN_UTTERANCE.lock().unwrap();
let utterance_id = UtteranceId::WinRT(new_item);
last_spoken_utterance.insert(*id, utterance_id.clone());
if let Some(callback) = callbacks.utterance_begin {
if let Some(callback) = callbacks.utterance_begin.as_mut() {
callback(utterance_id);
}
}

View File

@ -137,10 +137,14 @@ pub trait Backend {
#[derive(Default)]
struct Callbacks {
utterance_begin: Option<fn(UtteranceId)>,
utterance_end: Option<fn(UtteranceId)>,
utterance_begin: Option<Box<dyn FnMut(UtteranceId)>>,
utterance_end: Option<Box<dyn FnMut(UtteranceId)>>,
}
unsafe impl Send for Callbacks {}
unsafe impl Sync for Callbacks {}
lazy_static! {
static ref CALLBACKS: Mutex<HashMap<BackendId, Callbacks>> = {
let m: HashMap<BackendId, Callbacks> = HashMap::new();
@ -436,7 +440,10 @@ impl TTS {
/**
* Called when this speech synthesizer begins speaking an utterance.
*/
pub fn on_utterance_begin(&self, callback: Option<fn(UtteranceId)>) -> Result<(), Error> {
pub fn on_utterance_begin(
&self,
callback: Option<Box<dyn FnMut(UtteranceId)>>,
) -> Result<(), Error> {
let Features {
utterance_callbacks,
..
@ -455,7 +462,10 @@ impl TTS {
/**
* Called when this speech synthesizer finishes speaking an utterance.
*/
pub fn on_utterance_end(&self, callback: Option<fn(UtteranceId)>) -> Result<(), Error> {
pub fn on_utterance_end(
&self,
callback: Option<Box<dyn FnMut(UtteranceId)>>,
) -> Result<(), Error> {
let Features {
utterance_callbacks,
..