Fix most warnings and clippy lints
ci/woodpecker/push/build Pipeline was successful Details

This commit is contained in:
SeanOMik 2023-10-22 21:49:31 -04:00
parent 04d47c34bc
commit 63df35f8fc
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
23 changed files with 170 additions and 186 deletions

View File

@ -1,6 +1,5 @@
use std::{sync::Arc, path::{Path, PathBuf}}; use std::{sync::Arc, path::PathBuf};
use base64::Engine;
use thiserror::Error; use thiserror::Error;
use crate::{ResourceLoader, LoaderError, Mesh, Model, MeshVertexAttribute, VertexAttributeData, Resource, Material, MeshIndices, ResourceManager, util}; use crate::{ResourceLoader, LoaderError, Mesh, Model, MeshVertexAttribute, VertexAttributeData, Resource, Material, MeshIndices, ResourceManager, util};
@ -27,6 +26,7 @@ impl From<ModelLoaderError> for LoaderError {
} }
} }
#[allow(dead_code)]
pub(crate) struct GltfLoadContext<'a> { pub(crate) struct GltfLoadContext<'a> {
pub resource_manager: &'a mut ResourceManager, pub resource_manager: &'a mut ResourceManager,
pub gltf: &'a gltf::Gltf, pub gltf: &'a gltf::Gltf,
@ -161,15 +161,15 @@ impl ResourceLoader for ModelLoader {
let gltf = gltf::Gltf::open(path)?; let gltf = gltf::Gltf::open(path)?;
let mut use_bin = false; let mut use_bin = false;
let buffers: Vec<Vec<u8>> = gltf.buffers().map(|b| match b.source() { let buffers: Vec<Vec<u8>> = gltf.buffers().flat_map(|b| match b.source() {
gltf::buffer::Source::Bin => { gltf::buffer::Source::Bin => {
use_bin = true; use_bin = true;
gltf.blob.as_deref().map(|v| v.to_vec()) gltf.blob.as_deref().map(|v| v.to_vec())
.ok_or(ModelLoaderError::MissingBin(path.to_string())) .ok_or(ModelLoaderError::MissingBin(path.to_string()))
}, },
gltf::buffer::Source::Uri(uri) => util::gltf_read_buffer_uri(&parent_path, uri) gltf::buffer::Source::Uri(uri) => util::gltf_read_buffer_uri(&parent_path, uri)
.map_err(|e| ModelLoaderError::UriDecodingError(e)), .map_err(ModelLoaderError::UriDecodingError),
}).flatten().collect(); }).collect();
// TODO: Read in multiple scenes // TODO: Read in multiple scenes
let scene = gltf.scenes().next().unwrap(); let scene = gltf.scenes().next().unwrap();
@ -186,13 +186,14 @@ impl ResourceLoader for ModelLoader {
.map(|mat| Material::from_gltf(&mut context, mat)).collect(); .map(|mat| Material::from_gltf(&mut context, mat)).collect();
let meshes: Vec<Mesh> = scene.nodes() let meshes: Vec<Mesh> = scene.nodes()
.map(|node| self.process_node(&buffers, &materials, node)) .flat_map(|node| self.process_node(&buffers, &materials, node))
.flatten().collect(); .collect();
debug!("Loaded {} meshes, and {} materials from '{}'", meshes.len(), materials.len(), path); debug!("Loaded {} meshes, and {} materials from '{}'", meshes.len(), materials.len(), path);
Ok(Arc::new(Resource::with_data(path, Model::new(meshes)))) Ok(Arc::new(Resource::with_data(path, Model::new(meshes))))
} }
#[allow(unused_variables)]
fn load_bytes(&self, resource_manager: &mut ResourceManager, bytes: Vec<u8>, offset: usize, length: usize) -> Result<Arc<dyn crate::ResourceStorage>, LoaderError> { fn load_bytes(&self, resource_manager: &mut ResourceManager, bytes: Vec<u8>, offset: usize, length: usize) -> Result<Arc<dyn crate::ResourceStorage>, LoaderError> {
todo!() todo!()
} }

View File

@ -1,6 +1,6 @@
use std::{fs::File, io::{BufReader, Read}, collections::hash_map::DefaultHasher, hash::{Hash, Hasher}}; use std::{collections::hash_map::DefaultHasher, hash::{Hash, Hasher}};
use crate::{Texture, ResHandle, ResourceManager, util, loader::model::GltfLoadContext}; use crate::{Texture, ResHandle, util, loader::model::GltfLoadContext};
/// PBR metallic roughness /// PBR metallic roughness
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
@ -128,6 +128,7 @@ pub struct Material {
//pub texture: Option<ResHandle<Texture>>, //pub texture: Option<ResHandle<Texture>>,
} }
#[allow(dead_code)]
impl Material { impl Material {
/// Get a uri's identifier /// Get a uri's identifier
/// ///
@ -142,7 +143,7 @@ impl Material {
fn source_ident(gltf_rel_path: &str, src: &gltf::image::Source) -> Option<String> { fn source_ident(gltf_rel_path: &str, src: &gltf::image::Source) -> Option<String> {
match src { match src {
gltf::image::Source::View { view, mime_type } => { gltf::image::Source::View { view, mime_type: _ } => {
let buf = view.buffer(); let buf = view.buffer();
let src = buf.source(); let src = buf.source();
@ -153,7 +154,7 @@ impl Material {
} }
} }
}, },
gltf::image::Source::Uri { uri, mime_type } => { gltf::image::Source::Uri { uri, mime_type: _ } => {
Some(Material::uri_ident(gltf_rel_path, uri)) Some(Material::uri_ident(gltf_rel_path, uri))
}, },
} }

View File

@ -17,6 +17,10 @@ impl MeshIndices {
MeshIndices::U32(v) => v.len(), MeshIndices::U32(v) => v.len(),
} }
} }
pub fn is_empty(&self) -> bool {
self.len() == 0
}
} }
/* impl From<Vec<u8>> for MeshIndices { /* impl From<Vec<u8>> for MeshIndices {

View File

@ -1,4 +1,4 @@
use std::{sync::Arc, collections::{HashMap, hash_map::DefaultHasher}, hash::{Hash, Hasher}, any::Any}; use std::{sync::Arc, collections::HashMap, any::Any};
use thiserror::Error; use thiserror::Error;
@ -51,11 +51,17 @@ pub struct ResourceManager {
loaders: Vec<Arc<dyn ResourceLoader>>, loaders: Vec<Arc<dyn ResourceLoader>>,
} }
impl Default for ResourceManager {
fn default() -> Self {
Self::new()
}
}
impl ResourceManager { impl ResourceManager {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
resources: HashMap::new(), resources: HashMap::new(),
loaders: vec![ Arc::new(ImageLoader::default()), Arc::new(ModelLoader::default()) ], loaders: vec![ Arc::new(ImageLoader), Arc::new(ModelLoader) ],
} }
} }
@ -72,7 +78,7 @@ impl ResourceManager {
.find(|l| l.does_support_file(path)) { .find(|l| l.does_support_file(path)) {
// Load the resource and store it // Load the resource and store it
let loader = Arc::clone(&loader); // stop borrowing from self let loader = Arc::clone(loader); // stop borrowing from self
let res = loader.load(self, path)?; let res = loader.load(self, path)?;
self.resources.insert(path.to_string(), res.clone()); self.resources.insert(path.to_string(), res.clone());

View File

@ -1,4 +1,4 @@
use image::{DynamicImage, ImageResult, ImageBuffer, Rgba}; use image::DynamicImage;
#[derive(Clone)] #[derive(Clone)]
pub struct Texture { pub struct Texture {

View File

@ -2,6 +2,7 @@ use base64::Engine;
use thiserror::Error; use thiserror::Error;
use std::io; use std::io;
#[allow(dead_code)]
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum UriReadError { pub enum UriReadError {
#[error("IOError: '{0}'")] #[error("IOError: '{0}'")]
@ -22,7 +23,7 @@ pub enum UriReadError {
/// i.e. parent="resources/models/player.gltf", containing="resource/models" /// i.e. parent="resources/models/player.gltf", containing="resource/models"
pub(crate) fn gltf_read_buffer_uri(containing_path: &str, uri: &str) -> Result<Vec<u8>, UriReadError> { pub(crate) fn gltf_read_buffer_uri(containing_path: &str, uri: &str) -> Result<Vec<u8>, UriReadError> {
if let Some((mime, data)) = uri.strip_prefix("data") if let Some((mime, data)) = uri.strip_prefix("data")
.and_then(|uri| uri.split_once(",")) { .and_then(|uri| uri.split_once(',')) {
let (_mime, is_base64) = match mime.strip_suffix(";base64") { let (_mime, is_base64) = match mime.strip_suffix(";base64") {
Some(mime) => (mime, true), Some(mime) => (mime, true),
None => (mime, false), None => (mime, false),
@ -30,12 +31,12 @@ pub(crate) fn gltf_read_buffer_uri(containing_path: &str, uri: &str) -> Result<V
if is_base64 { if is_base64 {
base64::engine::general_purpose::STANDARD.decode(data) base64::engine::general_purpose::STANDARD.decode(data)
.map_err(|e| UriReadError::Base64Decode(e)) .map_err(UriReadError::Base64Decode)
} else { } else {
Ok(data.as_bytes().to_vec()) Ok(data.as_bytes().to_vec())
} }
} else { } else {
let full_path = format!("{containing_path}/{uri}"); let full_path = format!("{containing_path}/{uri}");
std::fs::read(&full_path).map_err(|e| UriReadError::IoError(e)) std::fs::read(full_path).map_err(UriReadError::IoError)
} }
} }

View File

@ -25,8 +25,9 @@ impl CameraComponent {
} }
pub fn new_2d() -> Self { pub fn new_2d() -> Self {
let mut s = Self::default(); CameraComponent {
s.mode = CameraProjectionMode::Orthographic; mode: CameraProjectionMode::Orthographic,
s ..Default::default()
}
} }
} }

View File

@ -2,19 +2,11 @@ use edict::Component;
use crate::math::Transform; use crate::math::Transform;
#[derive(Clone, Component)] #[derive(Clone, Component, Default)]
pub struct TransformComponent { pub struct TransformComponent {
pub transform: Transform, pub transform: Transform,
} }
impl Default for TransformComponent {
fn default() -> Self {
Self {
transform: Transform::default(),
}
}
}
impl From<Transform> for TransformComponent { impl From<Transform> for TransformComponent {
fn from(transform: Transform) -> Self { fn from(transform: Transform) -> Self {
Self { Self {

View File

@ -12,6 +12,12 @@ pub struct EventQueue {
event_write_queue: HashMap<TypeId, RefCell<Box<dyn CastableAny>>> event_write_queue: HashMap<TypeId, RefCell<Box<dyn CastableAny>>>
} }
impl Default for EventQueue {
fn default() -> Self {
Self::new()
}
}
impl EventQueue { impl EventQueue {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
@ -26,7 +32,7 @@ impl EventQueue {
E: Event E: Event
{ {
// the compiler wants me to explicit right here for some reason // the compiler wants me to explicit right here for some reason
let default = || RefCell::new(Box::new(Events::<E>::new()) as Box<dyn CastableAny>); let default = || RefCell::new(Box::<Events::<E>>::default() as Box<dyn CastableAny>);
// Get, or create, a list of events of this type // Get, or create, a list of events of this type
let type_id = event.type_id(); let type_id = event.type_id();
@ -45,7 +51,7 @@ impl EventQueue {
self.events.clear(); self.events.clear();
// get all keys of events // get all keys of events
let keys: Vec<TypeId> = self.event_write_queue.keys().map(|k| k.clone()).collect(); let keys: Vec<TypeId> = self.event_write_queue.keys().copied().collect();
// remove all elements from self.event_write_queue and insert them to events // remove all elements from self.event_write_queue and insert them to events
for k in keys.into_iter() { for k in keys.into_iter() {

View File

@ -11,7 +11,7 @@ use tracing::warn;
/// A trait that represents a simple system /// A trait that represents a simple system
pub trait SimpleSystem { pub trait SimpleSystem {
fn setup(&mut self, world: &mut World) -> anyhow::Result<()> { fn setup(&mut self, _world: &mut World) -> anyhow::Result<()> {
Ok(()) Ok(())
} }
@ -53,7 +53,8 @@ impl SimpleSystem for BatchedSystem {
struct SystemGraphNode { struct SystemGraphNode {
name: String, name: String,
dependent_on: Vec<String>, #[allow(dead_code)]
dependent_on: Vec<String>, // TODO
system: Box<dyn SimpleSystem>, system: Box<dyn SimpleSystem>,
} }
@ -114,7 +115,7 @@ impl SystemDispatcher {
.get(&depend) .get(&depend)
.expect("Dependency not found!"); .expect("Dependency not found!");
self.graph.add_edge(idx.clone(), added_index, SystemGraphEdge { }); self.graph.add_edge(*idx, added_index, SystemGraphEdge { });
} }
true true

View File

@ -1,20 +1,18 @@
use std::{sync::Arc, collections::VecDeque}; use std::{sync::Arc, collections::VecDeque};
use async_std::{task::block_on, sync::Mutex}; use async_std::task::block_on;
//use hecs::World; use tracing::{info, error, Level};
use instant::Instant;
use tracing::{metadata::LevelFilter, info, debug, warn, error, Level};
use tracing_appender::non_blocking; use tracing_appender::non_blocking;
use tracing_subscriber::{ use tracing_subscriber::{
layer::{Layer, SubscriberExt}, layer::SubscriberExt,
filter::{FilterFn, self}, filter,
util::SubscriberInitExt, fmt, util::SubscriberInitExt, fmt,
}; };
use winit::{window::{WindowBuilder, Window}, event::{Event, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode, DeviceEvent}, event_loop::{EventLoop, ControlFlow}}; use winit::{window::{WindowBuilder, Window}, event::{Event, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode, DeviceEvent}, event_loop::{EventLoop, ControlFlow}};
use crate::{render::renderer::{Renderer, BasicRenderer}, input_event::InputEvent, ecs::{SimpleSystem, SystemDispatcher, EventQueue, Events}, input::InputSystem, plugin::Plugin}; use crate::{render::renderer::{Renderer, BasicRenderer}, input_event::InputEvent, ecs::{SimpleSystem, SystemDispatcher, EventQueue, Events}, plugin::Plugin};
pub struct Controls<'a> { pub struct Controls<'a> {
pub world: &'a mut edict::World, pub world: &'a mut edict::World,
@ -95,14 +93,14 @@ impl GameLoop {
// TODO: Create system for this? or maybe merge into input system, idk // TODO: Create system for this? or maybe merge into input system, idk
InputEvent::CursorEntered { .. } => { InputEvent::CursorEntered { .. } => {
let mut state = self.world.with_resource(|| WindowState::new()); let state = self.world.with_resource(WindowState::new);
state.is_cursor_inside_window = true; state.is_cursor_inside_window = true;
None None
}, },
InputEvent::CursorLeft { .. } => { InputEvent::CursorLeft { .. } => {
let mut state = self.world.with_resource(|| WindowState::new()); let state = self.world.with_resource(WindowState::new);
state.is_cursor_inside_window = false; state.is_cursor_inside_window = false;
None None
@ -123,23 +121,18 @@ impl GameLoop {
pub async fn run_event_loop(&mut self, event: Event<'_, ()>, control_flow: &mut ControlFlow) { pub async fn run_event_loop(&mut self, event: Event<'_, ()>, control_flow: &mut ControlFlow) {
*control_flow = ControlFlow::Poll; *control_flow = ControlFlow::Poll;
match event { match event {
Event::DeviceEvent { device_id, event } => match event { Event::DeviceEvent { device_id, event: DeviceEvent::MouseMotion { delta } } => {
// convert a MouseMotion event to an InputEvent // convert a MouseMotion event to an InputEvent
DeviceEvent::MouseMotion { delta } => { // make sure that the mouse is inside the window and the mouse has focus before reporting mouse motion
// make sure that the mouse is inside the window and the mouse has focus before reporting mouse motion let trigger = matches!(self.world.get_resource::<WindowState>(), Some(window_state)
let trigger = match self.world.get_resource::<WindowState>() { if window_state.is_focused && window_state.is_cursor_inside_window);
Some(window_state) if window_state.is_focused && window_state.is_cursor_inside_window => true,
_ => false,
};
if trigger { if trigger {
let event_queue = self.world.with_resource(|| Events::<InputEvent>::new()); let event_queue = self.world.with_resource(Events::<InputEvent>::new);
let input_event = InputEvent::MouseMotion { device_id, delta, }; let input_event = InputEvent::MouseMotion { device_id, delta, };
event_queue.push_back(input_event); event_queue.push_back(input_event);
} }
},
_ => {}
}, },
Event::WindowEvent { Event::WindowEvent {
ref event, ref event,
@ -177,7 +170,7 @@ impl GameLoop {
}, },
WindowEvent::Focused(is_focused) => { WindowEvent::Focused(is_focused) => {
let mut state = self.world.with_resource(|| WindowState::new()); let state = self.world.with_resource(WindowState::new);
state.is_focused = *is_focused; state.is_focused = *is_focused;
}, },
@ -306,7 +299,7 @@ impl Game {
plugin.as_ref().setup(self); plugin.as_ref().setup(self);
} }
let mut world = self.world.take().unwrap_or_else(|| edict::World::new()); let mut world = self.world.take().unwrap_or_default();
// run startup systems // run startup systems
while let Some(mut startup) = self.startup_systems.pop_front() { while let Some(mut startup) = self.startup_systems.pop_front() {

View File

@ -1,11 +1,10 @@
use std::{collections::{HashMap, hash_map::DefaultHasher}, hash::{Hash, Hasher}, sync::{Arc, Mutex}}; use std::{collections::{HashMap, hash_map::DefaultHasher}, hash::{Hash, Hasher}};
use gilrs_core::Gilrs;
use glam::Vec2; use glam::Vec2;
use tracing::{warn, debug}; use tracing::debug;
use winit::{event::{ElementState, MouseScrollDelta}, window::{Window, CursorGrabMode}, dpi::PhysicalPosition}; use winit::event::{ElementState, MouseScrollDelta};
use crate::{ecs::{SimpleSystem, EventQueue}, input_event::InputEvent, plugin::Plugin, render::window::WindowOptions, change_tracker::Ct}; use crate::{ecs::{SimpleSystem, EventQueue}, input_event::InputEvent, plugin::Plugin,};
pub type KeyCode = winit::event::VirtualKeyCode; pub type KeyCode = winit::event::VirtualKeyCode;
@ -98,6 +97,12 @@ pub struct Touches {
pub touches: Vec<Touch>, pub touches: Vec<Touch>,
} }
impl Default for Touches {
fn default() -> Self {
Self::new()
}
}
impl Touches { impl Touches {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
@ -140,6 +145,12 @@ pub struct InputButtons<T: Clone + Hash + Eq + PartialEq + 'static> {
button_events: HashMap<u64, ButtonEvent<T>>, button_events: HashMap<u64, ButtonEvent<T>>,
} }
impl<T: Clone + Hash + Eq + PartialEq + 'static> Default for InputButtons<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Clone + Hash + Eq + PartialEq + 'static> InputButtons<T> { impl<T: Clone + Hash + Eq + PartialEq + 'static> InputButtons<T> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
@ -236,7 +247,7 @@ impl InputSystem {
InputEvent::KeyboardInput { input, .. } => { InputEvent::KeyboardInput { input, .. } => {
if let Some(code) = input.virtual_keycode { if let Some(code) = input.virtual_keycode {
drop(event_queue); drop(event_queue);
let e = world.with_resource(|| InputButtons::<KeyCode>::new()); let e = world.with_resource(InputButtons::<KeyCode>::new);
//let mut e = with_resource_mut(world, || InputButtons::<KeyCode>::new()); //let mut e = with_resource_mut(world, || InputButtons::<KeyCode>::new());
e.add_input_from_winit(code, input.state); e.add_input_from_winit(code, input.state);
} }
@ -285,11 +296,11 @@ impl InputSystem {
winit::event::MouseButton::Other(v) => MouseButton::Other(*v), winit::event::MouseButton::Other(v) => MouseButton::Other(*v),
}; };
event_queue.trigger_event(button_event.clone()); event_queue.trigger_event(button_event);
drop(event_queue); drop(event_queue);
let e = world.with_resource(|| InputButtons::<MouseButton>::new()); let e = world.with_resource(InputButtons::<MouseButton>::new);
e.add_input_from_winit(button_event, state.clone()); e.add_input_from_winit(button_event, *state);
}, },
InputEvent::Touch(t) => { InputEvent::Touch(t) => {
drop(event_queue); drop(event_queue);
@ -297,14 +308,11 @@ impl InputSystem {
let touch = Touch { let touch = Touch {
phase: TouchPhase::from(t.phase), phase: TouchPhase::from(t.phase),
location: Vec2::new(t.location.x as f32, t.location.y as f32), location: Vec2::new(t.location.x as f32, t.location.y as f32),
force: match t.force { force: t.force.map(Force::from),
Some(f) => Some(Force::from(f)),
None => None,
},
finger_id: t.id, finger_id: t.id,
}; };
let touches = world.with_resource(|| Touches::new()); let touches = world.with_resource(Touches::new);
touches.touches.push(touch); touches.touches.push(touch);
}, },
_ => {}, _ => {},
@ -317,7 +325,7 @@ impl InputSystem {
impl SimpleSystem for InputSystem { impl SimpleSystem for InputSystem {
fn execute_mut(&mut self, world: &mut edict::World) -> anyhow::Result<()> { fn execute_mut(&mut self, world: &mut edict::World) -> anyhow::Result<()> {
let queue = world.get_resource_mut::<EventQueue>() let queue = world.get_resource_mut::<EventQueue>()
.map(|q| q.read_events::<InputEvent>()).flatten(); .and_then(|q| q.read_events::<InputEvent>());
if queue.is_none() { if queue.is_none() {
return Ok(()); return Ok(());
@ -339,6 +347,6 @@ pub struct InputPlugin;
impl Plugin for InputPlugin { impl Plugin for InputPlugin {
fn setup(&self, game: &mut crate::game::Game) { fn setup(&self, game: &mut crate::game::Game) {
game.with_system("input", InputSystem::default(), &[]); game.with_system("input", InputSystem, &[]);
} }
} }

View File

@ -153,67 +153,70 @@ impl<'a> TryFrom<&'a WindowEvent<'a>> for InputEvent {
match value { match value {
WindowEvent::KeyboardInput { device_id, input, is_synthetic } => WindowEvent::KeyboardInput { device_id, input, is_synthetic } =>
Ok(InputEvent::KeyboardInput { Ok(InputEvent::KeyboardInput {
device_id: device_id.clone(), device_id: *device_id,
input: input.clone(), input: *input,
is_synthetic: is_synthetic.clone() is_synthetic: *is_synthetic
}), }),
#[allow(deprecated, reason="Compatibility")]
WindowEvent::CursorMoved { device_id, position, modifiers } => WindowEvent::CursorMoved { device_id, position, modifiers } =>
Ok(InputEvent::CursorMoved { Ok(InputEvent::CursorMoved {
device_id: device_id.clone(), device_id: *device_id,
position: position.clone(), position: *position,
modifiers: modifiers.clone() modifiers: *modifiers
}), }),
WindowEvent::CursorEntered { device_id } => WindowEvent::CursorEntered { device_id } =>
Ok(InputEvent::CursorEntered { Ok(InputEvent::CursorEntered {
device_id: device_id.clone() device_id: *device_id
}), }),
WindowEvent::CursorLeft { device_id } => WindowEvent::CursorLeft { device_id } =>
Ok(InputEvent::CursorLeft { Ok(InputEvent::CursorLeft {
device_id: device_id.clone() device_id: *device_id
}), }),
#[allow(deprecated, reason="Compatibility")]
WindowEvent::MouseWheel { device_id, delta, phase, modifiers } => WindowEvent::MouseWheel { device_id, delta, phase, modifiers } =>
Ok(InputEvent::MouseWheel { Ok(InputEvent::MouseWheel {
device_id: device_id.clone(), device_id: *device_id,
delta: delta.clone(), delta: *delta,
phase: phase.clone(), phase: *phase,
modifiers: modifiers.clone() modifiers: *modifiers
}), }),
#[allow(deprecated, reason="Compatibility")]
WindowEvent::MouseInput { device_id, state, button, modifiers } => WindowEvent::MouseInput { device_id, state, button, modifiers } =>
Ok(InputEvent::MouseInput { Ok(InputEvent::MouseInput {
device_id: device_id.clone(), device_id: *device_id,
state: state.clone(), state: *state,
button: button.clone(), button: *button,
modifiers: modifiers.clone() modifiers: *modifiers
}), }),
WindowEvent::TouchpadMagnify { device_id, delta, phase } => WindowEvent::TouchpadMagnify { device_id, delta, phase } =>
Ok(InputEvent::TouchpadMagnify { Ok(InputEvent::TouchpadMagnify {
device_id: device_id.clone(), device_id: *device_id,
delta: delta.clone(), delta: *delta,
phase: phase.clone() phase: *phase
}), }),
WindowEvent::SmartMagnify { device_id } => WindowEvent::SmartMagnify { device_id } =>
Ok(InputEvent::SmartMagnify { Ok(InputEvent::SmartMagnify {
device_id: device_id.clone() device_id: *device_id
}), }),
WindowEvent::TouchpadRotate { device_id, delta, phase } => WindowEvent::TouchpadRotate { device_id, delta, phase } =>
Ok(InputEvent::TouchpadRotate { Ok(InputEvent::TouchpadRotate {
device_id: device_id.clone(), device_id: *device_id,
delta: delta.clone(), delta: *delta,
phase: phase.clone() phase: *phase
}), }),
WindowEvent::TouchpadPressure { device_id, pressure, stage } => WindowEvent::TouchpadPressure { device_id, pressure, stage } =>
Ok(InputEvent::TouchpadPressure { Ok(InputEvent::TouchpadPressure {
device_id: device_id.clone(), device_id: *device_id,
pressure: pressure.clone(), pressure: *pressure,
stage: stage.clone() stage: *stage
}), }),
WindowEvent::AxisMotion { device_id, axis, value } => WindowEvent::AxisMotion { device_id, axis, value } =>
Ok(InputEvent::AxisMotion { Ok(InputEvent::AxisMotion {
device_id: device_id.clone(), device_id: *device_id,
axis: axis.clone(), axis: *axis,
value: value.clone() value: *value
}), }),
WindowEvent::Touch(t) => Ok(InputEvent::Touch(t.clone())), WindowEvent::Touch(t) => Ok(InputEvent::Touch(*t)),
_ => Err(InputEventConversionError::FromError(value)) _ => Err(InputEventConversionError::FromError(value))
} }

View File

@ -1,4 +1,5 @@
#![feature(hash_extract_if)] #![feature(hash_extract_if)]
#![feature(lint_reasons)]
pub mod game; pub mod game;
pub mod render; pub mod render;

View File

@ -1,6 +1,6 @@
use glam::{Vec3, Mat4, Quat}; use glam::{Vec3, Mat4, Quat};
use crate::math::angle::{self, Angle}; use crate::math::angle::Angle;
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
@ -28,6 +28,7 @@ impl Default for Transform {
// TODO: https://www.brainvoyager.com/bv/doc/UsersGuide/CoordsAndTransforms/SpatialTransformationMatrices.html // TODO: https://www.brainvoyager.com/bv/doc/UsersGuide/CoordsAndTransforms/SpatialTransformationMatrices.html
#[allow(dead_code)]
const ZERO_V3: Vec3 = Vec3::new(0.0, 0.0, 0.0); const ZERO_V3: Vec3 = Vec3::new(0.0, 0.0, 0.0);
const ONE_V3: Vec3 = Vec3::new(1.0, 1.0, 1.0); const ONE_V3: Vec3 = Vec3::new(1.0, 1.0, 1.0);

View File

@ -10,15 +10,15 @@ pub trait Plugin {
/// Setup this plugin. This runs before the game has started /// Setup this plugin. This runs before the game has started
fn setup(&self, game: &mut Game); fn setup(&self, game: &mut Game);
fn is_ready(&self, game: &mut Game) -> bool { fn is_ready(&self, _game: &mut Game) -> bool {
true true
} }
fn complete(&self, game: &mut Game) { fn complete(&self, _game: &mut Game) {
} }
fn cleanup(&self, game: &mut Game) { fn cleanup(&self, _game: &mut Game) {
} }
} }
@ -108,9 +108,9 @@ pub struct DefaultPlugins;
impl Plugin for DefaultPlugins { impl Plugin for DefaultPlugins {
fn setup(&self, game: &mut Game) { fn setup(&self, game: &mut Game) {
// setup input // setup input
EventsPlugin::default().setup(game); EventsPlugin.setup(game);
InputPlugin::default().setup(game); InputPlugin.setup(game);
ResourceManagerPlugin::default().setup(game); ResourceManagerPlugin.setup(game);
WindowPlugin::default().setup(game); WindowPlugin::default().setup(game);
} }
} }

View File

@ -1,4 +1,3 @@
use tracing::debug;
use winit::dpi::PhysicalSize; use winit::dpi::PhysicalSize;
use crate::{math::{Angle, OPENGL_TO_WGPU_MATRIX}, ecs::components::camera::CameraComponent}; use crate::{math::{Angle, OPENGL_TO_WGPU_MATRIX}, ecs::components::camera::CameraComponent};
@ -31,7 +30,7 @@ impl Projection {
self.aspect = width as f32 / height as f32; self.aspect = width as f32 / height as f32;
} }
pub fn calc_matrix(&self, fov: Angle, mode: CameraProjectionMode) -> glam::Mat4 { pub fn calc_matrix(&self, fov: Angle, _mode: CameraProjectionMode) -> glam::Mat4 {
OPENGL_TO_WGPU_MATRIX * glam::Mat4::perspective_rh_gl(fov.to_radians(), self.aspect, self.znear, self.zfar) OPENGL_TO_WGPU_MATRIX * glam::Mat4::perspective_rh_gl(fov.to_radians(), self.aspect, self.znear, self.zfar)
} }
} }
@ -40,6 +39,7 @@ impl Projection {
pub struct RenderCamera { pub struct RenderCamera {
view_proj: glam::Mat4, view_proj: glam::Mat4,
#[allow(dead_code)]
size: PhysicalSize<u32>, size: PhysicalSize<u32>,
aspect: f32, aspect: f32,
znear: f32, znear: f32,

View File

@ -1,6 +1,4 @@
use wgpu::{BindGroup, BindGroupLayout}; use super::vertex::Vertex;
use super::{vertex::Vertex, render_buffer::{BufferStorage}};
#[derive(Clone)] #[derive(Clone)]
pub struct Mesh { pub struct Mesh {

View File

@ -1,8 +1,6 @@
use std::ops::Range; use wgpu::{PipelineLayout, RenderPipeline, VertexBufferLayout, BindGroupLayout};
use wgpu::{PipelineLayout, RenderPipeline, RenderPass, VertexBufferLayout, BindGroupLayout}; use super::texture::RenderTexture;
use super::{render_job::RenderJob, texture::RenderTexture};
pub struct FullRenderPipeline { pub struct FullRenderPipeline {
layout: PipelineLayout, layout: PipelineLayout,
@ -34,12 +32,12 @@ impl FullRenderPipeline {
label: Some("Render Pipeline"), label: Some("Render Pipeline"),
layout: Some(&render_pipeline_layout), layout: Some(&render_pipeline_layout),
vertex: wgpu::VertexState { vertex: wgpu::VertexState {
module: &shader, module: shader,
entry_point: "vs_main", entry_point: "vs_main",
buffers: &buffer_layouts, buffers: &buffer_layouts,
}, },
fragment: Some(wgpu::FragmentState { fragment: Some(wgpu::FragmentState {
module: &shader, module: shader,
entry_point: "fs_main", entry_point: "fs_main",
targets: &[Some(wgpu::ColorTargetState { targets: &[Some(wgpu::ColorTargetState {
format: config.format, format: config.format,
@ -89,28 +87,4 @@ impl FullRenderPipeline {
pub fn get_wgpu_pipeline(&self) -> &RenderPipeline { pub fn get_wgpu_pipeline(&self) -> &RenderPipeline {
&self.wgpu_pipeline &self.wgpu_pipeline
} }
pub fn render<'a>(&'a self, jobs: &'a Vec<RenderJob>, pass: &'a mut RenderPass<'a>, vertices: Range<u32>, instances: Range<u32>) {
todo!()
/* pass.set_pipeline(&self.wgpu_pipeline);
for job in jobs.iter() {
let mesh = job.mesh();
if let Some(tex) = mesh.texture_bindgroup.as_ref() {
pass.set_bind_group(0, &tex, &[]);
}
if let Some(indices) = mesh.buffer_indices.as_ref() {
let indices_len = indices.count().unwrap(); // index buffers will have count, if not thats a bug
pass.set_vertex_buffer(mesh.buffer_vertex.slot(), mesh.buffer_vertex.buffer().slice(..));
pass.set_index_buffer(indices.buffer().slice(..), wgpu::IndexFormat::Uint16);
pass.draw_indexed(0..indices_len, 0, instances.clone());
} else {
pass.set_vertex_buffer(mesh.buffer_vertex.slot(), mesh.buffer_vertex.buffer().slice(..));
pass.draw(vertices.clone(), instances.clone());
}
} */
}
} }

