mirror of https://github.com/ndarilek/tts-rs.git
Refactor Linux, Windows, and Wasm platforms to use FnMut for callbacks, and bump version.
This commit is contained in:
parent
2c70f77a15
commit
1f22843086
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tts"
|
name = "tts"
|
||||||
version = "0.7.0"
|
version = "0.8.0"
|
||||||
authors = ["Nolan Darilek <nolan@thewordnerd.info>"]
|
authors = ["Nolan Darilek <nolan@thewordnerd.info>"]
|
||||||
repository = "https://github.com/ndarilek/tts-rs"
|
repository = "https://github.com/ndarilek/tts-rs"
|
||||||
description = "High-level Text-To-Speech (TTS) interface"
|
description = "High-level Text-To-Speech (TTS) interface"
|
||||||
|
@ -25,7 +25,7 @@ winrt = "0.7"
|
||||||
tts_winrt_bindings = { version = "0.1", path="winrt_bindings" }
|
tts_winrt_bindings = { version = "0.1", path="winrt_bindings" }
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
speech-dispatcher = "0.6"
|
speech-dispatcher = "0.7"
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
|
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
|
||||||
cocoa-foundation = "0.1"
|
cocoa-foundation = "0.1"
|
||||||
|
|
|
@ -17,12 +17,12 @@ fn main() -> Result<(), Error> {
|
||||||
..
|
..
|
||||||
} = tts.supported_features();
|
} = tts.supported_features();
|
||||||
if utterance_callbacks {
|
if utterance_callbacks {
|
||||||
tts.on_utterance_begin(Some(|utterance| {
|
tts.on_utterance_begin(Some(Box::new(|utterance| {
|
||||||
println!("Started speaking {:?}", utterance)
|
println!("Started speaking {:?}", utterance)
|
||||||
}))?;
|
})))?;
|
||||||
tts.on_utterance_end(Some(|utterance| {
|
tts.on_utterance_end(Some(Box::new(|utterance| {
|
||||||
println!("Finished speaking {:?}", utterance)
|
println!("Finished speaking {:?}", utterance)
|
||||||
}))?;
|
})))?;
|
||||||
}
|
}
|
||||||
tts.speak("Hello, world.", false)?;
|
tts.speak("Hello, world.", false)?;
|
||||||
let Features { rate, .. } = tts.supported_features();
|
let Features { rate, .. } = tts.supported_features();
|
||||||
|
|
|
@ -28,22 +28,22 @@ impl SpeechDispatcher {
|
||||||
sd.0.on_begin(Some(|msg_id, client_id| {
|
sd.0.on_begin(Some(|msg_id, client_id| {
|
||||||
let mut speaking = SPEAKING.lock().unwrap();
|
let mut speaking = SPEAKING.lock().unwrap();
|
||||||
speaking.insert(client_id, true);
|
speaking.insert(client_id, true);
|
||||||
let callbacks = CALLBACKS.lock().unwrap();
|
let mut callbacks = CALLBACKS.lock().unwrap();
|
||||||
let backend_id = BackendId::SpeechDispatcher(client_id);
|
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);
|
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);
|
f(utterance_id);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
sd.0.on_end(Some(|msg_id, client_id| {
|
sd.0.on_end(Some(|msg_id, client_id| {
|
||||||
let mut speaking = SPEAKING.lock().unwrap();
|
let mut speaking = SPEAKING.lock().unwrap();
|
||||||
speaking.insert(client_id, false);
|
speaking.insert(client_id, false);
|
||||||
let callbacks = CALLBACKS.lock().unwrap();
|
let mut callbacks = CALLBACKS.lock().unwrap();
|
||||||
let backend_id = BackendId::SpeechDispatcher(client_id);
|
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);
|
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);
|
f(utterance_id);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -60,18 +60,18 @@ impl Backend for Web {
|
||||||
let id = self.id().unwrap();
|
let id = self.id().unwrap();
|
||||||
let utterance_id = UtteranceId::Web(utterance.clone());
|
let utterance_id = UtteranceId::Web(utterance.clone());
|
||||||
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisEvent| {
|
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisEvent| {
|
||||||
let callbacks = CALLBACKS.lock().unwrap();
|
let mut callbacks = CALLBACKS.lock().unwrap();
|
||||||
let callback = callbacks.get(&id).unwrap();
|
let callback = callbacks.get_mut(&id).unwrap();
|
||||||
if let Some(f) = callback.utterance_begin {
|
if let Some(f) = callback.utterance_begin.as_mut() {
|
||||||
let utterance_id = UtteranceId::Web(evt.utterance());
|
let utterance_id = UtteranceId::Web(evt.utterance());
|
||||||
f(utterance_id);
|
f(utterance_id);
|
||||||
}
|
}
|
||||||
}) as Box<dyn Fn(_)>);
|
}) as Box<dyn Fn(_)>);
|
||||||
utterance.set_onstart(Some(callback.as_ref().unchecked_ref()));
|
utterance.set_onstart(Some(callback.as_ref().unchecked_ref()));
|
||||||
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisEvent| {
|
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisEvent| {
|
||||||
let callbacks = CALLBACKS.lock().unwrap();
|
let mut callbacks = CALLBACKS.lock().unwrap();
|
||||||
let callback = callbacks.get(&id).unwrap();
|
let callback = callbacks.get_mut(&id).unwrap();
|
||||||
if let Some(f) = callback.utterance_end {
|
if let Some(f) = callback.utterance_end.as_mut() {
|
||||||
let utterance_id = UtteranceId::Web(evt.utterance());
|
let utterance_id = UtteranceId::Web(evt.utterance());
|
||||||
f(utterance_id);
|
f(utterance_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,9 +83,9 @@ impl WinRT {
|
||||||
let id = backend_to_media_player.iter().find(|v| v.1 == sender);
|
let id = backend_to_media_player.iter().find(|v| v.1 == sender);
|
||||||
if let Some(id) = id {
|
if let Some(id) = id {
|
||||||
let id = id.0;
|
let id = id.0;
|
||||||
let callbacks = CALLBACKS.lock().unwrap();
|
let mut callbacks = CALLBACKS.lock().unwrap();
|
||||||
let callbacks = callbacks.get(&id).unwrap();
|
let callbacks = callbacks.get_mut(&id).unwrap();
|
||||||
if let Some(callback) = callbacks.utterance_end {
|
if let Some(callback) = callbacks.utterance_end.as_mut() {
|
||||||
let last_spoken_utterance = LAST_SPOKEN_UTTERANCE.lock().unwrap();
|
let last_spoken_utterance = LAST_SPOKEN_UTTERANCE.lock().unwrap();
|
||||||
if let Some(utterance_id) = last_spoken_utterance.get(&id) {
|
if let Some(utterance_id) = last_spoken_utterance.get(&id) {
|
||||||
callback(utterance_id.clone());
|
callback(utterance_id.clone());
|
||||||
|
@ -103,20 +103,20 @@ impl WinRT {
|
||||||
let id = backend_to_playback_list.iter().find(|v| v.1 == sender);
|
let id = backend_to_playback_list.iter().find(|v| v.1 == sender);
|
||||||
if let Some(id) = id {
|
if let Some(id) = id {
|
||||||
let id = id.0;
|
let id = id.0;
|
||||||
let callbacks = CALLBACKS.lock().unwrap();
|
let mut callbacks = CALLBACKS.lock().unwrap();
|
||||||
let callbacks = callbacks.get(&id).unwrap();
|
let callbacks = callbacks.get_mut(&id).unwrap();
|
||||||
let old_item = args.old_item()?;
|
let old_item = args.old_item()?;
|
||||||
if !old_item.is_null() {
|
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));
|
callback(UtteranceId::WinRT(old_item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let new_item = args.new_item()?;
|
let new_item = args.new_item()?;
|
||||||
if !new_item.is_null() {
|
if !new_item.is_null() {
|
||||||
let utterance_id = UtteranceId::WinRT(new_item);
|
|
||||||
let mut last_spoken_utterance = LAST_SPOKEN_UTTERANCE.lock().unwrap();
|
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());
|
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);
|
callback(utterance_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
src/lib.rs
18
src/lib.rs
|
@ -137,10 +137,14 @@ pub trait Backend {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Callbacks {
|
struct Callbacks {
|
||||||
utterance_begin: Option<fn(UtteranceId)>,
|
utterance_begin: Option<Box<dyn FnMut(UtteranceId)>>,
|
||||||
utterance_end: Option<fn(UtteranceId)>,
|
utterance_end: Option<Box<dyn FnMut(UtteranceId)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for Callbacks {}
|
||||||
|
|
||||||
|
unsafe impl Sync for Callbacks {}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref CALLBACKS: Mutex<HashMap<BackendId, Callbacks>> = {
|
static ref CALLBACKS: Mutex<HashMap<BackendId, Callbacks>> = {
|
||||||
let m: HashMap<BackendId, Callbacks> = HashMap::new();
|
let m: HashMap<BackendId, Callbacks> = HashMap::new();
|
||||||
|
@ -436,7 +440,10 @@ impl TTS {
|
||||||
/**
|
/**
|
||||||
* Called when this speech synthesizer begins speaking an utterance.
|
* 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 {
|
let Features {
|
||||||
utterance_callbacks,
|
utterance_callbacks,
|
||||||
..
|
..
|
||||||
|
@ -455,7 +462,10 @@ impl TTS {
|
||||||
/**
|
/**
|
||||||
* Called when this speech synthesizer finishes speaking an utterance.
|
* 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 {
|
let Features {
|
||||||
utterance_callbacks,
|
utterance_callbacks,
|
||||||
..
|
..
|
||||||
|
|
Loading…
Reference in New Issue