mirror of
https://github.com/Zenithsiz/zsw.git
synced 2026-02-04 02:08:37 +00:00
Upgraded all dependencies to latest.
This commit is contained in:
parent
2ded22afd7
commit
80f07dfa29
1823
Cargo.lock
generated
1823
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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)]
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"]}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"]}
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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>",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@ -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]
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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,
|
||||
_ => (),
|
||||
},
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ pub use self::args::Args;
|
||||
// Imports
|
||||
use {
|
||||
anyhow::Context,
|
||||
clap::StructOpt,
|
||||
clap::Parser,
|
||||
std::sync::atomic::{self, AtomicUsize},
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user