diff --git a/Cargo.toml b/Cargo.toml index d0e58b3..7a9b0b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,8 @@ crate-type = ["staticlib", "cdylib"] [dependencies] env_logger = "0.7" -gdnative = "0.9.0-preview.0" -tts = ">= 0.6.4" +gdnative = "0.9" +tts = "0.8" [target.'cfg(windows)'.dependencies] tolk = ">= 0.2.1" diff --git a/src/lib.rs b/src/lib.rs index 9f172fe..a957bfc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,19 +1,36 @@ +use std::sync::mpsc::{channel, Receiver}; + use gdnative::prelude::*; -use tts::{Features, TTS as Tts}; +use tts::{Features, UtteranceId, TTS as Tts}; + +enum Msg { + UtteranceBegin(UtteranceId), + UtteranceEnd(UtteranceId), +} #[derive(NativeClass)] #[inherit(Node)] -#[register_with(Self::register_properties)] -struct TTS(Tts); +#[register_with(Self::register)] +struct TTS(Tts, Receiver); #[methods] impl TTS { fn new(_owner: &Node) -> Self { let tts = Tts::default().unwrap(); - Self(tts) + let (tx, rx) = channel(); + let tx_end = tx.clone(); + tts.on_utterance_begin(Some(Box::new(move |utterance| { + tx.send(Msg::UtteranceBegin(utterance)).unwrap(); + }))) + .expect("Failed to set utterance_begin callback"); + tts.on_utterance_end(Some(Box::new(move |utterance| { + tx_end.send(Msg::UtteranceEnd(utterance)).unwrap(); + }))) + .expect("Failed to set utterance_end callback"); + Self(tts, rx) } - fn register_properties(builder: &ClassBuilder) { + fn register(builder: &ClassBuilder) { builder .add_property("rate") .with_getter(|this: &TTS, _| match this.0.get_rate() { @@ -118,6 +135,14 @@ impl TTS { } }) .done(); + builder.add_signal(Signal { + name: "utterance_begin", + args: &[], + }); + builder.add_signal(Signal { + name: "utterance_end", + args: &[], + }); } #[export] @@ -139,6 +164,20 @@ impl TTS { } = self.0.supported_features(); rate_supported } + + #[export] + fn _process(&mut self, owner: &Node, _delta: f32) { + if let Some(msg) = self.1.try_recv().ok() { + match msg { + Msg::UtteranceBegin(_utterance) => { + owner.emit_signal("utterance_begin", &[]); + } + Msg::UtteranceEnd(_utterance) => { + owner.emit_signal("utterance_end", &[]); + } + } + } + } } fn init(handle: InitHandle) {