mirror of
https://github.com/ndarilek/tts-rs.git
synced 2024-11-22 22:59:37 +00:00
Make UtteranceId
use u64
on most platforms, and add additional derives.
This commit is contained in:
parent
c2bbc5ac04
commit
174011bbb4
|
@ -18,6 +18,8 @@ pub struct Web {
|
|||
|
||||
lazy_static! {
|
||||
static ref NEXT_BACKEND_ID: Mutex<u64> = Mutex::new(0);
|
||||
static ref UTTERANCE_MAPPINGS: Mutex<Vec<(BackendId, UtteranceId)>> = Mutex::new(Vec::new());
|
||||
static ref NEXT_UTTERANCE_ID: Mutex<u64> = Mutex::new(0);
|
||||
}
|
||||
|
||||
impl Web {
|
||||
|
@ -58,23 +60,29 @@ impl Backend for Web {
|
|||
utterance.set_pitch(self.pitch);
|
||||
utterance.set_volume(self.volume);
|
||||
let id = self.id().unwrap();
|
||||
let utterance_id = UtteranceId::Web(utterance.clone());
|
||||
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisEvent| {
|
||||
let mut uid = NEXT_UTTERANCE_ID.lock().unwrap();
|
||||
let utterance_id = UtteranceId::Web(*uid);
|
||||
*uid += 1;
|
||||
drop(uid);
|
||||
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||
mappings.push((self.id, utterance_id));
|
||||
drop(mappings);
|
||||
let callback = Closure::wrap(Box::new(move |_evt: SpeechSynthesisEvent| {
|
||||
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 callback = Closure::wrap(Box::new(move |_evt: SpeechSynthesisEvent| {
|
||||
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);
|
||||
}
|
||||
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||
mappings.retain(|v| v.1 != utterance_id);
|
||||
}) as Box<dyn Fn(_)>);
|
||||
utterance.set_onend(Some(callback.as_ref().unchecked_ref()));
|
||||
if interrupt {
|
||||
|
@ -173,3 +181,10 @@ impl Backend for Web {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Web {
|
||||
fn drop(&mut self) {
|
||||
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||
mappings.retain(|v| v.0 != self.id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@ pub struct WinRT {
|
|||
|
||||
lazy_static! {
|
||||
static ref NEXT_BACKEND_ID: Mutex<u64> = Mutex::new(0);
|
||||
static ref NEXT_UTTERANCE_ID: Mutex<u64> = Mutex::new(0);
|
||||
static ref UTTERANCE_MAPPINGS: Mutex<Vec<(BackendId, MediaPlaybackItem, UtteranceId)>> =
|
||||
Mutex::new(Vec::new());
|
||||
static ref BACKEND_TO_MEDIA_PLAYER: Mutex<HashMap<BackendId, MediaPlayer>> = {
|
||||
let v: HashMap<BackendId, MediaPlayer> = HashMap::new();
|
||||
Mutex::new(v)
|
||||
|
@ -70,6 +73,16 @@ impl WinRT {
|
|||
self.player.set_auto_play(true)?;
|
||||
self.player.set_source(&self.playback_list)?;
|
||||
self.init_callbacks()?;
|
||||
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() {
|
||||
let mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||
for mapping in &*mappings {
|
||||
callback(mapping.2);
|
||||
}
|
||||
}
|
||||
mappings.retain(|v| v.0 != self.id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -107,17 +120,31 @@ impl WinRT {
|
|||
let callbacks = callbacks.get_mut(&id).unwrap();
|
||||
let old_item = args.old_item()?;
|
||||
if !old_item.is_null() {
|
||||
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||
if let Some(callback) = callbacks.utterance_end.as_mut() {
|
||||
callback(UtteranceId::WinRT(old_item));
|
||||
for mapping in &*mappings {
|
||||
if mapping.1 == old_item {
|
||||
callback(mapping.2);
|
||||
}
|
||||
}
|
||||
mappings.retain(|v| v.1 != old_item);
|
||||
}
|
||||
}
|
||||
let new_item = args.new_item()?;
|
||||
if !new_item.is_null() {
|
||||
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());
|
||||
let mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||
for mapping in &*mappings {
|
||||
if mapping.1 == new_item {
|
||||
last_spoken_utterance.insert(*id, mapping.2);
|
||||
}
|
||||
}
|
||||
if let Some(callback) = callbacks.utterance_begin.as_mut() {
|
||||
callback(utterance_id);
|
||||
for mapping in &*mappings {
|
||||
if mapping.1 == new_item {
|
||||
callback(mapping.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +196,12 @@ impl Backend for WinRT {
|
|||
if !self.is_speaking()? {
|
||||
self.player.play()?;
|
||||
}
|
||||
let utterance_id = UtteranceId::WinRT(item);
|
||||
let mut uid = NEXT_UTTERANCE_ID.lock().unwrap();
|
||||
let utterance_id = UtteranceId::WinRT(*uid);
|
||||
*uid += 1;
|
||||
drop(uid);
|
||||
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||
mappings.push((self.id, item, utterance_id));
|
||||
Ok(Some(utterance_id))
|
||||
}
|
||||
|
||||
|
@ -254,12 +286,14 @@ impl Backend for WinRT {
|
|||
|
||||
impl Drop for WinRT {
|
||||
fn drop(&mut self) {
|
||||
let id = self.id().unwrap();
|
||||
let id = self.id;
|
||||
let mut backend_to_playback_list = BACKEND_TO_PLAYBACK_LIST.lock().unwrap();
|
||||
backend_to_playback_list.remove(&id);
|
||||
let mut backend_to_media_player = BACKEND_TO_MEDIA_PLAYER.lock().unwrap();
|
||||
backend_to_media_player.remove(&id);
|
||||
let mut last_spoken_utterance = LAST_SPOKEN_UTTERANCE.lock().unwrap();
|
||||
last_spoken_utterance.remove(&id);
|
||||
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||
mappings.retain(|v| v.0 != id);
|
||||
}
|
||||
}
|
||||
|
|
11
src/lib.rs
11
src/lib.rs
|
@ -25,11 +25,6 @@ use libc::c_char;
|
|||
#[cfg(target_os = "macos")]
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use thiserror::Error;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use web_sys::SpeechSynthesisUtterance;
|
||||
|
||||
#[cfg(windows)]
|
||||
use tts_winrt_bindings::windows::media::playback::MediaPlaybackItem;
|
||||
|
||||
mod backends;
|
||||
|
||||
|
@ -60,14 +55,14 @@ pub enum BackendId {
|
|||
AvFoundation(u64),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub enum UtteranceId {
|
||||
#[cfg(target_os = "linux")]
|
||||
SpeechDispatcher(u64),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
Web(SpeechSynthesisUtterance),
|
||||
Web(u64),
|
||||
#[cfg(windows)]
|
||||
WinRT(MediaPlaybackItem),
|
||||
WinRT(u64),
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
AvFoundation(id),
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user