71 lines
1.5 KiB
Rust
71 lines
1.5 KiB
Rust
use std::{error::Error, time::Instant};
|
|
|
|
use bevy::prelude::*;
|
|
use bevy_tts::Tts;
|
|
|
|
use crate::error::error_handler;
|
|
|
|
#[derive(Component, Clone, Debug, Default, Deref, DerefMut)]
|
|
pub struct Log(pub Vec<LogEntry>);
|
|
|
|
impl Log {
|
|
pub fn push<S: Into<String>>(&mut self, message: S) {
|
|
self.0.push(LogEntry {
|
|
time: Instant::now(),
|
|
message: message.into(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Component, Clone, Debug, Reflect)]
|
|
pub struct LogEntry {
|
|
pub time: Instant,
|
|
pub message: String,
|
|
}
|
|
|
|
impl From<String> for LogEntry {
|
|
fn from(string: String) -> Self {
|
|
LogEntry {
|
|
time: Instant::now(),
|
|
message: string,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn setup(mut commands: Commands) {
|
|
commands.spawn(Log::default());
|
|
}
|
|
|
|
fn read_log(
|
|
mut tts: ResMut<Tts>,
|
|
mut position: Local<usize>,
|
|
log: Query<&Log, Changed<Log>>,
|
|
) -> Result<(), Box<dyn Error>> {
|
|
for log in &log {
|
|
if *position >= log.len() {
|
|
*position = 0;
|
|
}
|
|
for (index, entry) in log.iter().enumerate() {
|
|
if index >= *position {
|
|
tts.speak(entry.message.clone(), false)?;
|
|
*position = index + 1;
|
|
}
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub struct LogPlugin;
|
|
|
|
impl Plugin for LogPlugin {
|
|
fn build(&self, app: &mut App) {
|
|
app.register_type::<LogEntry>()
|
|
.add_startup_system(setup)
|
|
.add_system(
|
|
read_log
|
|
.pipe(error_handler)
|
|
.in_base_set(CoreSet::PostUpdate),
|
|
);
|
|
}
|
|
}
|