View File

@ -1,4 +1,3 @@
use std::cell::RefCell;
use std::collections::{HashMap, VecDeque, HashSet}; use std::collections::{HashMap, VecDeque, HashSet};
use std::mem; use std::mem;
use std::num::NonZeroU64; use std::num::NonZeroU64;
@ -14,7 +13,6 @@ use wgpu::util::DeviceExt;
use winit::window::Window; use winit::window::Window;
use crate::ecs::components::camera::CameraComponent; use crate::ecs::components::camera::CameraComponent;
use crate::ecs::components::mesh::MeshComponent;
use crate::ecs::components::model::ModelComponent; use crate::ecs::components::model::ModelComponent;
use crate::ecs::components::transform::TransformComponent; use crate::ecs::components::transform::TransformComponent;
use crate::math::Transform; use crate::math::Transform;
@ -40,6 +38,7 @@ struct RenderBufferStorage {
buffer_vertex: BufferStorage, buffer_vertex: BufferStorage,
buffer_indices: Option<(wgpu::IndexFormat, BufferStorage)>, buffer_indices: Option<(wgpu::IndexFormat, BufferStorage)>,
#[allow(dead_code)]
render_texture: Option<RenderTexture>, render_texture: Option<RenderTexture>,
texture_bindgroup: Option<BindGroup>, texture_bindgroup: Option<BindGroup>,
@ -85,13 +84,13 @@ impl TransformBuffers {
// get a dead index, or create a new one // get a dead index, or create a new one
let (indices, buffer) = if let Some(index) = self.dead_indices.pop_front() { let (indices, buffer) = if let Some(index) = self.dead_indices.pop_front() {
let (_, buffer, _) = self.buffer_bindgroups.get(index.buffer_index).unwrap(); let (_, buffer, _) = self.buffer_bindgroups.get(index.buffer_index).unwrap();
(index, &*buffer) (index, buffer)
} else { } else {
let indices = &mut self.next_indices; let indices = &mut self.next_indices;
let this_idx = indices.clone(); let this_idx = *indices;
let (count, buffer, _) = self.buffer_bindgroups.get_mut(indices.buffer_index).unwrap(); let (count, buffer, _) = self.buffer_bindgroups.get_mut(indices.buffer_index).unwrap();
if count.clone() >= self.max_transform_count { if *count >= self.max_transform_count {
panic!("Transform buffer is filled and 'next_indices' was not incremented! Was a new buffer created?"); panic!("Transform buffer is filled and 'next_indices' was not incremented! Was a new buffer created?");
} }
@ -126,8 +125,7 @@ impl TransformBuffers {
/// Collect the dead entities, mark entities and not updated for next updates. /// Collect the dead entities, mark entities and not updated for next updates.
fn tick(&mut self) { fn tick(&mut self) {
// take the dead entities, these were ones that were not updated this tick // take the dead entities, these were ones that were not updated this tick
let dead: VecDeque<TransformBufferIndices> = self.not_updated.values() let dead: VecDeque<TransformBufferIndices> = self.not_updated.values().copied().collect();
.map(|t| t.clone()).collect();
self.dead_indices = dead; self.dead_indices = dead;
self.not_updated = self.just_updated.clone(); self.not_updated = self.just_updated.clone();
@ -141,7 +139,7 @@ impl TransformBuffers {
/// Returns whether or not the transform buffers should be expanded /// Returns whether or not the transform buffers should be expanded
fn should_expand(&self) -> bool { fn should_expand(&self) -> bool {
if let Some(( count, _, _ )) = self.buffer_bindgroups.last() { if let Some(( count, _, _ )) = self.buffer_bindgroups.last() {
count.clone() >= self.max_transform_count *count >= self.max_transform_count
} else { } else {
true true
} }
@ -228,8 +226,7 @@ impl BasicRenderer {
let surface_format = surface_caps.formats.iter() let surface_format = surface_caps.formats.iter()
.copied() .copied()
.filter(|f| f.describe().srgb) .find(|f| f.describe().srgb)
.next()
.unwrap_or(surface_caps.formats[0]); .unwrap_or(surface_caps.formats[0]);
let config = wgpu::SurfaceConfiguration { let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT, usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
@ -270,7 +267,7 @@ impl BasicRenderer {
let shader_src = include_str!("shaders/base.wgsl"); let shader_src = include_str!("shaders/base.wgsl");
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Shader"), label: Some("Shader"),
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(&shader_src)), source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(shader_src)),
}); });
let transform_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { let transform_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
@ -446,7 +443,7 @@ impl BasicRenderer {
let vertices = vertices.as_slice(); let vertices = vertices.as_slice();
// align the vertices to 4 bytes (u32 is 4 bytes, which is wgpu::COPY_BUFFER_ALIGNMENT) // align the vertices to 4 bytes (u32 is 4 bytes, which is wgpu::COPY_BUFFER_ALIGNMENT)
let (_, vertices, _) = bytemuck::pod_align_to::<Vec3, u32>(vertices); let (_, vertices, _) = bytemuck::pod_align_to::<Vec3, u32>(vertices);
self.queue.write_buffer(&vertex_buffer, 0, bytemuck::cast_slice(&vertices)); self.queue.write_buffer(vertex_buffer, 0, bytemuck::cast_slice(vertices));
// update the indices if they're given // update the indices if they're given
if let Some(index_buffer) = buffers.buffer_indices.as_ref() { if let Some(index_buffer) = buffers.buffer_indices.as_ref() {
@ -457,7 +454,7 @@ impl BasicRenderer {
}; };
let index_buffer = index_buffer.1.buffer(); let index_buffer = index_buffer.1.buffer();
self.queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(&aligned_indices)); self.queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(aligned_indices));
} }
} }
} }
@ -469,8 +466,8 @@ impl BasicRenderer {
assert!(positions.len() == tex_coords.len()); assert!(positions.len() == tex_coords.len());
let vertex_inputs: Vec<Vertex> = std::iter::zip(positions, tex_coords.into_iter()) let vertex_inputs: Vec<Vertex> = std::iter::zip(positions, tex_coords)
.map(|(v, t)| Vertex::new(v.clone(), t)) .map(|(v, t)| Vertex::new(*v, t))
.collect(); .collect();
let vertex_buffer = self.device.create_buffer_init( let vertex_buffer = self.device.create_buffer_init(
@ -485,8 +482,8 @@ impl BasicRenderer {
let indices = match mesh.indices.as_ref() { let indices = match mesh.indices.as_ref() {
Some(indices) => { Some(indices) => {
let (idx_type, len, contents) = match indices { let (idx_type, len, contents) = match indices {
lyra_resource::MeshIndices::U16(v) => (wgpu::IndexFormat::Uint16, v.len(), bytemuck::cast_slice(&v)), lyra_resource::MeshIndices::U16(v) => (wgpu::IndexFormat::Uint16, v.len(), bytemuck::cast_slice(v)),
lyra_resource::MeshIndices::U32(v) => (wgpu::IndexFormat::Uint32, v.len(), bytemuck::cast_slice(&v)), lyra_resource::MeshIndices::U32(v) => (wgpu::IndexFormat::Uint32, v.len(), bytemuck::cast_slice(v)),
}; };
let index_buffer = self.device.create_buffer_init( let index_buffer = self.device.create_buffer_init(
@ -588,9 +585,8 @@ impl BasicRenderer {
let indices = self.transform_buffers.update_or_insert(&self.queue, &self.render_limits, let indices = self.transform_buffers.update_or_insert(&self.queue, &self.render_limits,
entity, || transform.calculate_mat4()); entity, || transform.calculate_mat4());
if self.mesh_buffers.contains_key(&mesh.uuid) { #[allow(clippy::map_entry)]
false if !self.mesh_buffers.contains_key(&mesh.uuid) {
} else {
// check if the transform buffers need to be expanded // check if the transform buffers need to be expanded
if self.transform_buffers.should_expand() { if self.transform_buffers.should_expand() {
self.expand_transform_buffers(); self.expand_transform_buffers();
@ -602,7 +598,7 @@ impl BasicRenderer {
self.entity_meshes.insert(entity, mesh.uuid); self.entity_meshes.insert(entity, mesh.uuid);
true true
} } else { false }
} }
} }
@ -618,10 +614,8 @@ impl Renderer for BasicRenderer {
let model = model.data.as_ref().unwrap().as_ref(); let model = model.data.as_ref().unwrap().as_ref();
for mesh in model.meshes.iter() { for mesh in model.meshes.iter() {
if !self.process_mesh(entity, transform.transform, mesh) { if !self.process_mesh(entity, transform.transform, mesh) && model_epoch == last_epoch {
if model_epoch == last_epoch { self.update_mesh_buffers(entity, mesh);
self.update_mesh_buffers(entity, mesh);
}
} }
let shader = mesh.material().shader_uuid.unwrap_or(0); let shader = mesh.material().shader_uuid.unwrap_or(0);
@ -630,9 +624,9 @@ impl Renderer for BasicRenderer {
} }
} }
for (entity, mesh, mesh_epoch, transform) in main_world.query::<(Entities, &MeshComponent, EpochOf<MeshComponent>, &TransformComponent)>().iter() { /* for (entity, mesh, mesh_epoch, transform) in main_world.query::<(Entities, &MeshComponent, EpochOf<MeshComponent>, &TransformComponent)>().iter() {
debug!("TODO: Process MeshComponents"); // TODO: Process MeshComponents debug!("TODO: Process MeshComponents"); // TODO: Process MeshComponents
} } */
// collect dead entities // collect dead entities
self.transform_buffers.tick(); self.transform_buffers.tick();
@ -649,7 +643,7 @@ impl Renderer for BasicRenderer {
if let Some(camera) = main_world.query_mut::<(&mut CameraComponent,)>().into_iter().next() { if let Some(camera) = main_world.query_mut::<(&mut CameraComponent,)>().into_iter().next() {
let view_proj = self.inuse_camera.update_view_projection(camera); let view_proj = self.inuse_camera.update_view_projection(camera);
self.queue.write_buffer(&self.camera_buffer, 0, bytemuck::cast_slice(&[view_proj.clone()])); self.queue.write_buffer(&self.camera_buffer, 0, bytemuck::cast_slice(&[*view_proj]));
} else { } else {
warn!("Missing camera!"); warn!("Missing camera!");
} }
@ -698,7 +692,7 @@ impl Renderer for BasicRenderer {
// Bind the optional texture // Bind the optional texture
if let Some(tex) = buffers.texture_bindgroup.as_ref() { if let Some(tex) = buffers.texture_bindgroup.as_ref() {
render_pass.set_bind_group(0, &tex, &[]); render_pass.set_bind_group(0, tex, &[]);
} else { } else {
render_pass.set_bind_group(0, &self.default_texture_bind_group, &[]); render_pass.set_bind_group(0, &self.default_texture_bind_group, &[]);
} }
@ -717,7 +711,7 @@ impl Renderer for BasicRenderer {
let indices_len = indices.count() as u32; let indices_len = indices.count() as u32;
render_pass.set_vertex_buffer(buffers.buffer_vertex.slot(), buffers.buffer_vertex.buffer().slice(..)); render_pass.set_vertex_buffer(buffers.buffer_vertex.slot(), buffers.buffer_vertex.buffer().slice(..));
render_pass.set_index_buffer(indices.buffer().slice(..), idx_type.clone()); render_pass.set_index_buffer(indices.buffer().slice(..), *idx_type);
render_pass.draw_indexed(0..indices_len, 0, 0..1); render_pass.draw_indexed(0..indices_len, 0, 0..1);
} else { } else {
let vertex_count = buffers.buffer_vertex.count(); let vertex_count = buffers.buffer_vertex.count();

View File

@ -96,7 +96,7 @@ impl RenderTexture {
}) })
} }
pub fn update_texture(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, texture: &Arc<Resource<Texture>>) { pub fn update_texture(&mut self, _device: &wgpu::Device, queue: &wgpu::Queue, texture: &Arc<Resource<Texture>>) {
let texture = &texture.data.as_ref().unwrap().image; let texture = &texture.data.as_ref().unwrap().image;
let rgba = texture.to_rgba8(); let rgba = texture.to_rgba8();
let dimensions = texture.dimensions(); let dimensions = texture.dimensions();

View File

@ -1,13 +1,11 @@
use std::sync::Arc; use std::sync::Arc;
use glam::{Vec2, IVec2}; use glam::{Vec2, IVec2};
use tracing::{warn, error, debug}; use tracing::{warn, error};
use winit::{window::{Window, Fullscreen}, dpi::{LogicalPosition, LogicalSize, PhysicalPosition}, error::ExternalError}; use winit::{window::{Window, Fullscreen}, dpi::{LogicalPosition, LogicalSize, PhysicalPosition}, error::ExternalError};
pub use winit::window::{CursorGrabMode, CursorIcon, Icon, Theme, WindowButtons, WindowLevel}; pub use winit::window::{CursorGrabMode, CursorIcon, Icon, Theme, WindowButtons, WindowLevel};
//use winit::dpi::{LogicalPosition, PhysicalPosition};
use crate::{plugin::Plugin, change_tracker::Ct}; use crate::{plugin::Plugin, change_tracker::Ct};
#[derive(Default, Clone)] #[derive(Default, Clone)]
@ -206,6 +204,7 @@ impl Default for WindowOptions {
#[derive(Default)] #[derive(Default)]
pub struct WindowPlugin { pub struct WindowPlugin {
#[allow(dead_code)]
create_options: WindowOptions, create_options: WindowOptions,
} }
@ -221,7 +220,7 @@ fn ivec2_to_logical_size(size: IVec2) -> LogicalSize<i32> {
/// Convert an Option<IVec2> to an Option<LogicalSize<i32>> /// Convert an Option<IVec2> to an Option<LogicalSize<i32>>
fn ivec2_to_logical_size_op(size: Option<IVec2>) -> Option<LogicalSize<i32>> { fn ivec2_to_logical_size_op(size: Option<IVec2>) -> Option<LogicalSize<i32>> {
size.map(|size| ivec2_to_logical_size(size)) size.map(ivec2_to_logical_size)
} }
/// Convert an Option<Vec2> to an Option<LogicalSize<f32>> /// Convert an Option<Vec2> to an Option<LogicalSize<f32>>
@ -256,7 +255,7 @@ fn set_cursor_grab(window: &Window, grab: &mut CursorGrabMode) -> anyhow::Result
/// if the window is set to confine the cursor, and the cursor is invisible, /// if the window is set to confine the cursor, and the cursor is invisible,
/// set the cursor position to the center of the screen. /// set the cursor position to the center of the screen.
fn center_mouse(window: &Window, options: &WindowOptions) { fn center_mouse(window: &Window, options: &WindowOptions) {
if options.cursor_grab == CursorGrabMode::Confined && options.cursor_visible == false { if options.cursor_grab == CursorGrabMode::Confined && !options.cursor_visible {
let size = window.inner_size(); let size = window.inner_size();
let middle = PhysicalPosition { let middle = PhysicalPosition {
x: size.width / 2, x: size.width / 2,

View File

@ -10,7 +10,7 @@ pub async fn load_bytes(file_name: &str) -> anyhow::Result<Vec<u8>> {
.bytes() .bytes()
.await?; .await?;
} else { } else {
let out_dir = std::env::var("OUT_DIR").unwrap_or(String::new()); let out_dir = std::env::var("OUT_DIR").unwrap_or_default();
let path = std::path::Path::new(&out_dir) let path = std::path::Path::new(&out_dir)
.join("res") .join("res")
.join(file_name); .join(file_name);