Upgraded all dependencies to latest.

This commit is contained in:
Filipe Rodrigues 2022-11-20 11:17:09 +00:00
parent 2ded22afd7
commit 80f07dfa29
24 changed files with 1381 additions and 969 deletions

1823
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -8,24 +8,24 @@ version = "0.1.0"
[dependencies]
# Zsw
zsw-util = {path = "../zsw-util"}
zsw-wgpu = {path = "../zsw-wgpu"}
zsw-util = { path = "../zsw-util" }
zsw-wgpu = { path = "../zsw-wgpu" }
# Windowing
winit = "0.26.1"
winit = "0.27.5"
# Gui
egui = "0.16.1"
egui_wgpu_backend = "0.16.0"
egui_winit_platform = "0.13.0"
epi = "0.16.0"
egui = { version = "0.19.0", features = ["default_fonts"] }
egui_wgpu_backend = "0.20.0"
egui_winit_platform = "0.16.0"
epi = "0.17.0"
# Async
futures = "0.3.21"
futures = "0.3.25"
# Error handling
anyhow = "1.0.52"
anyhow = "1.0.66"
# Threads
crossbeam = "0.8.1"
parking_lot = "0.12.0"
crossbeam = "0.8.2"
parking_lot = "0.12.1"

View File

@ -68,14 +68,14 @@ impl Egui {
// Create the resources
// Note: By using a 0-size channel we achieve the least latency
let (paint_jobs_tx, paint_jobs_rx) = mpsc::channel(0);
let (output_tx, output_rx) = mpsc::channel(0);
let platform_resource = EguiPlatformResource { platform };
let render_pass_resource = EguiRenderPassResource {
render_pass,
paint_jobs: vec![],
paint_jobs_rx,
output: egui::FullOutput::default(),
output_rx,
};
let painter_resource = EguiPainterResource { paint_jobs_tx };
let painter_resource = EguiPainterResource { output_tx };
Ok((service, platform_resource, render_pass_resource, painter_resource))
}
@ -85,8 +85,8 @@ impl Egui {
&self,
window: &Window,
platform_resource: &mut EguiPlatformResource,
f: impl FnOnce(&egui::CtxRef, &epi::Frame) -> Result<(), anyhow::Error>,
) -> Result<Vec<egui::ClippedMesh>, anyhow::Error> {
f: impl FnOnce(&egui::Context, &epi::Frame) -> Result<(), anyhow::Error>,
) -> Result<egui::FullOutput, anyhow::Error> {
// Start the frame
let egui_frame_start = Instant::now();
platform_resource.platform.begin_frame();
@ -109,12 +109,11 @@ impl Egui {
// Then draw using it
f(&platform_resource.platform.context(), &egui_frame).context("Unable to draw")?;
// Finally end the frame and retrieve the paint jobs
let (_output, paint_commands) = platform_resource.platform.end_frame(Some(window));
let paint_jobs = platform_resource.platform.context().tessellate(paint_commands);
// Finally end the frame and retrieve the output
let full_output = platform_resource.platform.end_frame(Some(window));
self.frame_time.store(Some(egui_frame_start.elapsed()));
Ok(paint_jobs)
Ok(full_output)
}
/// Handles an event
@ -122,42 +121,40 @@ impl Egui {
platform_resource.platform.handle_event(event);
}
/*
/// Returns the font image
pub fn font_image(&self, platform_resource: &EguiPlatformResource) -> Arc<egui::FontImage> {
platform_resource.platform.context().font_image()
}
*/
/// Returns the render pass and paint jobs
pub fn render_pass_with_paint_jobs<'a>(
/// Returns the render pass and output
pub fn render_pass_with_output<'a>(
&self,
render_pass_resource: &'a mut EguiRenderPassResource,
) -> (&'a mut egui_wgpu_backend::RenderPass, &'a [egui::ClippedMesh]) {
// If we have any new paint jobs, update them
) -> (&'a mut egui_wgpu_backend::RenderPass, &'a egui::FullOutput) {
// If we have a new output, update them
// TODO: Not panic here when the painter quit
if let Ok(paint_jobs) = render_pass_resource
.paint_jobs_rx
if let Ok(output) = render_pass_resource
.output_rx
.try_next()
.transpose()
.expect("Egui painter quit")
{
render_pass_resource.paint_jobs = paint_jobs;
render_pass_resource.output = output;
}
(&mut render_pass_resource.render_pass, &render_pass_resource.paint_jobs)
(&mut render_pass_resource.render_pass, &render_pass_resource.output)
}
/// Updates the paint jobs
/// Updates the output
///
/// Returns `Err` if they haven't been fetched yet
pub async fn update_paint_jobs(
&self,
painter_resource: &mut EguiPainterResource,
paint_jobs: Vec<egui::ClippedMesh>,
) {
/// Returns `Err` if it hasn't been fetched yet
pub async fn update_output(&self, painter_resource: &mut EguiPainterResource, output: egui::FullOutput) {
// TDO: Not panic
painter_resource
.paint_jobs_tx
.send(paint_jobs)
.output_tx
.send(output)
.await
.expect("Egui renderer quit");
}
@ -166,7 +163,8 @@ impl Egui {
/// Platform resource
pub struct EguiPlatformResource {
/// Platform
platform: egui_winit_platform::Platform,
// TODO: Not pub?
pub platform: egui_winit_platform::Platform,
}
impl std::fmt::Debug for EguiPlatformResource {
@ -180,11 +178,11 @@ pub struct EguiRenderPassResource {
/// Render pass
render_pass: egui_wgpu_backend::RenderPass,
/// Current paint jobs
paint_jobs: Vec<egui::ClippedMesh>,
/// Current output
output: egui::FullOutput,
/// Paint jobs receiver
paint_jobs_rx: mpsc::Receiver<Vec<egui::ClippedMesh>>,
/// Output receiver
output_rx: mpsc::Receiver<egui::FullOutput>,
}
impl std::fmt::Debug for EguiRenderPassResource {
@ -196,10 +194,15 @@ impl std::fmt::Debug for EguiRenderPassResource {
}
/// Painter resource
#[derive(Debug)]
pub struct EguiPainterResource {
/// Paint jobs sender
paint_jobs_tx: mpsc::Sender<Vec<egui::ClippedMesh>>,
/// Output sender
output_tx: mpsc::Sender<egui::FullOutput>,
}
impl std::fmt::Debug for EguiPainterResource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EguiPainterResource").field("output_tx", &"..").finish()
}
}
/// Repaint signal

View File

@ -12,16 +12,16 @@ zsw-playlist = {path = "../zsw-playlist"}
zsw-util = {path = "../zsw-util"}
# Async
async-channel = "1.6.1"
async-channel = "1.7.1"
# Math
cgmath = {version = "0.18.0", features = ["serde"]}
# Image
image = "0.23.14"
image = "0.24.5"
# Error handling
anyhow = "1.0.52"
anyhow = "1.0.66"
# Logging
tracing = "0.1.32"
tracing = "0.1.37"

View File

@ -10,11 +10,7 @@ pub mod loader;
pub use loader::ImageLoaderService;
// Imports
use {
cgmath::Vector2,
image::{DynamicImage, GenericImageView},
std::path::PathBuf,
};
use {cgmath::Vector2, image::DynamicImage, std::path::PathBuf};
/// Loaded image
#[derive(Debug)]

View File

@ -8,13 +8,13 @@ version = "0.1.0"
[dependencies]
# Windowing
winit = "0.26.1"
winit = "0.27.5"
# Async
futures = "0.3.21"
futures = "0.3.25"
# Math
cgmath = {version = "0.18.0", features = ["serde"]}
# Threads
crossbeam = "0.8.1"
crossbeam = "0.8.2"

View File

@ -14,36 +14,36 @@ zsw-util = {path = "../zsw-util"}
zsw-wgpu = {path = "../zsw-wgpu"}
# Windowing
winit = "0.26.1"
winit = "0.27.5"
# Rendering
wgpu = {version = "0.12.0", features = ["serde", "replay"]}
wgpu = {version = "0.14.0", features = ["serde", "replay"]}
# Async
futures = "0.3.21"
futures = "0.3.25"
# Serialization
serde = {version = "1.0.132", features = ["derive"]}
serde = {version = "1.0.147", features = ["derive"]}
# Math
cgmath = {version = "0.18.0", features = ["serde"]}
# Image
image = "0.23.14"
image = "0.24.5"
# Random
rand = "0.8.4"
rand = "0.8.5"
# Error handling
anyhow = "1.0.52"
anyhow = "1.0.66"
# Logging
tracing = "0.1.32"
tracing = "0.1.37"
# Util
bytemuck = {version = "1.7.3", features = ["derive"]}
num-rational = "0.4.0"
bytemuck = {version = "1.12.3", features = ["derive"]}
num-rational = "0.4.1"
# Threads
crossbeam = "0.8.1"
parking_lot = {version = "0.12.0", features = ["deadlock_detection"]}
crossbeam = "0.8.2"
parking_lot = {version = "0.12.1", features = ["deadlock_detection"]}

View File

@ -5,7 +5,7 @@ use {
super::PanelUniforms,
crate::PanelsRenderer,
cgmath::Vector2,
image::{DynamicImage, GenericImageView},
image::DynamicImage,
std::path::{Path, PathBuf},
wgpu::util::DeviceExt,
zsw_img::Image,

View File

@ -92,7 +92,7 @@ impl PanelsRenderer {
// Create the render pass for all panels
let render_pass_descriptor = wgpu::RenderPassDescriptor {
label: Some("[zsw::panel] Render pass"),
color_attachments: &[wgpu::RenderPassColorAttachment {
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: surface_view,
resolve_target: None,
ops: wgpu::Operations {
@ -104,7 +104,7 @@ impl PanelsRenderer {
}),
store: true,
},
}],
})],
depth_stencil_attachment: None,
};
let mut render_pass = encoder.begin_render_pass(&render_pass_descriptor);
@ -220,7 +220,7 @@ fn create_render_pipeline(
label: Some("[zsw::panel] Shader"),
source: wgpu::ShaderSource::Wgsl(include_str!("renderer/shader.wgsl").into()),
};
let shader = device.create_shader_module(&shader_descriptor);
let shader = device.create_shader_module(shader_descriptor);
// Create the pipeline layout
let render_pipeline_layout_descriptor = wgpu::PipelineLayoutDescriptor {
@ -230,11 +230,11 @@ fn create_render_pipeline(
};
let render_pipeline_layout = device.create_pipeline_layout(&render_pipeline_layout_descriptor);
let color_targets = [wgpu::ColorTargetState {
let color_targets = [Some(wgpu::ColorTargetState {
format: surface_texture_format,
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
write_mask: wgpu::ColorWrites::ALL,
}];
})];
let render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
label: Some("[zsw::panel] Render pipeline"),
layout: Some(&render_pipeline_layout),

View File

@ -1,58 +1,58 @@
// Vertex input
struct VertexInput {
[[location(0)]]
pos: vec2<f32>;
[[location(1)]]
uvs: vec2<f32>;
@location(0)
pos: vec2<f32>,
@location(1)
uvs: vec2<f32>,
};
// Vertex output
struct VertexOutput {
[[builtin(position)]]
pos: vec4<f32>;
[[location(0)]]
uvs: vec2<f32>;
@builtin(position)
pos: vec4<f32>,
@location(0)
uvs: vec2<f32>,
};
// Uniforms
struct Uniforms {
pos_matrix: mat4x4<f32>;
uvs_matrix: mat4x4<f32>;
alpha: f32;
pos_matrix: mat4x4<f32>,
uvs_matrix: mat4x4<f32>,
alpha: f32,
};
// Uniforms
[[group(0), binding(0)]]
@group(0) @binding(0)
var<uniform> uniforms: Uniforms;
[[stage(vertex)]]
@vertex
fn vs_main(in: VertexInput) -> VertexOutput {
var out: VertexOutput;
out.pos = uniforms.pos_matrix * vec4<f32>(in.pos, 0.0, 1.0);
out.uvs = in.uvs;
return out;
}
// Frag output
struct FragOutput {
[[location(0)]]
color: vec4<f32>;
@location(0)
color: vec4<f32>,
};
// Texture
[[group(1), binding(0)]]
@group(1) @binding(0)
var texture: texture_2d<f32>;
// Sampler
[[group(1), binding(1)]]
@group(1) @binding(1)
var texture_sampler: sampler;
[[stage(fragment)]]
@fragment
fn fs_main(in: VertexOutput) -> FragOutput {
var out: FragOutput;

View File

@ -11,15 +11,15 @@ version = "0.1.0"
zsw-util = { path = "../zsw-util" }
# Async
async-channel = "1.6.1"
futures = "0.3.21"
async-channel = "1.7.1"
futures = "0.3.25"
# Util
parking_lot = "0.12.0"
parking_lot = "0.12.1"
crossbeam = "0.8.2"
# Logging
tracing = "0.1.32"
tracing = "0.1.37"
# Random
rand = "0.8.4"
rand = "0.8.5"

View File

@ -13,16 +13,16 @@ zsw-playlist = {path = "../zsw-playlist"}
zsw-util = {path = "../zsw-util"}
# Async
futures = "0.3.21"
futures = "0.3.25"
# Serialization
serde = {version = "1.0.132", features = ["derive"]}
serde = {version = "1.0.147", features = ["derive"]}
# Error handling
anyhow = "1.0.52"
anyhow = "1.0.66"
# Logging
tracing = "0.1.32"
tracing = "0.1.37"
# Threads
parking_lot = {version = "0.12.0", features = ["deadlock_detection"]}
parking_lot = {version = "0.12.1", features = ["deadlock_detection"]}

View File

@ -16,18 +16,18 @@ zsw-util = {path = "../zsw-util"}
zsw-wgpu = {path = "../zsw-wgpu"}
# Windowing
winit = "0.26.1"
winit = "0.27.5"
# Gui
egui_wgpu_backend = "0.16.0"
egui_wgpu_backend = "0.20.0"
# Async
futures = "0.3.21"
pollster = "0.2.4"
tokio = "1.17.0"
futures = "0.3.25"
pollster = "0.2.5"
tokio = "1.22.0"
# Error handling
anyhow = "1.0.52"
anyhow = "1.0.66"
# Logging
tracing = "0.1.32"
tracing = "0.1.37"

View File

@ -6,7 +6,7 @@
// Imports
use {
anyhow::Context,
std::{mem, time::Duration},
std::time::Duration,
tokio::time::Instant,
winit::window::Window,
zsw_egui::{Egui, EguiPlatformResource, EguiRenderPassResource},
@ -156,35 +156,45 @@ impl Renderer {
// Get the egui render results
// DEADLOCK: Caller ensures we can lock it.
let mut render_pass_resource = resources.resource::<EguiRenderPassResource>().await;
let (egui_render_pass, egui_paint_jobs) = egui.render_pass_with_paint_jobs(&mut render_pass_resource);
let (egui_render_pass, egui_output) = egui.render_pass_with_output(&mut render_pass_resource);
// If we have any paint jobs, draw egui
if !egui_paint_jobs.is_empty() {
let font_image = {
{
// Update textures
egui_render_pass
.add_textures(wgpu.device(), wgpu.queue(), &egui_output.textures_delta)
.context("Unable to update textures")?;
// Update buffers
let paint_jobs = {
// DEADLOCK: Caller ensures we can lock it after the egui render pass lock
let platform_resource = resources.resource::<EguiPlatformResource>().await;
egui.font_image(&platform_resource)
platform_resource
.platform
.context()
.tessellate(egui_output.shapes.clone())
};
egui_render_pass.update_texture(wgpu.device(), wgpu.queue(), &font_image);
egui_render_pass.update_user_textures(wgpu.device(), wgpu.queue());
egui_render_pass.update_buffers(wgpu.device(), wgpu.queue(), egui_paint_jobs, &screen_descriptor);
egui_render_pass.update_buffers(wgpu.device(), wgpu.queue(), &paint_jobs, &screen_descriptor);
// Record all render passes.
egui_render_pass
.execute(
&mut frame.encoder,
&frame.surface_view,
egui_paint_jobs,
&paint_jobs,
&screen_descriptor,
None,
)
.context("Unable to render egui")?;
}
mem::drop(render_pass_resource);
//mem::drop(render_pass_resource);
wgpu.finish_render(frame);
egui_render_pass
.remove_textures(egui_output.textures_delta.clone())
.context("Unable to update textures")?;
Ok(())
}
}

View File

@ -8,37 +8,37 @@ version = "0.1.0"
[dependencies]
# Zsw
zsw-egui = {path = "../zsw-egui"}
zsw-panels = {path = "../zsw-panels"}
zsw-playlist = {path = "../zsw-playlist"}
zsw-profiles = {path = "../zsw-profiles"}
zsw-renderer = {path = "../zsw-renderer"}
zsw-util = {path = "../zsw-util"}
zsw-wgpu = {path = "../zsw-wgpu"}
zsw-egui = { path = "../zsw-egui" }
zsw-panels = { path = "../zsw-panels" }
zsw-playlist = { path = "../zsw-playlist" }
zsw-profiles = { path = "../zsw-profiles" }
zsw-renderer = { path = "../zsw-renderer" }
zsw-util = { path = "../zsw-util" }
zsw-wgpu = { path = "../zsw-wgpu" }
# Windowing
winit = "0.26.1"
winit = "0.27.5"
# Gui
egui = "0.16.1"
epi = "0.16.0"
egui = { version = "0.19.0", features = ["default_fonts"] }
epi = "0.17.0"
# Async
async-channel = "1.6.1"
futures = "0.3.21"
pollster = "0.2.4"
async-channel = "1.7.1"
futures = "0.3.25"
pollster = "0.2.5"
# Math
cgmath = {version = "0.18.0", features = ["serde"]}
cgmath = { version = "0.18.0", features = ["serde"] }
# Error handling
anyhow = "1.0.52"
anyhow = "1.0.66"
# Logging
tracing = "0.1.32"
tracing = "0.1.37"
# Filesystem
native-dialog = "0.6.3"
# Threads
crossbeam = "0.8.1"
crossbeam = "0.8.2"

View File

@ -12,7 +12,7 @@
// Imports
use {
cgmath::{Point2, Vector2},
egui::{plot, Widget},
egui::Widget,
futures::lock::Mutex,
winit::{
dpi::{PhysicalPosition, PhysicalSize},
@ -80,7 +80,7 @@ impl SettingsWindow {
/// - [`zsw_profiles::ProfilesLock`] on `profiles`
/// - [`zsw_playlist::PlaylistLock`] on `playlist`
/// - [`zsw_panels::PanelsLock`] on `panels`
/// Blocks until [`Self::update_paint_jobs`] on `egui` is called.
/// Blocks until [`Self::update_output`] on `egui` is called.
pub async fn run<S, R>(
&self,
services: &S,
@ -133,9 +133,9 @@ impl SettingsWindow {
})
};
// Try to update the paint jobs
// Try to update the output
match res {
Ok(paint_jobs) => egui.update_paint_jobs(egui_painter_resource, paint_jobs).await,
Ok(output) => egui.update_output(egui_painter_resource, output).await,
Err(err) => tracing::warn!(?err, "Unable to draw egui"),
}
}
@ -144,7 +144,7 @@ impl SettingsWindow {
/// Draws the settings window
fn draw<'panels>(
inner: &mut Inner,
ctx: &egui::CtxRef,
ctx: &egui::Context,
_frame: &epi::Frame,
surface_size: PhysicalSize<u32>,
window: &Window,
@ -449,26 +449,9 @@ impl<'panel> egui::Widget for PanelWidget<'panel> {
egui::Slider::new(&mut self.panel.panel.parallax_ratio, 0.0..=1.0).ui(ui);
});
ui.vertical(|ui| {
ui.horizontal(|ui| {
ui.label("Parallax exp");
egui::Slider::new(&mut self.panel.panel.parallax_exp, 0.0..=4.0).ui(ui);
});
ui.collapsing("Graph", |ui| {
let it = (0..=100).map(|i| {
let x = i as f32 / 100.0;
plot::Value::new(x, x.signum() * x.abs().powf(self.panel.panel.parallax_exp))
});
let line = plot::Line::new(plot::Values::from_values_iter(it));
plot::Plot::new("Frame timings (ms)")
.allow_drag(false)
.allow_zoom(false)
.show_background(false)
.view_aspect(1.0)
.show(ui, |plot_ui| plot_ui.line(line));
});
ui.horizontal(|ui| {
ui.label("Parallax exp");
egui::Slider::new(&mut self.panel.panel.parallax_exp, 0.0..=4.0).ui(ui);
});

View File

@ -10,24 +10,24 @@ version = "0.1.0"
# Zsw
# Image
image = "0.23.14"
image = "0.24.5"
# Async
futures = "0.3.21"
futures = "0.3.25"
# Math
cgmath = {version = "0.18.0", features = ["serde"]}
# Error
anyhow = "1.0.52"
anyhow = "1.0.66"
# Serde
serde = "1.0.132"
serde_json = "1.0.73"
serde = "1.0.147"
serde_json = "1.0.88"
# Logging
tracing = "0.1.32"
tracing = "0.1.37"
# Threads
crossbeam = "0.8.1"
parking_lot = "0.12.0"
crossbeam = "0.8.2"
parking_lot = "0.12.1"

View File

@ -151,12 +151,11 @@ pub fn image_format(image: &DynamicImage) -> &'static str {
DynamicImage::ImageLumaA8(_) => "LumaA8",
DynamicImage::ImageRgb8(_) => "Rgb8",
DynamicImage::ImageRgba8(_) => "Rgba8",
DynamicImage::ImageBgr8(_) => "Bgr8",
DynamicImage::ImageBgra8(_) => "Bgra8",
DynamicImage::ImageLuma16(_) => "Luma16",
DynamicImage::ImageLumaA16(_) => "LumaA16",
DynamicImage::ImageRgb16(_) => "Rgb16",
DynamicImage::ImageRgba16(_) => "Rgba16",
_ => "<unknown>",
}
}

View File

@ -11,21 +11,21 @@ version = "0.1.0"
zsw-util = {path = "../zsw-util"}
# Windowing
winit = "0.26.1"
winit = "0.27.5"
# Rendering
wgpu = {version = "0.12.0", features = ["serde", "replay"]}
wgpu = {version = "0.14.0", features = ["serde", "replay"]}
# Async
futures = "0.3.21"
pollster = "0.2.4"
futures = "0.3.25"
pollster = "0.2.5"
# Error handling
anyhow = "1.0.52"
anyhow = "1.0.66"
# Logging
tracing = "0.1.32"
tracing = "0.1.37"
# Threads
crossbeam = "0.8.1"
parking_lot = "0.12.0"
crossbeam = "0.8.2"
parking_lot = "0.12.1"

View File

@ -172,7 +172,7 @@ impl Wgpu {
/// Finishes rendering a frame
pub fn finish_render(&self, frame: FrameRender) {
// Submit everything to the queue and present the surface's texture
self.queue.submit([frame.encoder.finish()]);
let _ = self.queue.submit([frame.encoder.finish()]);
frame.surface_texture.present();
}
}
@ -198,9 +198,10 @@ fn configure_window_surface(
device: &wgpu::Device,
) -> Result<(TextureFormat, PhysicalSize<u32>), anyhow::Error> {
// Get the format
let surface_texture_format = surface
.get_preferred_format(adapter)
.context("Unable to query preferred format")?;
let surface_texture_format = *surface
.get_supported_formats(adapter)
.first()
.context("No supported texture formats for surface found")?;
tracing::debug!(?surface_texture_format, "Found preferred surface format");
// Then configure it
@ -293,5 +294,6 @@ const fn window_surface_configuration(
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Mailbox,
alpha_mode: wgpu::CompositeAlphaMode::Auto,
}
}

View File

@ -7,66 +7,66 @@ version = "0.1.0"
[dependencies]
# Zsw
zsw-egui = {path = "../zsw-egui"}
zsw-img = {path = "../zsw-img"}
zsw-input = {path = "../zsw-input"}
zsw-panels = {path = "../zsw-panels"}
zsw-playlist = {path = "../zsw-playlist"}
zsw-profiles = {path = "../zsw-profiles"}
zsw-renderer = {path = "../zsw-renderer"}
zsw-settings-window = {path = "../zsw-settings-window"}
zsw-util = {path = "../zsw-util"}
zsw-wgpu = {path = "../zsw-wgpu"}
zsw-egui = { path = "../zsw-egui" }
zsw-img = { path = "../zsw-img" }
zsw-input = { path = "../zsw-input" }
zsw-panels = { path = "../zsw-panels" }
zsw-playlist = { path = "../zsw-playlist" }
zsw-profiles = { path = "../zsw-profiles" }
zsw-renderer = { path = "../zsw-renderer" }
zsw-settings-window = { path = "../zsw-settings-window" }
zsw-util = { path = "../zsw-util" }
zsw-wgpu = { path = "../zsw-wgpu" }
# Windowing
winit = "0.26.1"
winit = "0.27.5"
# Rendering
wgpu = {version = "0.12.0", features = ["serde", "replay"]}
wgpu = { version = "0.14.0", features = ["serde", "replay"] }
# Gui
egui = "0.16.1"
egui_wgpu_backend = "0.16.0"
egui_winit_platform = "0.13.0"
epi = "0.16.0"
egui = { version = "0.19.0", features = ["default_fonts"] }
egui_wgpu_backend = "0.20.0"
egui_winit_platform = "0.16.0"
epi = "0.17.0"
# Async
async-channel = "1.6.1"
console-subscriber = {version = "0.1.3", optional = true}
futures = "0.3.21"
pollster = "0.2.4"
tokio = {version = "1.17.0", features = ["full", "tracing"]}
async-channel = "1.7.1"
console-subscriber = { version = "0.1.8", optional = true }
futures = "0.3.25"
pollster = "0.2.5"
tokio = { version = "1.22.0", features = ["full", "tracing"] }
# Serialization
serde = {version = "1.0.132", features = ["derive"]}
serde_json = "1.0.73"
serde = { version = "1.0.147", features = ["derive"] }
serde_json = "1.0.88"
# Math
cgmath = {version = "0.18.0", features = ["serde"]}
cgmath = { version = "0.18.0", features = ["serde"] }
# Image
image = "0.23.14"
image = "0.24.5"
# Random
rand = "0.8.4"
rand = "0.8.5"
# Error handling
anyhow = "1.0.52"
thiserror = "1.0.30"
anyhow = "1.0.66"
thiserror = "1.0.37"
# Logging
chrono = "0.4.19"
fern = {version = "0.6.0", features = ["colored"]}
tracing = "0.1.32"
tracing-subscriber = {version = "0.3.10", features = ["json", "parking_lot"]}
chrono = "0.4.23"
fern = { version = "0.6.1", features = ["colored"] }
tracing = "0.1.37"
tracing-subscriber = { version = "0.3.16", features = ["json", "parking_lot"] }
# Cmd
clap = {version = "3.0.7", features = ["derive"]}
clap = { version = "4.0.26", features = ["derive"] }
# Util
bytemuck = {version = "1.7.3", features = ["derive"]}
bytemuck = { version = "1.12.3", features = ["derive"] }
#num-rational = "0.4.0"
duplicate = "0.4.0"
duplicate = "0.4.1"
# Filesystem
# TODO: Use `notify` once issues with it using `std`'s `mpsc` are fixed
@ -74,9 +74,9 @@ duplicate = "0.4.0"
native-dialog = "0.6.3"
# Threads
crossbeam = "0.8.1"
parking_lot = {version = "0.12.0", features = ["deadlock_detection"]}
rayon = "1.5.1"
crossbeam = "0.8.2"
parking_lot = { version = "0.12.1", features = ["deadlock_detection"] }
rayon = "1.6.0"
[features]

View File

@ -25,7 +25,7 @@ use {
tokio::task,
winit::{
dpi::{PhysicalPosition, PhysicalSize},
event_loop::EventLoop,
event_loop::{EventLoop, EventLoopBuilder},
platform::{
run_return::EventLoopExtRunReturn,
unix::{WindowBuilderExtUnix, XWindowType},
@ -71,10 +71,11 @@ pub async fn run(args: &Args) -> Result<(), anyhow::Error> {
playlist_manager,
profiles_manager,
args,
);
)
.context("Unable to spawn all tasks")?;
// Run the event loop until exit
event_loop.run_return(|event, _, control_flow| {
let _ = event_loop.run_return(|event, _, control_flow| {
event_handler
.handle_event(&*services, &*resources, event, control_flow)
.block_on();
@ -180,7 +181,7 @@ pub fn spawn_services(
playlist_manager: PlaylistManager,
profiles_manager: ProfilesManager,
args: &Args,
) -> impl Future<Output = Result<(), anyhow::Error>> {
) -> Result<impl Future<Output = Result<(), anyhow::Error>>, anyhow::Error> {
/// Macro to help spawn a service runner
macro spawn_service_runner([$($clones:ident),* $(,)?] $name:expr => $runner:expr) {{
$(
@ -190,45 +191,54 @@ pub fn spawn_services(
}}
// Spawn all
let profiles_loader_task = args.profile.clone().map(|profile_path| {
spawn_service_runner!(
[services, resources, playlist_manager, profiles_manager] "Profiles loader" => async move {
// Try to load the profile
let profile = match profiles_manager.load(profile_path) {
Ok(profile) => profile,
Err(err) => {
tracing::warn!(?err, "Unable to load profile");
return;
}
};
let profiles_loader_task = args
.profile
.clone()
.map(|profile_path| {
spawn_service_runner!(
[services, resources, playlist_manager, profiles_manager] "Profiles loader" => async move {
// Try to load the profile
let profile = match profiles_manager.load(profile_path) {
Ok(profile) => profile,
Err(err) => {
tracing::warn!(?err, "Unable to load profile");
return;
}
};
// Then apply it
let mut panels_resource = resources.panels.lock().await;
profile.apply(&playlist_manager, &services.panels, &mut panels_resource);
}
)
});
// Then apply it
let mut panels_resource = resources.panels.lock().await;
profile.apply(&playlist_manager, &services.panels, &mut panels_resource);
}
)
})
.transpose()
.context("Unable to spawn profile loader task")?;
let playlist_runner_task = task::Builder::new()
.name("Playlist runner")
.spawn_blocking(move || playlist_runner.run());
.spawn_blocking(move || playlist_runner.run())
.context("Unable to spawn playlist runner task")?;
// TODO: Use spawn_blocking for these
let image_loader_tasks = (0..self::image_loader_tasks())
.map(|idx| {
spawn_service_runner!(
[services, playlist_receiver] &format!("Image loader #{idx}") => services.image_loader.run(playlist_receiver)
)
})
.collect::<Vec<_>>();
.collect::<Result<Vec<_>, _>>()
.context("Unable to spawn image loader tasks")?;
let settings_window_task = spawn_service_runner!(
[services, resources] "Settings window runner" => services.settings_window.run(&*services, &*resources, &mut resources_mut.egui_painter, playlist_manager, profiles_manager)
);
).context("Unable to spawn settings window task")?;
let renderer_task =
spawn_service_runner!([services, resources] "Renderer" => services.renderer.run(&*services, &*resources));
spawn_service_runner!([services, resources] "Renderer" => services.renderer.run(&*services, &*resources))
.context("Unable to spawn renderer task")?;
// Then create the join future
async move {
Ok(async move {
if let Some(task) = profiles_loader_task {
task.await.context("Unable to await for profiles loader runner")?;
}
@ -243,13 +253,13 @@ pub fn spawn_services(
.context("Unable to await for settings window runner")?;
renderer_task.await.context("Unable to await for renderer runner")?;
Ok(())
}
})
}
/// Creates the window, as well as the associated event loop
fn create_window() -> Result<(EventLoop<!>, Window), anyhow::Error> {
// Build the window
let event_loop = EventLoop::with_user_event();
let event_loop = EventLoopBuilder::with_user_event().build();
// Find the window geometry
// Note: We just merge all monitors' geometry.

View File

@ -97,18 +97,12 @@ async fn handle_event(
WindowEvent::CursorMoved { position, .. } => input.update_cursor_pos(position),
// If right clicked, queue a click
// Note: If the window is open, we don't notify the settings_window, else
// we don't notify egui instead
// TODO: Don't queue the open click here? Feels kinda hacky
WindowEvent::MouseInput {
state: winit::event::ElementState::Pressed,
button: winit::event::MouseButton::Right,
..
} => match settings_window.is_open().await {
true => event_status.update_egui = false,
false => settings_window.queue_open_click(input.cursor_pos()).await,
},
} => settings_window.queue_open_click(input.cursor_pos()).await,
_ => (),
},

View File

@ -27,7 +27,7 @@ pub use self::args::Args;
// Imports
use {
anyhow::Context,
clap::StructOpt,
clap::Parser,
std::sync::atomic::{self, AtomicUsize},
};