generated from GarandPLG/rust-flake-template
Add tests, fix offset logic, and bump dependencies
- Introduce a comprehensive test suite (cli, app, board, tasks, audio) and a new TESTING.md document describing test execution. - Correct vertical offset calculation in `BoardState` to use saturating subtraction and ceiling division. - Clamp initial `Offset` values to the provided maximum in `Offset::new`. - Export `load_audio` from the audio thread module and switch to `LoopedDecoder` for proper OGG looping. - Update several crate versions: clap, ratatui, log, rodio, and bitflags.
This commit is contained in:
1 parent
9bc42dc898
commit
fcdbbaf74c
16 files changed
+817
-246
No files matched your search
@@ -51,7 +51,7 @@ impl BoardState {
|
||||
let h_max_offset: usize = Self::max_offset(map_width, cols);
|
||||
|
||||
let vertical_offset: Offset = Offset::new(
|
||||
Some((map_height - rows as usize + 1) / 2),
|
||||
Some(map_height.saturating_sub(rows).div_ceil(2)),
|
||||
Some(v_max_offset),
|
||||
);
|
||||
let horizontal_offset: Offset = Offset::new(None, Some(h_max_offset));
|
||||
|
||||
@@ -7,7 +7,7 @@ pub struct Offset {
|
||||
impl Offset {
|
||||
pub fn new(initial_value: Option<usize>, initial_max: Option<usize>) -> Self {
|
||||
Self {
|
||||
value: initial_value.unwrap_or(0),
|
||||
value: initial_value.unwrap_or(0).min(initial_max.unwrap_or(0)),
|
||||
max: initial_max.unwrap_or(0),
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,12 @@ impl Offset {
|
||||
}
|
||||
|
||||
pub fn set_value(&mut self, value: usize) {
|
||||
self.value = value;
|
||||
self.value = value.min(self.max);
|
||||
}
|
||||
|
||||
pub fn set_max(&mut self, max: usize) {
|
||||
self.max = max;
|
||||
self.value = self.value.min(max);
|
||||
}
|
||||
|
||||
pub fn next(&mut self) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::app::states::skirmish_states::tasks::Task;
|
||||
use std::{collections::VecDeque, ops::Add};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct DiggingTask {
|
||||
@@ -49,7 +49,7 @@ impl Task for DiggingTask {
|
||||
}
|
||||
|
||||
fn progress(&mut self) {
|
||||
let _ = self.progress.add(self.tick_increase).max(0.0).min(100.0);
|
||||
self.progress = (self.progress + self.tick_increase).clamp(0.0, 100.0);
|
||||
}
|
||||
|
||||
fn is_finished(&self) -> bool {
|
||||
|
||||
+29
-34
@@ -1,7 +1,8 @@
|
||||
use clap::ValueEnum;
|
||||
use once_cell::sync::Lazy;
|
||||
use rodio::{
|
||||
Decoder, DeviceSinkBuilder, MixerDeviceSink, Player, Source, cpal::BufferSize, source::Amplify,
|
||||
Decoder, DeviceSinkBuilder, MixerDeviceSink, Player, Source, cpal::BufferSize,
|
||||
decoder::LoopedDecoder, source::Amplify,
|
||||
};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
@@ -69,10 +70,10 @@ fn load_soundtrack_folder(folder: &str) -> SoundtrackCache {
|
||||
cache
|
||||
}
|
||||
|
||||
fn load_audio(
|
||||
pub fn load_audio(
|
||||
soundtrack: &Soundtrack,
|
||||
part: &SoundrackParts,
|
||||
) -> Amplify<Decoder<BufReader<Cursor<Vec<u8>>>>> {
|
||||
) -> Amplify<LoopedDecoder<BufReader<Cursor<Vec<u8>>>>> {
|
||||
{
|
||||
let guard: RwLockReadGuard<'_, HashMap<Soundtrack, Arc<HashMap<SoundrackParts, Vec<u8>>>>> =
|
||||
PRELOADED_SOUNDTRACKS
|
||||
@@ -86,7 +87,7 @@ fn load_audio(
|
||||
if let Some(soundtrack_cache) = guard.get(soundtrack) {
|
||||
let data: &Vec<u8> = soundtrack_cache.get(part).expect("part missing in cache");
|
||||
|
||||
return Decoder::new(BufReader::new(Cursor::new(data.clone())))
|
||||
return Decoder::new_looped(BufReader::new(Cursor::new(data.clone())))
|
||||
.expect("decoder issue")
|
||||
.amplify(0.20);
|
||||
}
|
||||
@@ -107,7 +108,7 @@ fn load_audio(
|
||||
if let Some(soundtrack_cache) = guard.get(soundtrack) {
|
||||
let data: &Vec<u8> = soundtrack_cache.get(part).expect("part missing in cache");
|
||||
|
||||
return Decoder::new(BufReader::new(Cursor::new(data.clone())))
|
||||
return Decoder::new_looped(BufReader::new(Cursor::new(data.clone())))
|
||||
.expect("decoder issue")
|
||||
.amplify(0.20);
|
||||
}
|
||||
@@ -123,7 +124,7 @@ fn load_audio(
|
||||
|
||||
guard.insert(*soundtrack, Arc::clone(&new_cache));
|
||||
|
||||
Decoder::new(BufReader::new(Cursor::new(data.clone())))
|
||||
Decoder::new_looped(BufReader::new(Cursor::new(data.clone())))
|
||||
.expect("decoder issue")
|
||||
.amplify(0.20)
|
||||
}
|
||||
@@ -146,35 +147,29 @@ pub fn handle_audio(rx: Receiver<AudioCmd>, mute: bool, soundtrack: Soundtrack)
|
||||
let mut current_part: SoundrackParts = SoundrackParts::Calm;
|
||||
player.append(load_audio(¤t_soundtrack, ¤t_part));
|
||||
|
||||
loop {
|
||||
for cmd in rx.try_iter() {
|
||||
match cmd {
|
||||
AudioCmd::Mute => {
|
||||
player.set_volume(if player.volume() == 0.0 { volume } else { 0.0 });
|
||||
}
|
||||
AudioCmd::VolumeUp => {
|
||||
volume = (volume + 0.1).min(1.0);
|
||||
player.set_volume(volume);
|
||||
}
|
||||
AudioCmd::VolumeDown => {
|
||||
volume = (volume - 0.1).max(0.0);
|
||||
player.set_volume(volume);
|
||||
}
|
||||
AudioCmd::ChangePart(part) => {
|
||||
current_part = part;
|
||||
player.append(load_audio(¤t_soundtrack, ¤t_part));
|
||||
player.skip_one();
|
||||
}
|
||||
AudioCmd::ChangeSoundtrack(st) => {
|
||||
current_soundtrack = st;
|
||||
player.append(load_audio(¤t_soundtrack, ¤t_part));
|
||||
player.skip_one();
|
||||
}
|
||||
for cmd in rx {
|
||||
match cmd {
|
||||
AudioCmd::Mute => {
|
||||
player.set_volume(if player.volume() == 0.0 { volume } else { 0.0 });
|
||||
}
|
||||
AudioCmd::VolumeUp => {
|
||||
volume = (volume + 0.1).min(1.0);
|
||||
player.set_volume(volume);
|
||||
}
|
||||
AudioCmd::VolumeDown => {
|
||||
volume = (volume - 0.1).max(0.0);
|
||||
player.set_volume(volume);
|
||||
}
|
||||
AudioCmd::ChangePart(part) => {
|
||||
current_part = part;
|
||||
player.append(load_audio(¤t_soundtrack, ¤t_part));
|
||||
player.skip_one();
|
||||
}
|
||||
AudioCmd::ChangeSoundtrack(st) => {
|
||||
current_soundtrack = st;
|
||||
player.append(load_audio(¤t_soundtrack, ¤t_part));
|
||||
player.skip_one();
|
||||
}
|
||||
}
|
||||
|
||||
if player.empty() {
|
||||
player.append(load_audio(¤t_soundtrack, ¤t_part));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,6 @@ mod audio;
|
||||
mod events;
|
||||
mod tick;
|
||||
|
||||
pub use audio::{AudioCmd, SoundrackParts, Soundtrack, handle_audio};
|
||||
pub use audio::{AudioCmd, SoundrackParts, Soundtrack, handle_audio, load_audio};
|
||||
pub use events::handle_ct_events;
|
||||
pub use tick::{TICK_MS, handle_tick_event};
|
||||
Reference in new issue
Block a user