From b31594b23fcb74a87cb310b7f5d6044fcf76a582 Mon Sep 17 00:00:00 2001 From: Paris DOUADY Date: Thu, 21 Dec 2023 00:00:19 +0100 Subject: [PATCH] update oddio to 0.7.4 + clippy pass --- Cargo.lock | 4 +- Cargo.toml | 2 +- assets_gui/src/orbit_camera.rs | 1 + assets_gui/src/yakui_gui.rs | 9 +- engine/src/audio.rs | 159 ++++++++++++++++++------ engine/src/drawables/terrain.rs | 28 ++--- engine/src/framework.rs | 4 +- engine/src/geometry/earcut.rs | 5 +- engine/src/shader.rs | 24 ++-- engine/src/texture.rs | 1 - engine/src/yakui.rs | 2 +- engine_demo/src/main.rs | 8 +- engine_demo/src/terrain.rs | 9 +- geom/src/heightmap.rs | 16 +-- geom/src/lib.rs | 2 + geom/src/skeleton.rs | 4 +- native_app/src/audio/ambient.rs | 22 ++-- native_app/src/audio/car_sounds.rs | 103 ++++++++------- native_app/src/audio/music.rs | 12 +- native_app/src/gui/terraforming.rs | 13 +- networking/examples/example.rs | 9 +- networking/src/connections.rs | 12 +- simulation/src/economy/ecostats.rs | 1 + simulation/src/souls/freight_station.rs | 2 +- simulation/src/tests/mod.rs | 1 - simulation/src/tests/test_iso.rs | 4 +- 26 files changed, 269 insertions(+), 188 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a846d43a..84f947db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2147,9 +2147,9 @@ dependencies = [ [[package]] name = "oddio" -version = "0.6.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f3379cc7e854d0b0d4a0e310f276faafc46896843b720efe4646faa1b0c734" +checksum = "c287b2b60511f53bd87e59adca987a46d4bdde6f16ad5cfa89531bffca344cf2" dependencies = [ "mint", ] diff --git a/Cargo.toml b/Cargo.toml index 68a00b36..b2d34bf9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ flat_spatial = "0.6" egui_extras = { git = "https://github.com/emilk/egui" } egui_plot = { git = "https://github.com/emilk/egui" } ordered-float = { version = "4.2.0", default-features = false } -oddio = "0.6.2" +oddio = "0.7.4" derive_more = "0.99.17" # Set the settings for build scripts and proc-macros. diff --git a/assets_gui/src/orbit_camera.rs b/assets_gui/src/orbit_camera.rs index 7eee59b9..15daa883 100644 --- a/assets_gui/src/orbit_camera.rs +++ b/assets_gui/src/orbit_camera.rs @@ -36,6 +36,7 @@ impl OrbitCamera { self.update(ctx); } + #[allow(clippy::redundant_closure_call)] pub fn camera_movement(&mut self, ctx: &mut Context) { if !self.camera.pos.is_finite() { self.camera.pos = Vec3::ZERO; diff --git a/assets_gui/src/yakui_gui.rs b/assets_gui/src/yakui_gui.rs index d70d2881..a1d3cf3d 100644 --- a/assets_gui/src/yakui_gui.rs +++ b/assets_gui/src/yakui_gui.rs @@ -70,10 +70,8 @@ impl State { l.cross_axis_alignment = CrossAxisAlignment::Stretch; l.show(|| { label("Companies"); - if self.gui.companies.changed { - if button("Save").clicked { - self.gui.companies.save(); - } + if self.gui.companies.changed && button("Save").clicked { + self.gui.companies.save(); } for (i, comp) in self.gui.companies.companies.iter().enumerate() { let b = Button::styled(comp.name.to_string()); @@ -250,7 +248,7 @@ impl State { recipe.consumption.iter().zip(consumption.iter()) { let amount = amount.clone(); - props.add(&*name, move || inspect_v(&mut *amount.borrow_mut())); + props.add(name, move || inspect_v(&mut *amount.borrow_mut())); } props.add("production", || { @@ -335,6 +333,7 @@ fn on_changed(v: T, f: impl FnOnce()) { } } +#[allow(clippy::type_complexity)] struct PropertiesBuilder<'a> { props: Vec<(&'a str, Box)>, } diff --git a/engine/src/audio.rs b/engine/src/audio.rs index d3d6a374..709ab2bf 100644 --- a/engine/src/audio.rs +++ b/engine/src/audio.rs @@ -1,6 +1,8 @@ use common::{AudioKind, FastMap, FastSet}; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; -use oddio::{Filter, Frames, FramesSignal, Gain, Handle, Mixer, Sample, Signal, Smoothed, Stop}; +use oddio::{ + FixedGain, Frame, Frames, FramesSignal, Mixed, Mixer, MixerControl, Sample, Signal, Smoothed, +}; use std::cell::RefCell; use std::fmt::Debug; use std::sync::atomic::{AtomicU32, Ordering}; @@ -13,7 +15,7 @@ type StoredAudio = Arc>; #[allow(dead_code)] pub struct AudioContext { stream: Option, - scene_handle: Option>>, + scene_handle: Option>, cache: Arc>>, preloading: FastSet, } @@ -23,7 +25,6 @@ static MUSIC_SHARED: AtomicU32 = AtomicU32::new(0); static EFFECT_SHARED: AtomicU32 = AtomicU32::new(0); static UI_SHARED: AtomicU32 = AtomicU32::new(0); -pub type ControlHandle = Handle>>; pub type Stereo = [Sample; 2]; pub type BaseSignal = FramesSignal; @@ -55,13 +56,13 @@ impl AudioContext { buffer_size: cpal::BufferSize::Fixed(4096), // Using BufferSize::Default causes 100% cpu usage with ALSA on linux }; - let (scene_handle, scene) = oddio::split(Mixer::new()); + let (scene_handle, mut scene) = Mixer::new(); let stream = match device.build_output_stream( &config, move |data: &mut [f32], _: &cpal::OutputCallbackInfo| { let frames = oddio::frame_stereo(data); - oddio::run(&scene, sample_rate.0, frames); + oddio::run(&mut scene, sample_rate.0, frames); }, move |err| { eprintln!("{err:?}"); @@ -195,10 +196,11 @@ impl AudioContext { if let AudioKind::Music = kind { log::error!("shouldn't play music with base play as it's not affected by global volume changes"); } - log::info!("playing {}", name); - let mut g = Gain::new(FramesSignal::new(x, 0.0)); - g.set_amplitude_ratio(vol); - h.control().play(g); + if vol <= 0.001 { + return; + } + let g = FixedGain::new(FramesSignal::new(x, 0.0).1, vol.log10() * 20.0); + h.play(g); } } } @@ -207,24 +209,25 @@ impl AudioContext { self.cache.read().unwrap().len() >= self.preloading.len() } - pub fn play_with_control( + pub fn play_with_control( &mut self, name: &'static str, - transform: impl FnOnce(StoredAudio) -> S, + transform: impl FnOnce(StoredAudio) -> (Control, S), kind: AudioKind, - ) -> Option> + ) -> Option<(Control, Mixed)> where S: Signal + Send, { if let Some(ref mut h) = self.scene_handle { if let Some(x) = Self::get(&self.preloading, &self.cache, name) { + let (control, signal) = transform(x); let test = GlobalGain { volume: RefCell::new(Smoothed::new(1.0)), kind, - inner: transform(x), + inner: signal, }; - let hand = h.control().play(test); - return Some(hand); + let mixed = h.play(test); + return Some((control, mixed)); } } None @@ -274,7 +277,7 @@ pub struct GlobalGain { impl> Signal for GlobalGain { type Frame = [Sample; 2]; - fn sample(&self, interval: f32, out: &mut [Self::Frame]) { + fn sample(&mut self, interval: f32, out: &mut [Self::Frame]) { fn upd(x: &AtomicU32, gain: &mut std::cell::RefMut>) { let master = f32::from_bits(MASTER_SHARED.load(Ordering::Relaxed)); let shared = master * f32::from_bits(x.load(Ordering::Relaxed)); @@ -309,18 +312,6 @@ impl> Signal for GlobalGain { gain.advance(interval * 30.0); } } - - fn handle_dropped(&self) { - self.inner.handle_dropped() - } -} - -impl Filter for GlobalGain { - type Inner = T; - - fn inner(&self) -> &Self::Inner { - &self.inner - } } pub struct FadeIn { @@ -342,7 +333,7 @@ impl FadeIn { impl> Signal for FadeIn { type Frame = [Sample; 2]; - fn sample(&self, interval: f32, out: &mut [Self::Frame]) { + fn sample(&mut self, interval: f32, out: &mut [Self::Frame]) { self.inner.sample(interval, out); let mut advance = self.advance.borrow_mut(); @@ -356,16 +347,114 @@ impl> Signal for FadeIn { *advance += interval / self.fadetime; } } +} + +/// Amplifies a signal dynamically +/// +/// To implement a volume control, place a gain combinator near the end of your pipeline where the +/// input amplitude is initially in the range [0, 1] and pass decibels to [`oddio::GainControl::set_gain`], +/// mapping the maximum volume to 0 decibels, and the minimum to e.g. -60. +/// +/// Forked from oddio to allow directly setting the volume to avoid pops at zero volume +/// due to Ordering::Relaxed being too relaxed +pub struct Gain { + shared: Arc, + gain: Smoothed, + inner: T, +} - fn handle_dropped(&self) { - self.inner.handle_dropped() +impl Gain { + /// Apply dynamic amplification to `signal` + pub fn new(signal: T, vol: f32) -> (GainControl, Self) { + let signal = Gain { + shared: Arc::new(AtomicU32::new(vol.to_bits())), + gain: Smoothed::new(vol), + inner: signal, + }; + let handle = GainControl(signal.shared.clone()); + (handle, signal) } } -impl Filter for FadeIn { - type Inner = T; +impl Signal for Gain +where + T::Frame: Frame, +{ + type Frame = T::Frame; - fn inner(&self) -> &Self::Inner { - &self.inner + #[allow(clippy::float_cmp)] + fn sample(&mut self, interval: f32, out: &mut [T::Frame]) { + self.inner.sample(interval, out); + let shared = f32::from_bits(self.shared.load(Ordering::Relaxed)); + if self.gain.target() != &shared { + self.gain.set(shared); + } + if self.gain.progress() == 1.0 { + let g = self.gain.get(); + if g != 1.0 { + for x in out { + *x = scale(x, g); + } + } + return; + } + for x in out { + *x = scale(x, self.gain.get()); + self.gain.advance(interval / SMOOTHING_PERIOD); + } + } + + fn is_finished(&self) -> bool { + self.inner.is_finished() + } +} + +#[inline] +fn scale(x: &T, factor: f32) -> T { + map(x, |x| x * factor) +} + +#[inline] +fn map(x: &T, mut f: impl FnMut(Sample) -> Sample) -> T { + let mut out = T::ZERO; + for (&x, o) in x.channels().iter().zip(out.channels_mut()) { + *o = f(x); } + out } + +/// Thread-safe control for a [`Gain`] filter +pub struct GainControl(Arc); + +impl GainControl { + /// Get the current amplification in decibels + pub fn gain(&self) -> f32 { + 20.0 * self.amplitude_ratio().log10() + } + + /// Amplify the signal by `db` decibels + /// + /// Perceptually linear. Negative values make the signal quieter. + /// + /// Equivalent to `self.set_amplitude_ratio(10.0f32.powf(db / 20.0))`. + pub fn set_gain(&mut self, db: f32) { + self.set_amplitude_ratio(10.0f32.powf(db / 20.0)); + } + + /// Get the current amplitude scaling factor + pub fn amplitude_ratio(&self) -> f32 { + f32::from_bits(self.0.load(Ordering::Relaxed)) + } + + /// Scale the amplitude of the signal directly + /// + /// This is nonlinear in terms of both perception and power. Most users should prefer + /// `set_gain`. Unlike `set_gain`, this method allows a signal to be completely zeroed out if + /// needed, or even have its phase inverted with a negative factor. + pub fn set_amplitude_ratio(&mut self, factor: f32) { + self.0.store(factor.to_bits(), Ordering::Relaxed); + } +} + +/// Number of seconds over which to smooth a change in gain +const SMOOTHING_PERIOD: f32 = 0.1; diff --git a/engine/src/drawables/terrain.rs b/engine/src/drawables/terrain.rs index 4617efda..6927d182 100644 --- a/engine/src/drawables/terrain.rs +++ b/engine/src/drawables/terrain.rs @@ -134,15 +134,15 @@ impl TerrainRender TerrainRender RenderPipeline { }) } -fn normal_update<'a>( +fn normal_update( gfx: &GfxContext, normal_pipeline: &RenderPipeline, - encoder: &'a mut CommandEncoder, + encoder: &mut CommandEncoder, height_tex: &TextureView, normal_view: &TextureView, uni: &Uniform, @@ -448,7 +446,7 @@ fn normal_update<'a>( layout: &normal_pipeline.get_bind_group_layout(0), entries: &[wgpu::BindGroupEntry { binding: 0, - resource: wgpu::BindingResource::TextureView(&height_tex), + resource: wgpu::BindingResource::TextureView(height_tex), }], label: None, }); @@ -456,7 +454,7 @@ fn normal_update<'a>( let mut rp = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("terrain normals render pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &normal_view, + view: normal_view, resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Load, @@ -467,7 +465,7 @@ fn normal_update<'a>( timestamp_writes: None, occlusion_query_set: None, }); - rp.set_pipeline(&normal_pipeline); + rp.set_pipeline(normal_pipeline); rp.set_bind_group(0, &bg, &[]); rp.set_bind_group(1, &uni.bindgroup, &[]); rp.draw(0..4, 0..1); @@ -556,7 +554,7 @@ fn downsample_update( timestamp_writes: None, occlusion_query_set: None, }); - rp.set_pipeline(&downsample_pipeline); + rp.set_pipeline(downsample_pipeline); rp.set_bind_group(0, &bg, &[]); rp.draw(0..4, 0..1); drop(rp); @@ -594,7 +592,7 @@ fn upsample_update( timestamp_writes: None, occlusion_query_set: None, }); - rp.set_pipeline(&upsample_pipeline); + rp.set_pipeline(upsample_pipeline); rp.set_bind_group(0, &bg, &[]); rp.draw(0..4, 0..1); drop(rp); diff --git a/engine/src/framework.rs b/engine/src/framework.rs index f325beb8..329b013c 100644 --- a/engine/src/framework.rs +++ b/engine/src/framework.rs @@ -70,7 +70,7 @@ async fn run(el: EventLoop<()>, window: Window) { WindowEvent::Resized(physical_size) => { log::info!("resized: {:?}", physical_size); new_size = Some((physical_size, scale_factor)); - frame.take().map(|v| ManuallyDrop::into_inner(v)); + frame.take().map(ManuallyDrop::into_inner); } WindowEvent::ScaleFactorChanged { scale_factor: sf, @@ -79,7 +79,7 @@ async fn run(el: EventLoop<()>, window: Window) { log::info!("scale_factor: {:?}", scale_factor); scale_factor = sf; new_size = Some((PhysicalSize::new(ctx.gfx.size.0, ctx.gfx.size.1), scale_factor)); - frame.take().map(|v| ManuallyDrop::into_inner(v)); + frame.take().map(ManuallyDrop::into_inner); } WindowEvent::CloseRequested => { if state.exit() { diff --git a/engine/src/geometry/earcut.rs b/engine/src/geometry/earcut.rs index bec6f4b8..23dba896 100644 --- a/engine/src/geometry/earcut.rs +++ b/engine/src/geometry/earcut.rs @@ -1189,7 +1189,7 @@ mod tests { a - signed_area(data, ix * DIM, iy * DIM).abs() }); - let i = triangles.iter().skip(0).step_by(3).map(|x| x * DIM); + let i = triangles.iter().step_by(3).map(|x| x * DIM); let j = triangles.iter().skip(1).step_by(3).map(|x| x * DIM); let k = triangles.iter().skip(2).step_by(3).map(|x| x * DIM); let triangles_area = i.zip(j).zip(k).fold(0., |ta, ((a, b), c)| { @@ -1207,8 +1207,7 @@ mod tests { if ll.nodes.len() == 1 { return "[]".to_string(); } - let mut markv: Vec = Vec::new(); - markv.resize(ll.nodes.len(), 0); + let mut markv: Vec = vec![0; ll.nodes.len()]; let mut cycler; for i in 0..markv.len() { // if ll.freelist.contains(&i) { diff --git a/engine/src/shader.rs b/engine/src/shader.rs index 212795aa..24e1816a 100644 --- a/engine/src/shader.rs +++ b/engine/src/shader.rs @@ -163,10 +163,10 @@ mod tests { x.iter().map(|x| (x.to_string(), "".to_string())).collect() } - assert_eq!(super::apply_ifdefs(&f(&[]), &src).trim(), "b"); - assert_eq!(super::apply_ifdefs(&f(&["A"]), &src).trim(), "a"); - assert_eq!(super::apply_ifdefs(&f(&["B"]), &src).trim(), "b"); - assert_eq!(super::apply_ifdefs(&f(&["A", "B"]), &src).trim(), "a"); + assert_eq!(super::apply_ifdefs(&f(&[]), src).trim(), "b"); + assert_eq!(super::apply_ifdefs(&f(&["A"]), src).trim(), "a"); + assert_eq!(super::apply_ifdefs(&f(&["B"]), src).trim(), "b"); + assert_eq!(super::apply_ifdefs(&f(&["A", "B"]), src).trim(), "a"); let src = r#" #ifdef A @@ -178,10 +178,10 @@ mod tests { #endif "#; - assert_eq!(super::apply_ifdefs(&f(&[]), &src).trim(), "c"); - assert_eq!(super::apply_ifdefs(&f(&["A"]), &src).trim(), "a"); - assert_eq!(super::apply_ifdefs(&f(&["B"]), &src).trim(), "b"); - assert_eq!(super::apply_ifdefs(&f(&["A", "B"]), &src).trim(), "a"); + assert_eq!(super::apply_ifdefs(&f(&[]), src).trim(), "c"); + assert_eq!(super::apply_ifdefs(&f(&["A"]), src).trim(), "a"); + assert_eq!(super::apply_ifdefs(&f(&["B"]), src).trim(), "b"); + assert_eq!(super::apply_ifdefs(&f(&["A", "B"]), src).trim(), "a"); let src = r#" #ifdef A @@ -195,9 +195,9 @@ mod tests { #endif "#; - assert_eq!(super::apply_ifdefs(&f(&[]), &src).trim(), "c"); - assert_eq!(super::apply_ifdefs(&f(&["A"]), &src).trim(), "b"); - assert_eq!(super::apply_ifdefs(&f(&["B"]), &src).trim(), "c"); - assert_eq!(super::apply_ifdefs(&f(&["A", "B"]), &src).trim(), "a"); + assert_eq!(super::apply_ifdefs(&f(&[]), src).trim(), "c"); + assert_eq!(super::apply_ifdefs(&f(&["A"]), src).trim(), "b"); + assert_eq!(super::apply_ifdefs(&f(&["B"]), src).trim(), "c"); + assert_eq!(super::apply_ifdefs(&f(&["A", "B"]), src).trim(), "a"); } } diff --git a/engine/src/texture.rs b/engine/src/texture.rs index f3b5536f..c83444a4 100644 --- a/engine/src/texture.rs +++ b/engine/src/texture.rs @@ -170,7 +170,6 @@ impl Texture { ), count: None, })) - .into_iter() }) } diff --git a/engine/src/yakui.rs b/engine/src/yakui.rs index f38ba43e..340ffc3c 100644 --- a/engine/src/yakui.rs +++ b/engine/src/yakui.rs @@ -44,7 +44,7 @@ impl YakuiWrapper { format: self.format, sample_count: gfx.gfx.samples, color_attachment: &gfx.gfx.fbos.color_msaa, - resolve_target: Some(&gfx.view), + resolve_target: Some(gfx.view), }, ); } diff --git a/engine_demo/src/main.rs b/engine_demo/src/main.rs index eb017fb8..6ed87a05 100644 --- a/engine_demo/src/main.rs +++ b/engine_demo/src/main.rs @@ -70,8 +70,10 @@ impl engine::framework::State for State { ctx.audio.set_settings(100.0, 100.0, 100.0, 100.0); - let mut gfx_settings = GfxSettings::default(); - gfx_settings.shader_debug = true; + let gfx_settings = GfxSettings { + shader_debug: true, + ..Default::default() + }; Self { demo_elements: vec![ @@ -144,7 +146,7 @@ impl engine::framework::State for State { } for v in self.play_queue.drain(..) { - ctx.audio.play(&v, AudioKind::Ui); + ctx.audio.play(v, AudioKind::Ui); } } diff --git a/engine_demo/src/terrain.rs b/engine_demo/src/terrain.rs index c505e4bb..486af0f3 100644 --- a/engine_demo/src/terrain.rs +++ b/engine_demo/src/terrain.rs @@ -23,6 +23,7 @@ impl DemoElement for Terrain { "Terrain" } + #[allow(clippy::needless_range_loop)] fn init(ctx: &mut Context) -> Self { let gfx = &mut ctx.gfx; @@ -56,7 +57,7 @@ impl DemoElement for Terrain { terrain.update_chunk( gfx, (x as u32, y as u32), - &h.get_chunk((x as u16, y as u16)).unwrap().heights(), + h.get_chunk((x as u16, y as u16)).unwrap().heights(), ); } } @@ -118,10 +119,8 @@ impl DemoElement for Terrain { fn render_gui(&mut self, ui: &mut egui::Ui) { ui.indent("terrain", |ui| { - if cfg!(debug_assertions) { - if ui.button("reload terrain").clicked() { - self.reload = true; - } + if cfg!(debug_assertions) && ui.button("reload terrain").clicked() { + self.reload = true; } }); } diff --git a/geom/src/heightmap.rs b/geom/src/heightmap.rs index f33fbcb8..590289bc 100644 --- a/geom/src/heightmap.rs +++ b/geom/src/heightmap.rs @@ -381,8 +381,9 @@ impl Heightmap { let min_t = t_x.min(t_y) + 0.0001; t += min_t; + #[allow(clippy::neg_cmp_op_on_partial_ord)] + // reverse the condition to avoid infinite loop in case of NaN if !(t < l) { - // reverse the condition to avoid infinite loop in case of NaN return None; } cur += min_t * speed; @@ -656,10 +657,10 @@ mod erosion { let amount_to_deposit = amount_to_deposit * Self::CELL_SIZE; { - self.height_idx_mut(pos.x as usize , pos.y as usize) .map(|v| { *v += amount_to_deposit * (1.0 - cell_offset.x) * (1.0 - cell_offset.y) }); - self.height_idx_mut(pos.x as usize + 1, pos.y as usize) .map(|v| { *v += amount_to_deposit * cell_offset.x * (1.0 - cell_offset.y) }); - self.height_idx_mut(pos.x as usize , pos.y as usize + 1).map(|v| { *v += amount_to_deposit * (1.0 - cell_offset.x) * cell_offset.y }); - self.height_idx_mut(pos.x as usize + 1, pos.y as usize + 1).map(|v| *v += amount_to_deposit * cell_offset.x * cell_offset.y); + if let Some(v) = self.height_idx_mut(pos.x as usize , pos.y as usize) { *v += amount_to_deposit * (1.0 - cell_offset.x) * (1.0 - cell_offset.y) }; + if let Some(v) = self.height_idx_mut(pos.x as usize + 1, pos.y as usize) { *v += amount_to_deposit * cell_offset.x * (1.0 - cell_offset.y) }; + if let Some(v) = self.height_idx_mut(pos.x as usize , pos.y as usize + 1) { *v += amount_to_deposit * (1.0 - cell_offset.x) * cell_offset.y }; + if let Some(v) = self.height_idx_mut(pos.x as usize + 1, pos.y as usize + 1) { *v += amount_to_deposit * cell_offset.x * cell_offset.y }; } } else { // Erode a fraction of the droplet's current carry capacity. @@ -688,8 +689,9 @@ mod erosion { .div(Self::CELL_SIZE) .min(weighed_erode_amount); - self.height_idx_mut(pos_radius.x as usize, pos_radius.y as usize) - .map(|v| *v -= delta_sediment * Self::CELL_SIZE); + if let Some(v) = self.height_idx_mut(pos_radius.x as usize, pos_radius.y as usize) + { *v -= delta_sediment * Self::CELL_SIZE } + //dbg!(delta_sediment, weighed_erode_amount, amount_to_erode); sediment += delta_sediment; diff --git a/geom/src/lib.rs b/geom/src/lib.rs index a5c262c7..b54c00c5 100644 --- a/geom/src/lib.rs +++ b/geom/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(clippy::needless_range_loop, clippy::needless_late_init)] + extern crate core; macro_rules! defer_inter { ($a:ty => $b:ty) => { diff --git a/geom/src/skeleton.rs b/geom/src/skeleton.rs index dd015446..19715aab 100644 --- a/geom/src/skeleton.rs +++ b/geom/src/skeleton.rs @@ -1125,8 +1125,8 @@ mod tests { .copied() .rev() .collect::>(); - let skeleton = skeleton(&poly, &[]); - let _ = faces_from_skeleton(&poly, &skeleton, false).unwrap().0; + let skeleton = skeleton(poly, &[]); + let _ = faces_from_skeleton(poly, &skeleton, false).unwrap().0; } #[test] diff --git a/native_app/src/audio/ambient.rs b/native_app/src/audio/ambient.rs index ee87315c..86253e58 100644 --- a/native_app/src/audio/ambient.rs +++ b/native_app/src/audio/ambient.rs @@ -1,16 +1,16 @@ use crate::uiworld::UiWorld; use common::AudioKind; -use engine::{AudioContext, ControlHandle, Stereo}; +use engine::{AudioContext, Gain, GainControl}; use geom::{lerp, Camera, Vec2, AABB}; -use oddio::{Cycle, Gain}; +use oddio::{Cycle, Mixed}; use simulation::Simulation; /// Ambient sounds /// These are sounds that are played in the background /// They are not tied to any entity pub struct Ambient { - wind: Option>>>, - forest: Option>>>, + wind: Option<(GainControl, Mixed)>, + forest: Option<(GainControl, Mixed)>, } impl Ambient { @@ -18,18 +18,16 @@ impl Ambient { let wind = ctx.play_with_control( "calm_wind", |s| { - let mut g = Gain::new(Cycle::new(s)); - g.set_amplitude_ratio(0.0); - g + let (g_control, signal) = Gain::new(Cycle::new(s), 0.0); + (g_control, signal) }, AudioKind::Effect, ); let forest = ctx.play_with_control( "forest", |s| { - let mut g = Gain::new(Cycle::new(s)); - g.set_amplitude_ratio(0.0); - g + let (g_control, signal) = Gain::new(Cycle::new(s), 0.0); + (g_control, signal) }, AudioKind::Effect, ); @@ -46,7 +44,7 @@ impl Ambient { // Wind let volume = lerp(0.1, 0.8, (h - 100.0) / 4000.0); if let Some(ref mut wind) = self.wind { - wind.control::, _>().set_amplitude_ratio(volume); + wind.0.set_amplitude_ratio(volume); } // Forest @@ -65,7 +63,7 @@ impl Ambient { volume *= matches as f32 / 50.0; } if let Some(ref mut forest) = self.forest { - forest.control::, _>().set_amplitude_ratio(volume); + forest.0.set_amplitude_ratio(volume); } } } diff --git a/native_app/src/audio/car_sounds.rs b/native_app/src/audio/car_sounds.rs index 52d84c65..257a8e56 100644 --- a/native_app/src/audio/car_sounds.rs +++ b/native_app/src/audio/car_sounds.rs @@ -1,39 +1,37 @@ use crate::uiworld::UiWorld; use common::AudioKind; -use engine::{AudioContext, ControlHandle, Stereo}; +use engine::{AudioContext, Gain, GainControl}; use flat_spatial::grid::GridHandle; use geom::{Camera, AABB}; -use oddio::{Cycle, Gain, Seek, Speed, Stop}; +use oddio::{Cycle, Mixed, Seek, Speed, SpeedControl}; use simulation::physics::CollisionWorld; use simulation::Simulation; use slotmapd::SecondaryMap; /// CarSound is the sound of a single car pub struct CarSound { - road: Option>>>>, - engine: Option>>>>, + road: Option<(SpeedControl, GainControl, Mixed)>, + engine: Option<(SpeedControl, GainControl, Mixed)>, } /// CarSounds are sounds that are played when cars are near the player /// They are tied to a car entity pub struct CarSounds { sounds: SecondaryMap, - generic_car_sound: Option>>>, + generic_car_sound: Option, } impl CarSounds { pub fn new(ctx: &mut AudioContext) -> Self { Self { sounds: SecondaryMap::new(), - generic_car_sound: ctx.play_with_control( - "car_loop", - |x| { - let mut g = Gain::new(Cycle::new(x)); - g.set_amplitude_ratio(0.0); - g - }, - AudioKind::Effect, - ), + generic_car_sound: ctx + .play_with_control( + "car_loop", + |x| Gain::new(Cycle::new(x), 0.0), + AudioKind::Effect, + ) + .map(|x| x.0), } } @@ -63,11 +61,11 @@ impl CarSounds { for h in to_remove { let cs = self.sounds.remove(h).unwrap(); - if let Some(mut road) = cs.road { - road.control::, _>().stop(); + if let Some((_, _, mut mixed)) = cs.road { + mixed.stop(); } - if let Some(mut engine) = cs.engine { - engine.control::, _>().stop(); + if let Some((_, _, mut mixed)) = cs.engine { + mixed.stop(); } } @@ -88,29 +86,33 @@ impl CarSounds { } if !self.sounds.contains_key(h) { - let engine = ctx.play_with_control( - "car_engine", - |x| { - let cycle = Cycle::new(x); - cycle.seek(common::rand::rand2(pos.x, pos.y)); - let mut g = Gain::new(cycle); - g.set_amplitude_ratio(0.0); - Speed::new(g) - }, - AudioKind::Effect, - ); - - let road = ctx.play_with_control( - "car_loop", - |x| { - let cycle = Cycle::new(x); - cycle.seek(common::rand::rand2(pos.x, pos.y)); - let mut g = Gain::new(cycle); - g.set_amplitude_ratio(0.0); - Speed::new(g) - }, - AudioKind::Effect, - ); + let engine = ctx + .play_with_control( + "car_engine", + |x| { + let mut cycle = Cycle::new(x); + cycle.seek(common::rand::rand2(pos.x, pos.y)); + let (g_control, signal) = Gain::new(cycle, 0.0); + let (speed_control, signal) = Speed::new(signal); + ((speed_control, g_control), signal) + }, + AudioKind::Effect, + ) + .map(|((a, b), c)| (a, b, c)); + + let road = ctx + .play_with_control( + "car_loop", + |x| { + let mut cycle = Cycle::new(x); + cycle.seek(common::rand::rand2(pos.x, pos.y)); + let (g_control, signal) = Gain::new(cycle, 0.0); + let (speed_control, signal) = Speed::new(signal); + ((speed_control, g_control), signal) + }, + AudioKind::Effect, + ) + .map(|((a, b), c)| (a, b, c)); self.sounds.insert(h, CarSound { road, engine }); } @@ -126,17 +128,14 @@ impl CarSounds { let speed_to_me = his_speed.dot(dir_to_me); let boost = 300.0 / (300.0 - speed_to_me); - if let Some(ref mut road) = cs.road { - road.control::, _>() - .set_amplitude_ratio(obj.speed.sqrt() * 3.0 / pos.z0().distance(campos)); - road.control::, _>().set_speed(boost) + if let Some((ref mut speed, ref mut gain, _)) = cs.road { + gain.set_amplitude_ratio(obj.speed.sqrt() * 3.0 / pos.z0().distance(campos)); + speed.set_speed(boost) } - if let Some(ref mut engine) = cs.road { - engine - .control::, _>() - .set_amplitude_ratio(obj.speed.sqrt() / pos.z0().distance(campos)); - engine.control::, _>().set_speed(boost) + if let Some((ref mut speed, ref mut gain, _)) = cs.engine { + gain.set_amplitude_ratio(obj.speed.sqrt() / pos.z0().distance(campos)); + speed.set_speed(boost) } } @@ -147,13 +146,13 @@ impl CarSounds { .filter(|(_, obj)| matches!(obj.group, simulation::physics::PhysicsGroup::Vehicles)) .count(); if let Some(ref mut s) = self.generic_car_sound { - s.control::, _>().set_amplitude_ratio( + s.set_amplitude_ratio( ((cars_on_screen as f32).min(100.0) / 100.0 * (1.0 - campos.z / 1000.0)) .min(0.03), ); } } else if let Some(ref mut s) = self.generic_car_sound { - s.control::, _>().set_amplitude_ratio(0.0); + s.set_amplitude_ratio(0.0); } } } diff --git a/native_app/src/audio/music.rs b/native_app/src/audio/music.rs index f4df9250..817868e5 100644 --- a/native_app/src/audio/music.rs +++ b/native_app/src/audio/music.rs @@ -1,6 +1,6 @@ use common::AudioKind; -use engine::{AudioContext, BaseSignal, ControlHandle, FadeIn}; -use oddio::{FramesSignal, Stop}; +use engine::{AudioContext, FadeIn}; +use oddio::{FramesSignal, Mixed}; use std::time::{Duration, Instant}; const TRACKS: &[&str] = &["music2", "music1"]; @@ -10,7 +10,7 @@ pub struct Music { track_id: usize, time_between_tracks: Duration, last_played: Instant, - cur_track: Option>>, + cur_track: Option, } impl Music { @@ -28,7 +28,7 @@ impl Music { return; } if let Some(ref mut x) = self.cur_track { - if !x.control::, _>().is_stopped() { + if !x.is_stopped() { return; } self.cur_track = None; @@ -38,10 +38,10 @@ impl Music { self.track_id = (self.track_id + 1) % TRACKS.len(); let h = ctx.play_with_control( TRACKS[self.track_id], - |s| FadeIn::new(FramesSignal::new(s, 0.0), 5.0), + |s| ((), FadeIn::new(FramesSignal::new(s, 0.0).1, 5.0)), AudioKind::Music, ); - self.cur_track = h; + self.cur_track = h.map(|x| x.1); log::info!("playing soundtrack {}", TRACKS[self.track_id]); self.last_played = Instant::now(); } diff --git a/native_app/src/gui/terraforming.rs b/native_app/src/gui/terraforming.rs index 6bdf96c9..98d20c3b 100644 --- a/native_app/src/gui/terraforming.rs +++ b/native_app/src/gui/terraforming.rs @@ -60,7 +60,7 @@ pub fn terraforming(sim: &Simulation, uiworld: &mut UiWorld) { TerraformKind::Smooth => {} TerraformKind::Level => { // set level on first click - if res.level == None && inp.just_act.contains(&InputAction::Select) { + if res.level.is_none() && inp.just_act.contains(&InputAction::Select) { res.level = Some(mpos.z); } @@ -71,17 +71,16 @@ pub fn terraforming(sim: &Simulation, uiworld: &mut UiWorld) { } TerraformKind::Slope => { // Set the end slope (second click) - if res.slope_start != None - && res.slope_end == None + if res.slope_start.is_some() + && res.slope_end.is_none() && inp.just_act.contains(&InputAction::Select) + && !res.slope_start.unwrap().is_close(mpos, 5.0) { - if !res.slope_start.unwrap().is_close(mpos, 5.0) { - res.slope_end = Some(mpos); - } + res.slope_end = Some(mpos); } // Set the start slope (first click) - if res.slope_start == None && inp.just_act.contains(&InputAction::Select) { + if res.slope_start.is_none() && inp.just_act.contains(&InputAction::Select) { res.slope_start = Some(mpos); } diff --git a/networking/examples/example.rs b/networking/examples/example.rs index c6482a09..9999ea83 100644 --- a/networking/examples/example.rs +++ b/networking/examples/example.rs @@ -28,19 +28,14 @@ impl World { } } -#[derive(Copy, Clone, Serialize, Deserialize, Debug)] +#[derive(Copy, Clone, Serialize, Deserialize, Debug, Default)] enum Action { + #[default] DoNothing, IncrA, IncrB, } -impl Default for Action { - fn default() -> Self { - DoNothing - } -} - const UP_DT: Duration = Duration::from_millis(50); pub fn main() { diff --git a/networking/src/connections.rs b/networking/src/connections.rs index 120aa45a..c7983da0 100644 --- a/networking/src/connections.rs +++ b/networking/src/connections.rs @@ -267,15 +267,15 @@ mod tests { data[4..].copy_from_slice(&vec![1u8; 996]); receiver.recv(&data, |d| assert_eq!(d, vec![1u8; 996])); - receiver.recv(&vec![0u8; 0], |_| assert!(false)); + receiver.recv(&[0u8; 0], |_| panic!("should not be called")); receiver = FramedTcpReceiver::new(); let s = 5u32.to_le_bytes(); - receiver.recv(&s[..2], |_| assert!(false)); - receiver.recv(&s[2..], |_| assert!(false)); - receiver.recv(&vec![1u8; 3], |_| assert!(false)); - receiver.recv(&vec![2u8; 3], |d| { + receiver.recv(&s[..2], |_| panic!("should not be called")); + receiver.recv(&s[2..], |_| panic!("should not be called")); + receiver.recv(&[1u8; 3], |_| panic!("should not be called")); + receiver.recv(&[2u8; 3], |d| { assert_eq!(d, vec![1u8, 1u8, 1u8, 2u8, 2u8]) }); assert_eq!(receiver.buf, vec![2u8]); @@ -289,7 +289,7 @@ mod tests { } else if i == 1 { assert_eq!(d, vec![1, 5]) } else { - assert!(false); + panic!("should not be called"); } i += 1; }); diff --git a/simulation/src/economy/ecostats.rs b/simulation/src/economy/ecostats.rs index 9e7beba8..269120b8 100644 --- a/simulation/src/economy/ecostats.rs +++ b/simulation/src/economy/ecostats.rs @@ -132,6 +132,7 @@ mod tests { use crate::economy::HISTORY_SIZE; #[test] + #[allow(clippy::assertions_on_constants)] fn history_is_not_zero() { assert!(HISTORY_SIZE > 0); } diff --git a/simulation/src/souls/freight_station.rs b/simulation/src/souls/freight_station.rs index 96fd43a7..a3a3c425 100644 --- a/simulation/src/souls/freight_station.rs +++ b/simulation/src/souls/freight_station.rs @@ -219,6 +219,6 @@ mod tests { } } - assert!(false); + panic!("should have delivered to freight station") } } diff --git a/simulation/src/tests/mod.rs b/simulation/src/tests/mod.rs index 1f873c62..c6979b24 100644 --- a/simulation/src/tests/mod.rs +++ b/simulation/src/tests/mod.rs @@ -27,7 +27,6 @@ impl TestCtx { let g = Simulation::new_with_options(SimulationOptions { terrain_size: 1, save_replay: false, - ..Default::default() }); let sched = Simulation::schedule(); diff --git a/simulation/src/tests/test_iso.rs b/simulation/src/tests/test_iso.rs index a9a5b300..cf512e95 100644 --- a/simulation/src/tests/test_iso.rs +++ b/simulation/src/tests/test_iso.rs @@ -278,13 +278,13 @@ fn test_world_survives_serde() { println!("not equal"); deser.save_to_disk("world"); sim.save_to_disk("world2"); - assert!(false); + panic!("not equal"); } if !deser.is_equal(&sim2) { println!("not equal"); deser.save_to_disk("world"); sim2.save_to_disk("world2"); - assert!(false); + panic!("not equal"); } std::mem::swap(&mut deser, &mut sim2);