summaryrefslogtreecommitdiff
path: root/engine/src
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-09-22 18:22:46 +0200
committerHampusM <hampus@hampusmat.com>2026-09-22 18:22:46 +0200
commitc73ab25c9dbe40284cfd38beaf31e2a20a9810de (patch)
tree51c5817a0c252a172c03a47e36886e563a4e623d /engine/src
parent2ccda0cd5f81909fddc74d95f960f781a64bcae1 (diff)
refactor(engine): fix portion of clippy lints
Diffstat (limited to 'engine/src')
-rw-r--r--engine/src/asset.rs55
-rw-r--r--engine/src/camera.rs1
-rw-r--r--engine/src/collision.rs3
-rw-r--r--engine/src/data_types/matrix.rs9
-rw-r--r--engine/src/data_types/vector.rs1
-rw-r--r--engine/src/file_format/wavefront/obj.rs71
-rw-r--r--engine/src/image.rs19
-rw-r--r--engine/src/lib.rs9
-rw-r--r--engine/src/lighting.rs1
-rw-r--r--engine/src/material.rs2
-rw-r--r--engine/src/mesh.rs41
-rw-r--r--engine/src/mesh/vertex_buffer.rs13
-rw-r--r--engine/src/model.rs5
-rw-r--r--engine/src/model/asset.rs1
-rw-r--r--engine/src/projection.rs5
-rw-r--r--engine/src/rendering.rs11
-rw-r--r--engine/src/rendering/backend.rs1
-rw-r--r--engine/src/rendering/backend/opengl.rs108
-rw-r--r--engine/src/rendering/backend/opengl/glutin_compat.rs52
-rw-r--r--engine/src/rendering/backend/opengl/graphics_mesh.rs9
-rw-r--r--engine/src/rendering/main_render_pass.rs67
-rw-r--r--engine/src/rendering/object.rs7
-rw-r--r--engine/src/rendering/shader.rs78
-rw-r--r--engine/src/rendering/shader/cursor.rs26
-rw-r--r--engine/src/texture.rs8
-rw-r--r--engine/src/transform.rs3
-rw-r--r--engine/src/ui/dear_imgui.rs123
-rw-r--r--engine/src/ui/view/transform_3d.rs2
-rw-r--r--engine/src/ui/view/world.rs386
-rw-r--r--engine/src/util.rs10
-rw-r--r--engine/src/windowing.rs731
-rw-r--r--engine/src/windowing/dpi.rs24
-rw-r--r--engine/src/windowing/keyboard.rs48
-rw-r--r--engine/src/windowing/monitor.rs4
-rw-r--r--engine/src/windowing/mouse.rs7
-rw-r--r--engine/src/windowing/window.rs20
-rw-r--r--engine/src/work_queue.rs2
37 files changed, 1076 insertions, 887 deletions
diff --git a/engine/src/asset.rs b/engine/src/asset.rs
index dd8aa37..56b8a46 100644
--- a/engine/src/asset.rs
+++ b/engine/src/asset.rs
@@ -38,11 +38,12 @@ pub struct Label<'a>
impl Label<'_>
{
+ #[must_use]
pub fn to_owned(&self) -> LabelOwned
{
LabelOwned {
path: self.path.to_path_buf(),
- name: self.name.as_ref().map(|name| name.to_string()),
+ name: self.name.as_ref().map(std::string::ToString::to_string),
}
}
}
@@ -82,7 +83,7 @@ impl Display for Label<'_>
if let Some(name) = &self.name {
formatter.write_str("::")?;
- formatter.write_str(&name)?;
+ formatter.write_str(name)?;
}
Ok(())
@@ -98,6 +99,7 @@ pub struct LabelOwned
impl LabelOwned
{
+ #[must_use]
pub fn to_label(&self) -> Label<'_>
{
Label {
@@ -115,7 +117,7 @@ impl Display for LabelOwned
if let Some(name) = &self.name {
formatter.write_str("::")?;
- formatter.write_str(&name)?;
+ formatter.write_str(name)?;
}
Ok(())
@@ -125,7 +127,7 @@ impl Display for LabelOwned
#[derive(Debug, Sole)]
pub struct Assets
{
- assets: Vec<StoredAsset>,
+ store: Vec<StoredAsset>,
asset_lookup: RefCell<HashMap<LabelHash, LookupEntry>>,
importers: Vec<WrappedImporterFn>,
importer_lookup: HashMap<OsString, usize>,
@@ -137,13 +139,14 @@ pub struct Assets
impl Assets
{
+ #[must_use]
pub fn with_capacity(capacity: usize) -> Self
{
let (import_work_msg_sender, import_work_msg_receiver) =
mpsc_channel::<ImportWorkMessage>();
Self {
- assets: Vec::with_capacity(capacity),
+ store: Vec::with_capacity(capacity),
asset_lookup: RefCell::new(HashMap::with_capacity(capacity)),
importers: Vec::new(),
importer_lookup: HashMap::new(),
@@ -194,7 +197,9 @@ impl Assets
tracing::Span::current()
.record("asset_label", tracing::field::display(&asset_label));
- let stored_asset = self.assets.get(*asset_index).expect("Not possible");
+ let Some(stored_asset) = self.store.get(*asset_index) else {
+ unreachable!();
+ };
let Some(asset) = stored_asset.strong.downcast_ref::<Asset>() else {
tracing::error!("Wrong asset type");
@@ -220,12 +225,14 @@ impl Assets
return None;
};
- let stored_asset = self.assets.get(*asset_index).expect("Not possible");
+ let Some(stored_asset) = self.store.get(*asset_index) else {
+ unreachable!();
+ };
if stored_asset.strong.downcast_ref::<Asset>().is_none() {
tracing::error!("Wrong asset type");
return None;
- };
+ }
Some(Handle::new(label_hash))
}
@@ -243,7 +250,9 @@ impl Assets
return false;
};
- let stored_asset = self.assets.get(*asset_index).expect("Not possible");
+ let Some(stored_asset) = self.store.get(*asset_index) else {
+ unreachable!();
+ };
stored_asset.strong.downcast_ref::<Asset>().is_some()
}
@@ -306,7 +315,9 @@ impl Assets
match lookup_entry {
LookupEntry::Occupied(asset_index, _) => {
- let stored_asset = self.assets.get(*asset_index).expect("Not possible");
+ let Some(stored_asset) = self.store.get(*asset_index) else {
+ unreachable!();
+ };
if stored_asset.strong.downcast_ref::<Asset>().is_none() {
tracing::error!("Wrong asset type {}", type_name::<Asset>());
@@ -351,7 +362,9 @@ impl Assets
match lookup_entry {
LookupEntry::Occupied(asset_index, _) => {
- let stored_asset = self.assets.get(*asset_index).expect("Not possible");
+ let Some(stored_asset) = self.store.get(*asset_index) else {
+ unreachable!();
+ };
if stored_asset.strong.downcast_ref::<Asset>().is_none() {
tracing::error!(
@@ -420,9 +433,9 @@ impl Assets
tracing::debug!("Storing asset");
- self.assets.push(StoredAsset::new(asset));
+ self.store.push(StoredAsset::new(asset));
- let index = self.assets.len() - 1;
+ let index = self.store.len() - 1;
self.asset_lookup
.get_mut()
@@ -455,7 +468,7 @@ impl Assets
if let Some(LookupEntry::Pending) = asset_lookup.get(&LabelHash::new(label)) {
return true;
- };
+ }
false
}
@@ -528,7 +541,11 @@ impl Assets
{
let index = *self.importer_lookup.get(file_ext)?;
- Some(self.importers.get(index).expect("Not possible"))
+ let Some(importer) = self.importers.get(index) else {
+ unreachable!();
+ };
+
+ Some(importer)
}
}
@@ -660,11 +677,13 @@ pub struct Handle<Asset: 'static>
impl<Asset: 'static> Handle<Asset>
{
+ #[must_use]
pub fn from_id(id: Id) -> Self
{
Self { id, _pd: PhantomData }
}
+ #[must_use]
pub fn id(&self) -> Id
{
self.id
@@ -838,17 +857,17 @@ fn add_received_assets(mut assets: Single<Assets>)
curr_tick_events.clear();
- while let Some(import_work_msg) = assets.import_work_msg_receiver.try_recv().ok() {
+ while let Ok(import_work_msg) = assets.import_work_msg_receiver.try_recv() {
match import_work_msg {
ImportWorkMessage::Store { do_store, label, asset } => {
do_store(assets, label, asset);
}
ImportWorkMessage::Load { do_load, label, asset_settings } => {
do_load(
- &assets,
+ assets,
Label {
path: label.path.as_path().into(),
- name: label.name.as_deref().map(|name| name.into()),
+ name: label.name.as_deref().map(std::convert::Into::into),
},
asset_settings,
);
diff --git a/engine/src/camera.rs b/engine/src/camera.rs
index 51cd54c..dfccbd7 100644
--- a/engine/src/camera.rs
+++ b/engine/src/camera.rs
@@ -16,6 +16,7 @@ pub struct Camera
impl Camera
{
+ #[must_use]
pub fn to_view_matrix(&self, camera_world_pos: Vec3<f32>) -> Matrix<f32, 4, 4>
{
let mut view = Matrix::new();
diff --git a/engine/src/collision.rs b/engine/src/collision.rs
index 015ab58..3808754 100644
--- a/engine/src/collision.rs
+++ b/engine/src/collision.rs
@@ -18,6 +18,7 @@ pub struct BoxCollider
impl BoxCollider
{
+ #[must_use]
pub fn for_mesh(mesh: &Mesh) -> Self
{
let furthest_dir_points = mesh.find_furthest_vertex_positions();
@@ -36,6 +37,7 @@ impl BoxCollider
}
}
+ #[must_use]
pub fn offset(self, offset: Vec3<f32>) -> Self
{
Self {
@@ -88,6 +90,7 @@ pub struct SphereCollider
impl SphereCollider
{
+ #[must_use]
pub fn offset(self, offset: Vec3<f32>) -> Self
{
Self {
diff --git a/engine/src/data_types/matrix.rs b/engine/src/data_types/matrix.rs
index 9ab5bd4..149f0dc 100644
--- a/engine/src/data_types/matrix.rs
+++ b/engine/src/data_types/matrix.rs
@@ -43,7 +43,7 @@ impl<Value, const ROWS: usize, const COLUMNS: usize> Matrix<Value, ROWS, COLUMNS
where
Row: Into<[Value; COLUMNS]>,
{
- let items = rows.map(|row| row.into());
+ let items = rows.map(Into::into);
Self { items }
}
@@ -59,7 +59,7 @@ impl<Value, const ROWS: usize, const COLUMNS: usize> Matrix<Value, ROWS, COLUMNS
pub fn items(&self) -> &[Value]
{
- &self.items.as_flattened()
+ self.items.as_flattened()
}
pub fn to_column_major(&self) -> [[Value; ROWS]; COLUMNS]
@@ -160,6 +160,7 @@ impl Matrix<f32, 4, 4>
self[CellPos { row: 3, col: 3 }] = 1.0;
}
+ #[must_use]
pub fn inverse(&self) -> Self
{
let coef_00 = self[CellPos { row: 2, col: 2 }] * self[CellPos { row: 3, col: 3 }]
@@ -411,7 +412,7 @@ where
fn mul(self, rhs: Vec3<Value>) -> Self::Output
{
- self * &rhs
+ <Self as Mul<&Vec3<Value>>>::mul(self, &rhs)
}
}
@@ -463,7 +464,7 @@ where
fn mul(self, rhs: Vec4<Value>) -> Self::Output
{
- self * &rhs
+ <Self as Mul<&Vec4<Value>>>::mul(self, &rhs)
}
}
diff --git a/engine/src/data_types/vector.rs b/engine/src/data_types/vector.rs
index 915599a..106f215 100644
--- a/engine/src/data_types/vector.rs
+++ b/engine/src/data_types/vector.rs
@@ -187,6 +187,7 @@ impl Vec3<f32>
.normalize()
}
+ #[must_use]
pub fn into_deg_angles(self) -> Angles<f32>
{
let Self { x, y, z } = self.normalize();
diff --git a/engine/src/file_format/wavefront/obj.rs b/engine/src/file_format/wavefront/obj.rs
index dbcee33..d1a1bf3 100644
--- a/engine/src/file_format/wavefront/obj.rs
+++ b/engine/src/file_format/wavefront/obj.rs
@@ -43,7 +43,7 @@ pub fn parse(obj_content: &str) -> Result<Obj, Error>
continue;
}
- let Some((keyword, _)) = line.split_once(" ") else {
+ let Some((keyword, _)) = line.split_once(' ') else {
continue;
};
@@ -119,19 +119,18 @@ impl Obj
for face in &self.faces {
for face_vertex in &face.vertices {
- if let Some(index) = added_face_vertices.get(&face_vertex) {
+ if let Some(index) = added_face_vertices.get(face_vertex) {
indices.push(*index);
continue;
}
- let pos = self
+ let pos = *self
.vertex_positions
.get(face_vertex.position as usize - 1)
.ok_or(Error::FaceVertexPositionNotFound {
vertex_pos_index: face_vertex.position,
- })?
- .clone();
+ })?;
let texture_pos = face_vertex.texture.map_or_else(
|| {
@@ -154,10 +153,11 @@ impl Obj
},
)?;
- let texture_pos = options
- .y_flip_uvs
- .then(|| Vec2 { x: texture_pos.x, y: -texture_pos.y })
- .unwrap_or(texture_pos);
+ let texture_pos = if options.y_flip_uvs {
+ Vec2 { x: texture_pos.x, y: -texture_pos.y }
+ } else {
+ texture_pos
+ };
let normal = face_vertex.normal.map_or_else(
|| {
@@ -243,14 +243,12 @@ impl Obj
fn with_capacities_from_item_cnts(item_counts: ItemCounts) -> Self
{
Self {
- vertex_positions: Vec::with_capacity(item_counts.pos_cnt),
- vertex_normals: Vec::with_capacity(item_counts.normal_cnt),
- texture_positions: Vec::with_capacity(item_counts.uv_cnt),
- faces: Vec::with_capacity(item_counts.face_cnt),
- mtl_libs: Vec::with_capacity(item_counts.mtl_lib_cnt),
- unique_used_material_names: Vec::with_capacity(
- item_counts.material_usage_cnt,
- ),
+ vertex_positions: Vec::with_capacity(item_counts.pos),
+ vertex_normals: Vec::with_capacity(item_counts.normal),
+ texture_positions: Vec::with_capacity(item_counts.uv),
+ faces: Vec::with_capacity(item_counts.face),
+ mtl_libs: Vec::with_capacity(item_counts.mtl_lib),
+ unique_used_material_names: Vec::with_capacity(item_counts.material_usage),
}
}
@@ -286,7 +284,7 @@ impl Obj
return Err(Error::UnsupportedArgumentCount {
keyword: statement.keyword.to_string(),
arg_count: statement.arguments.len(),
- line_no: line_no,
+ line_no,
});
}
@@ -294,7 +292,7 @@ impl Obj
return Err(Error::InvalidArgumentCount {
keyword: statement.keyword.to_string(),
arg_count: statement.arguments.len(),
- line_no: line_no,
+ line_no,
});
}
@@ -319,7 +317,7 @@ impl Obj
return Err(Error::UnsupportedArgumentCount {
keyword: statement.keyword.to_string(),
arg_count: statement.arguments.len(),
- line_no: line_no,
+ line_no,
});
}
@@ -327,7 +325,7 @@ impl Obj
return Err(Error::InvalidArgumentCount {
keyword: statement.keyword.to_string(),
arg_count: statement.arguments.len(),
- line_no: line_no,
+ line_no,
});
}
@@ -351,7 +349,7 @@ impl Obj
return Err(Error::InvalidArgumentCount {
keyword: statement.keyword.to_string(),
arg_count: statement.arguments.len(),
- line_no: line_no,
+ line_no,
});
}
@@ -377,7 +375,7 @@ impl Obj
return Err(Error::InvalidArgumentCount {
keyword: statement.keyword.to_string(),
arg_count: statement.arguments.len(),
- line_no: line_no,
+ line_no,
});
}
@@ -408,7 +406,7 @@ impl Obj
return Err(Error::UnsupportedArgumentCount {
keyword: statement.keyword.to_string(),
arg_count: statement.arguments.len(),
- line_no: line_no,
+ line_no,
});
}
@@ -459,6 +457,7 @@ impl ToMeshOptions
/// their origin at the bottom left corner of the image
///
/// The default is `true`.
+ #[must_use]
pub fn y_flip_uvs(mut self, y_flip_uvs: bool) -> Self
{
self.y_flip_uvs = y_flip_uvs;
@@ -578,12 +577,12 @@ struct ParsingState
#[derive(Debug, Default)]
struct ItemCounts
{
- pos_cnt: usize,
- uv_cnt: usize,
- normal_cnt: usize,
- face_cnt: usize,
- mtl_lib_cnt: usize,
- material_usage_cnt: usize,
+ pos: usize,
+ uv: usize,
+ normal: usize,
+ face: usize,
+ mtl_lib: usize,
+ material_usage: usize,
}
impl ItemCounts
@@ -591,12 +590,12 @@ impl ItemCounts
fn increment_item_cnt_by_keyword(&mut self, keyword: Keyword)
{
match keyword {
- Keyword::V => self.pos_cnt += 1,
- Keyword::Vn => self.normal_cnt += 1,
- Keyword::Vt => self.uv_cnt += 1,
- Keyword::F => self.face_cnt += 1,
- Keyword::Mtllib => self.mtl_lib_cnt += 1,
- Keyword::Usemtl => self.material_usage_cnt += 1,
+ Keyword::V => self.pos += 1,
+ Keyword::Vn => self.normal += 1,
+ Keyword::Vt => self.uv += 1,
+ Keyword::F => self.face += 1,
+ Keyword::Mtllib => self.mtl_lib += 1,
+ Keyword::Usemtl => self.material_usage += 1,
Keyword::O | Keyword::S => {}
}
}
diff --git a/engine/src/image.rs b/engine/src/image.rs
index b01ea53..fd6629e 100644
--- a/engine/src/image.rs
+++ b/engine/src/image.rs
@@ -70,22 +70,25 @@ impl Image
Self::from((color, size))
}
+ #[must_use]
pub fn dimensions(&self) -> Dimens<u32>
{
self.inner.dimensions().into()
}
+ #[must_use]
pub fn color_type(&self) -> ColorType
{
self.inner.color().into()
}
+ #[must_use]
pub fn color_space_is_srgb(&self) -> bool
{
- match self.inner.color_space().primaries {
- image_rs::metadata::CicpColorPrimaries::SRgb => true,
- _ => false,
- }
+ matches!(
+ self.inner.color_space().primaries,
+ image_rs::metadata::CicpColorPrimaries::SRgb
+ )
}
/// Returns a immutable view of a subsection of this image.
@@ -93,14 +96,16 @@ impl Image
///
/// # Panics
/// Panics if the view would be out of bounds
+ #[must_use]
pub fn sub_view(&self, offset: Vec2<u32>, size: Dimens<u32>) -> SubView<'_>
{
assert!(offset.x + size.width <= self.dimensions().width);
assert!(offset.y + size.height <= self.dimensions().height);
- SubView { image: &self, offset, size }
+ SubView { image: self, offset, size }
}
+ #[must_use]
pub fn to_rgba8(&self) -> Self
{
Self { inner: self.inner.to_rgba8().into() }
@@ -108,6 +113,7 @@ impl Image
/// Consumes the image and returns a RGBA8 image. If it already is RGBA8, the image is
/// returned as is. If not, the image is converted to RGBA8.
+ #[must_use]
pub fn into_rgba8(self) -> Self
{
Self {
@@ -115,11 +121,13 @@ impl Image
}
}
+ #[must_use]
pub fn as_bytes(&self) -> &[u8]
{
self.inner.as_bytes()
}
+ #[must_use]
pub fn into_bytes(self) -> Vec<u8>
{
self.inner.into_bytes()
@@ -303,6 +311,7 @@ pub struct SubView<'image>
impl SubView<'_>
{
+ #[must_use]
pub fn to_image(&self) -> Image
{
fn create_sub_image<Image>(
diff --git a/engine/src/lib.rs b/engine/src/lib.rs
index 36affff..57aa125 100644
--- a/engine/src/lib.rs
+++ b/engine/src/lib.rs
@@ -1,5 +1,10 @@
#![deny(clippy::all, clippy::pedantic)]
-#![allow(clippy::needless_pass_by_value)]
+#![allow(
+ clippy::needless_pass_by_value,
+ clippy::struct_excessive_bools,
+ clippy::type_complexity,
+ clippy::too_many_arguments
+)]
use crate::asset::{Assets, Extension as AssetExtension};
use crate::ecs::error::HandlerFn as ErrorHandlerFn;
@@ -67,12 +72,14 @@ impl Engine
Self { world }
}
+ #[must_use]
pub fn with_error_handler(mut self, error_handler: ErrorHandlerFn) -> Self
{
self.world.set_err_handler(error_handler);
self
}
+ #[must_use]
pub fn with_extension(mut self, extension: impl Extension) -> Self
{
self.world.add_extension(extension);
diff --git a/engine/src/lighting.rs b/engine/src/lighting.rs
index 5314e58..8b75de0 100644
--- a/engine/src/lighting.rs
+++ b/engine/src/lighting.rs
@@ -122,6 +122,7 @@ pub struct Environmental
impl Environmental
{
+ #[must_use]
pub fn builder() -> EnvironmentalBuilder
{
EnvironmentalBuilder::default()
diff --git a/engine/src/material.rs b/engine/src/material.rs
index af982f4..fc9fcd7 100644
--- a/engine/src/material.rs
+++ b/engine/src/material.rs
@@ -22,6 +22,7 @@ pub struct Material
impl Material
{
+ #[must_use]
pub fn builder() -> Builder
{
Builder::new()
@@ -187,6 +188,7 @@ impl Default for Flags
impl FlagsBuilder
{
+ #[must_use]
pub const fn new() -> Self
{
Self { use_ambient_color: false }
diff --git a/engine/src/mesh.rs b/engine/src/mesh.rs
index c1c0f77..771f7bd 100644
--- a/engine/src/mesh.rs
+++ b/engine/src/mesh.rs
@@ -17,13 +17,26 @@ pub struct Mesh
impl Mesh
{
+ #[must_use]
pub fn cube(size: Dimens3<f32>) -> Self
{
Self::cube_with_options(CubeOptions::default().size(size))
}
+ #[must_use]
pub fn cube_with_options(options: CubeOptions) -> Self
{
+ #[inline]
+ fn vertex(pos: [f32; 3], uv: [f32; 2], normal: Vec3<f32>) -> [f32; 8]
+ {
+ let [pos_x, pos_y, pos_z] = pos;
+ let [uv_x, uv_y] = uv;
+
+ [
+ pos_x, pos_y, pos_z, uv_x, uv_y, normal.x, normal.y, normal.z,
+ ]
+ }
+
let CubeOptions {
size,
top_face:
@@ -62,17 +75,6 @@ impl Mesh
let half_h = size.height / 2.0;
let half_d = size.depth / 2.0;
- #[inline(always)]
- fn vertex(pos: [f32; 3], uv: [f32; 2], normal: Vec3<f32>) -> [f32; 8]
- {
- let [pos_x, pos_y, pos_z] = pos;
- let [uv_x, uv_y] = uv;
-
- [
- pos_x, pos_y, pos_z, uv_x, uv_y, normal.x, normal.y, normal.z,
- ]
- }
-
let top_vertices = [
(
[half_w, half_h, half_d],
@@ -235,11 +237,13 @@ impl Mesh
.build()
}
+ #[must_use]
pub fn builder() -> Builder
{
Builder::default()
}
+ #[must_use]
pub fn vertex_buf(&self) -> &vertex_buffer::VertexBuffer
{
&self.vertex_buf
@@ -264,22 +268,22 @@ impl Mesh
pub fn set_indices(&mut self, indices: impl IntoIterator<Item = u32>)
{
- let curr_indices = self.indices.get_or_insert_with(|| Vec::new());
+ let curr_indices = self.indices.get_or_insert_with(Vec::new);
curr_indices.clear();
- curr_indices.extend(indices.into_iter());
+ curr_indices.extend(indices);
}
/// Finds the vertex positions that are furthest in every 3D direction. Keep in mind
/// that this can be quite time-expensive if the mesh has many vertices.
+ #[must_use]
pub fn find_furthest_vertex_positions(&self) -> DirectionPositions
{
let mut pos_iter = self
.vertex_buf()
.iter::<[f32; 3]>(VertexLabel::Position)
- .map(|vertex_pos| Vec3::from(*vertex_pos))
- .into_iter();
+ .map(|vertex_pos| Vec3::from(*vertex_pos));
let first_pos = pos_iter.next().unwrap();
@@ -318,23 +322,27 @@ pub struct Builder
impl Builder
{
+ #[must_use]
pub fn new() -> Self
{
Self::default()
}
+ #[must_use]
pub fn vertices(mut self, vertices_bytes: vertex_buffer::VertexBuffer) -> Self
{
self.vertex_buf = vertices_bytes;
self
}
+ #[must_use]
pub fn indices(mut self, indices: impl IntoIterator<Item = u32>) -> Self
{
self.indices = Some(indices.into_iter().collect());
self
}
+ #[must_use]
pub fn build(self) -> Mesh
{
Mesh {
@@ -356,6 +364,7 @@ pub enum VertexAttrType
impl VertexAttrType
{
+ #[must_use]
pub fn layout(&self) -> Layout
{
match self {
@@ -469,6 +478,7 @@ impl CubeFaceOptions
/// would be on the upper left of the face.
///
/// The default is `(0, 0)`
+ #[must_use]
pub fn uv_upper_left(mut self, uv_upper_left: Vec2<f32>) -> Self
{
self.uv_upper_left = uv_upper_left;
@@ -479,6 +489,7 @@ impl CubeFaceOptions
/// would be on the lower right of the face.
///
/// The default is `(1, 1)`
+ #[must_use]
pub fn uv_lower_right(mut self, uv_lower_right: Vec2<f32>) -> Self
{
self.uv_lower_right = uv_lower_right;
diff --git a/engine/src/mesh/vertex_buffer.rs b/engine/src/mesh/vertex_buffer.rs
index 5c03b45..64edc58 100644
--- a/engine/src/mesh/vertex_buffer.rs
+++ b/engine/src/mesh/vertex_buffer.rs
@@ -75,6 +75,7 @@ pub struct VertexBuffer
impl VertexBuffer
{
+ #[must_use]
pub unsafe fn from_raw(
vertex_attr_props: &[VertexAttrProperties],
buffer: Vec<u8>,
@@ -95,6 +96,7 @@ impl VertexBuffer
}
}
+ #[must_use]
pub fn with_capacity(vertex_attrs: &[VertexAttrInfo], capacity: usize) -> Self
{
let mut vertex_attr_props = vertex_attrs
@@ -169,11 +171,13 @@ impl VertexBuffer
}
}
+ #[must_use]
pub fn vertex_attr_props(&self) -> &[VertexAttrProperties]
{
&self.vertex_attr_props
}
+ #[must_use]
pub fn len(&self) -> usize
{
assert_eq!(self.buf.len() % self.vertex_size, 0, "Invalid length");
@@ -181,11 +185,19 @@ impl VertexBuffer
self.buf.len() / self.vertex_size
}
+ #[must_use]
+ pub fn is_empty(&self) -> bool
+ {
+ self.buf.is_empty()
+ }
+
+ #[must_use]
pub fn vertex_size(&self) -> usize
{
self.vertex_size
}
+ #[must_use]
pub fn as_bytes(&self) -> &[u8]
{
&self.buf
@@ -196,6 +208,7 @@ impl VertexBuffer
self.buf.clear();
}
+ #[must_use]
pub fn iter<VertexAttr: VertexAttrValue>(
&self,
vertex_label: VertexLabel,
diff --git a/engine/src/model.rs b/engine/src/model.rs
index 1269afd..560c43d 100644
--- a/engine/src/model.rs
+++ b/engine/src/model.rs
@@ -14,6 +14,7 @@ pub struct Model
impl Model
{
+ #[must_use]
pub fn new(asset_handle: AssetHandle<Spec>) -> Self
{
Self { spec_asset: asset_handle }
@@ -30,6 +31,7 @@ pub struct Spec
impl Spec
{
+ #[must_use]
pub fn builder() -> SpecBuilder
{
SpecBuilder::default()
@@ -62,6 +64,7 @@ pub struct SpecBuilder
impl SpecBuilder
{
+ #[must_use]
pub fn mesh(mut self, asset: AssetHandle<Mesh>) -> Self
{
self.mesh_asset = Some(asset);
@@ -69,6 +72,7 @@ impl SpecBuilder
self
}
+ #[must_use]
pub fn materials(
mut self,
materials: impl IntoIterator<Item = MaterialDescription>,
@@ -98,6 +102,7 @@ pub struct MaterialDescription
impl MaterialDescription
{
+ #[must_use]
pub fn new(asset: AssetHandle<Material>) -> Self
{
Self { asset }
diff --git a/engine/src/model/asset.rs b/engine/src/model/asset.rs
index 52a6733..ff5eddf 100644
--- a/engine/src/model/asset.rs
+++ b/engine/src/model/asset.rs
@@ -24,6 +24,7 @@ impl Settings
/// their origin at the bottom left corner of the image
///
/// The default is `true`.
+ #[must_use]
pub fn y_flip_uvs(mut self, y_flip_uvs: bool) -> Self
{
self.y_flip_uvs = y_flip_uvs;
diff --git a/engine/src/projection.rs b/engine/src/projection.rs
index b3bfa00..91a0259 100644
--- a/engine/src/projection.rs
+++ b/engine/src/projection.rs
@@ -15,6 +15,7 @@ pub enum Projection
impl Projection
{
+ #[must_use]
pub fn to_matrix_rh(
&self,
window_size: PhysicalSize<u32>,
@@ -47,6 +48,7 @@ impl Perspective
{
/// Creates a perspective projection matrix using right-handed coordinates.
#[inline]
+ #[must_use]
pub fn to_matrix_rh(&self, aspect: f32, clip_volume: ClipVolume)
-> Matrix<f32, 4, 4>
{
@@ -107,12 +109,14 @@ pub struct Orthographic
impl Orthographic
{
+ #[must_use]
pub fn builder() -> OrthographicBuilder
{
OrthographicBuilder::default()
}
/// Creates a orthographic projection matrix using right-handed coordinates.
+ #[must_use]
pub fn to_matrix_rh(
&self,
window_size: PhysicalSize<u32>,
@@ -187,6 +191,7 @@ pub struct OrthographicParams
}
/// Creates a orthographic projection matrix using right-handed coordinates.
+#[must_use]
pub fn orthographic_rh(
OrthographicParams { left, right, bottom, top, near, far }: OrthographicParams,
clip_volume: ClipVolume,
diff --git a/engine/src/rendering.rs b/engine/src/rendering.rs
index 6840dbe..bf0ab4e 100644
--- a/engine/src/rendering.rs
+++ b/engine/src/rendering.rs
@@ -57,6 +57,7 @@ pub struct Extension {
impl Extension
{
+ #[must_use]
pub fn builder() -> ExtensionBuilder
{
ExtensionBuilder::default()
@@ -131,6 +132,7 @@ pub struct GraphicsProperties
impl GraphicsProperties
{
+ #[must_use]
pub fn builder() -> GraphicsPropertiesBuilder
{
GraphicsPropertiesBuilder::default()
@@ -147,12 +149,14 @@ impl Default for GraphicsProperties
impl GraphicsPropertiesBuilder
{
+ #[must_use]
pub fn multisampling_sample_cnt(mut self, multisampling_sample_cnt: u8) -> Self
{
self.multisampling_sample_cnt = Some(multisampling_sample_cnt);
self
}
+ #[must_use]
pub fn no_multisampling(mut self) -> Self
{
self.multisampling_sample_cnt = None;
@@ -282,6 +286,7 @@ builder! {
impl DrawMeshOptions
{
+ #[must_use]
pub fn builder() -> DrawMeshOptionsBuilder
{
DrawMeshOptionsBuilder::default()
@@ -290,6 +295,7 @@ impl DrawMeshOptions
impl DrawMeshOptionsBuilder
{
+ #[must_use]
pub fn element_cnt(mut self, element_cnt: u32) -> Self
{
self.element_cnt = Some(element_cnt);
@@ -535,7 +541,7 @@ fn enqueue_commands_from_render_passes(
window.inner_size,
));
- window_surface.size = window.inner_size.clone();
+ window_surface.size = window.inner_size;
}
}
@@ -556,7 +562,7 @@ fn enqueue_commands_from_render_passes(
Command::UpdateDrawProperties(draw_props, _) => Some(draw_props.clone()),
_ => None,
})
- .last();
+ .next_back();
command_queue.queue.extend(render_pass.commands);
@@ -664,6 +670,7 @@ pub enum TexturePixelDataFormat
impl TexturePixelDataFormat
{
+ #[must_use]
pub fn for_image(image: &Image) -> Option<Self>
{
let is_srgb = image.color_space_is_srgb();
diff --git a/engine/src/rendering/backend.rs b/engine/src/rendering/backend.rs
index d69b338..495f223 100644
--- a/engine/src/rendering/backend.rs
+++ b/engine/src/rendering/backend.rs
@@ -3,6 +3,7 @@ use ecs::extension::Extension;
pub mod opengl;
/// Returns the default rendering backend.
+#[must_use]
pub fn get_default() -> impl Extension
{
self::opengl::Extension::default()
diff --git a/engine/src/rendering/backend/opengl.rs b/engine/src/rendering/backend/opengl.rs
index 8b887b3..0a04d6e 100644
--- a/engine/src/rendering/backend/opengl.rs
+++ b/engine/src/rendering/backend/opengl.rs
@@ -419,7 +419,7 @@ impl BackendShaderBinding
);
}
BackendShaderBinding::Texture(texture) => {
- texture.bind_to_texture_unit(gl_context, binding_index.0)
+ texture.bind_to_texture_unit(gl_context, binding_index.0);
}
}
}
@@ -542,10 +542,9 @@ fn prepare_windows(
let window_handle = match window
.as_ref()
- .map(|window| unsafe {
+ .and_then(|window| unsafe {
windowing_context.get_window_as_handle(&window.wid())
})
- .flatten()
.transpose()
{
Ok(window_handle) => window_handle,
@@ -555,7 +554,7 @@ fn prepare_windows(
}
};
- let (new_window_creation_attrs, gl_config) = match DisplayBuilder::new()
+ let (new_window_creation_attrs, gl_config) = match DisplayBuilder::default()
.with_window_attributes(window_creation_attrs.clone())
.build(
window_handle,
@@ -638,7 +637,7 @@ fn init_window_graphics(
};
let Ok(window_inner_size) =
- PhysicalSize::<NonZero<u32>>::try_convert_from(window.inner_size.clone())
+ PhysicalSize::<NonZero<u32>>::try_convert_from(window.inner_size)
else {
tracing::error!(
"Cannot create a surface for a window with a width/height of 0",
@@ -669,7 +668,7 @@ fn init_window_graphics(
let gl_context = match graphics_ctx.gl_context.get_or_try_insert_with_fn(|| {
create_gl_context(
&window_gl_config.gl_config,
- &graphics_props,
+ graphics_props,
window_handle,
&window_surface,
)
@@ -684,10 +683,10 @@ fn init_window_graphics(
if let Err(err) = gl_context.make_current(&window_surface) {
tracing::error!("Failed to make GL context current: {err}");
continue;
- };
+ }
if let Err(err) = gl_set_viewport(
- &gl_context,
+ gl_context,
&Vec2 { x: 0, y: 0 }.into(),
&opengl_bindings::data_types::Dimens {
width: window.inner_size.width,
@@ -697,26 +696,22 @@ fn init_window_graphics(
tracing::error!("Failed to set viewport: {err}");
}
- set_enabled(
- &gl_context,
- Capability::DepthTest,
- graphics_props.depth_test,
- );
+ set_enabled(gl_context, Capability::DepthTest, graphics_props.depth_test);
set_enabled(
- &gl_context,
+ gl_context,
Capability::MultiSample,
graphics_props.multisampling_sample_cnt.is_some(),
);
if graphics_props.debug {
- enable(&gl_context, Capability::DebugOutput);
- enable(&gl_context, Capability::DebugOutputSynchronous);
+ enable(gl_context, Capability::DebugOutput);
+ enable(gl_context, Capability::DebugOutputSynchronous);
- set_debug_message_callback(&gl_context, opengl_debug_message_cb);
+ set_debug_message_callback(gl_context, opengl_debug_message_cb);
match set_debug_message_control(
- &gl_context,
+ gl_context,
None,
None,
None,
@@ -739,7 +734,7 @@ fn init_window_graphics(
window_ent_id,
(Surface {
id: surface_id,
- size: window.inner_size.clone(),
+ size: window.inner_size,
},),
);
@@ -747,7 +742,7 @@ fn init_window_graphics(
surface_id,
GraphicsContextSurface {
window_surface,
- size: window.inner_size.clone(),
+ size: window.inner_size,
},
);
}
@@ -927,7 +922,7 @@ fn handle_commands(
program.activate(gl_context);
- for (binding_index, binding) in bindings.iter() {
+ for (binding_index, binding) in bindings {
binding.bind(gl_context, binding_index);
}
@@ -945,7 +940,7 @@ fn handle_commands(
backend_resources,
object_store,
gl_context,
- shader_object_id.clone(),
+ shader_object_id,
&binding_location,
binding_value,
);
@@ -1097,7 +1092,7 @@ fn handle_commands(
Command::CreateMesh { obj_id, mesh, usage: mesh_usage } => {
let mesh = match &mesh {
AssetOrValue::Asset(mesh_asset) => {
- let Some(mesh) = assets.get(&mesh_asset) else {
+ let Some(mesh) = assets.get(mesh_asset) else {
tracing::error!(
asset_id=?mesh_asset.id(),
"Mesh asset does not exist"
@@ -1116,7 +1111,7 @@ fn handle_commands(
obj_id,
|| {
Ok(BackendResource::Mesh {
- mesh: GraphicsMesh::new(gl_context, &mesh, mesh_usage)?,
+ mesh: GraphicsMesh::new(gl_context, mesh, mesh_usage)?,
vertex_attrs_updated_for_shader: None,
})
},
@@ -1201,7 +1196,7 @@ fn handle_commands(
if let Err(err) = draw_mesh(gl_context, graphics_mesh, &draw_mesh_opts) {
tracing::error!("Failed to draw mesh: {err}");
- };
+ }
}
Command::UpdateDrawProperties(properties, update_flags) => {
update_draw_properties(
@@ -1237,7 +1232,7 @@ fn create_gl_context(
}
.map_err(CreateGlContextError::CreateGlutinContext)?;
- MaybeCurrentContextWithFns::new(glutin_context, &surface)
+ MaybeCurrentContextWithFns::new(glutin_context, surface)
.map_err(CreateGlContextError::MakeContextCurrent)
}
@@ -1519,8 +1514,8 @@ fn update_framebuffer_properties(
}
}
-fn set_shader_binding<'backend_resources>(
- backend_resources: &'backend_resources mut BackendResourceStore,
+fn set_shader_binding(
+ backend_resources: &mut BackendResourceStore,
object_store: &ObjectStore,
gl_context: &MaybeCurrentContextWithFns,
shader_object_id: ObjectId,
@@ -1549,14 +1544,11 @@ fn set_shader_binding<'backend_resources>(
None => return None,
};
- if let Some(prev_binding) =
+ // TODO: Textures should probably also be handled somehow here
+ if let Some(BackendShaderBinding::Uniform(prev_binding_uniform_buf)) =
shader_bindings.remove(ShaderBindingIndex(binding_location.binding_index))
{
- // TODO: Textures should probably also be handled somehow here
- if let BackendShaderBinding::Uniform(prev_binding_uniform_buf) = prev_binding
- {
- prev_binding_uniform_buf.delete(gl_context);
- }
+ prev_binding_uniform_buf.delete(gl_context);
}
return Some(
@@ -1588,27 +1580,27 @@ fn set_shader_binding<'backend_resources>(
None => return None,
};
- let binding = match shader_bindings
- .get(ShaderBindingIndex(binding_location.binding_index))
- .cloned()
+ let binding = if let Some(binding @ BackendShaderBinding::Uniform(_)) =
+ shader_bindings
+ .get(ShaderBindingIndex(binding_location.binding_index))
+ .cloned()
{
- Some(binding @ BackendShaderBinding::Uniform(_)) => binding,
- Some(_) | None => {
- let uniform_buf = GlBuffer::<u8>::new(gl_context);
+ binding
+ } else {
+ let uniform_buf = GlBuffer::<u8>::new(gl_context);
- uniform_buf
- .init(
- gl_context,
- binding_location.binding_size,
- opengl_bindings::buffer::Usage::Dynamic,
- )
- .unwrap();
+ uniform_buf
+ .init(
+ gl_context,
+ binding_location.binding_size,
+ opengl_bindings::buffer::Usage::Dynamic,
+ )
+ .unwrap();
- shader_bindings
- .entry(ShaderBindingIndex(binding_location.binding_index))
- .set_or_insert_with(|| BackendShaderBinding::Uniform(uniform_buf))
- .clone()
- }
+ shader_bindings
+ .entry(ShaderBindingIndex(binding_location.binding_index))
+ .set_or_insert_with(|| BackendShaderBinding::Uniform(uniform_buf))
+ .clone()
};
let BackendShaderBinding::Uniform(binding_uniform_buf) = &binding else {
@@ -1828,8 +1820,7 @@ fn create_shader_program(
stage: ShaderStage::Vertex,
entrypoint: vs_entry_point_reflection
.name()
- .map(|name| name.to_string().into())
- .unwrap_or("(none)".into()),
+ .map_or("(none)".into(), |name| name.to_string().into()),
})?;
let (fs_entry_point_index, fs_entry_point_reflection) = shader_program_reflection
@@ -1849,15 +1840,14 @@ fn create_shader_program(
stage: ShaderStage::Fragment,
entrypoint: fs_entry_point_reflection
.name()
- .map(|name| name.to_string().into())
- .unwrap_or("(none)".into()),
+ .map_or("(none)".into(), |name| name.to_string().into()),
})?;
let vertex_shader = GlShader::new(current_context, ShaderKind::Vertex);
vertex_shader.set_source(
current_context,
- &vertex_shader_entry_point_code.as_str().unwrap(),
+ vertex_shader_entry_point_code.as_str().unwrap(),
)?;
vertex_shader.compile(current_context)?;
@@ -1866,7 +1856,7 @@ fn create_shader_program(
fragment_shader.set_source(
current_context,
- &fragment_shader_entry_point_code.as_str().unwrap(),
+ fragment_shader_entry_point_code.as_str().unwrap(),
)?;
fragment_shader.compile(current_context)?;
@@ -1938,7 +1928,7 @@ fn opengl_debug_message_cb(
_ => {
emit_log_with_message!(tracing::Level::WARN);
}
- };
+ }
}
#[inline]
diff --git a/engine/src/rendering/backend/opengl/glutin_compat.rs b/engine/src/rendering/backend/opengl/glutin_compat.rs
index 27f82ad..0bdfcd2 100644
--- a/engine/src/rendering/backend/opengl/glutin_compat.rs
+++ b/engine/src/rendering/backend/opengl/glutin_compat.rs
@@ -66,12 +66,6 @@ pub struct DisplayBuilder
impl DisplayBuilder
{
- /// Create new display builder.
- pub fn new() -> Self
- {
- Default::default()
- }
-
/// The preference in picking the configuration.
#[allow(dead_code)]
pub fn with_preference(mut self, preference: ApiPreference) -> Self
@@ -153,7 +147,7 @@ impl DisplayBuilder
config_picker_fn(gl_configs).ok_or(Error::NoConfigPicked)?;
let window_attrs = cfg_select! {
- windows => { self.window_attributes }
+ windows => self.window_attributes,
_ => {
finalize_window_creation_attrs(self.window_attributes, &picked_gl_config)
}
@@ -179,39 +173,36 @@ pub enum Error
WindowRequired,
}
+#[allow(unused_variables)]
fn create_display(
display_handle: &DisplayHandle<'_>,
- _api_preference: ApiPreference,
- _raw_window_handle: Option<RawWindowHandle>,
+ api_preference: ApiPreference,
+ raw_window_handle: Option<RawWindowHandle>,
) -> Result<Display, GlutinError>
{
let preference = cfg_select! {
- windows => {
- match _api_preference {
- ApiPreference::PreferEgl => {
- DisplayApiPreference::EglThenWgl(_raw_window_handle)
- }
- ApiPreference::FallbackEgl => {
- DisplayApiPreference::WglThenEgl(_raw_window_handle)
- }
+ windows => match _api_preference {
+ ApiPreference::PreferEgl => {
+ DisplayApiPreference::EglThenWgl(_raw_window_handle)
}
- }
- target_os = "linux" => {
- match _api_preference {
- ApiPreference::PreferEgl => DisplayApiPreference::EglThenGlx(Box::new(
- crate::windowing::window::platform::x11::register_xlib_error_hook,
- )),
- ApiPreference::FallbackEgl => DisplayApiPreference::GlxThenEgl(Box::new(
- crate::windowing::window::platform::x11::register_xlib_error_hook,
- )),
+ ApiPreference::FallbackEgl => {
+ DisplayApiPreference::WglThenEgl(_raw_window_handle)
}
- }
- target_os = "macos" => { DisplayApiPreference::Cgl }
+ },
+ target_os = "linux" => match api_preference {
+ ApiPreference::PreferEgl => DisplayApiPreference::EglThenGlx(Box::new(
+ crate::windowing::window::platform::x11::register_xlib_error_hook,
+ )),
+ ApiPreference::FallbackEgl => DisplayApiPreference::GlxThenEgl(Box::new(
+ crate::windowing::window::platform::x11::register_xlib_error_hook,
+ )),
+ },
+ target_os = "macos" => DisplayApiPreference::Cgl,
};
let handle = display_handle.as_raw();
- unsafe { Ok(Display::new(handle, preference)?) }
+ unsafe { Display::new(handle, preference) }
}
/// Finalize [`Window`] creation by applying the options from the [`Config`], be
@@ -235,7 +226,8 @@ fn finalize_window_creation_attrs(
if let Some(x11_visual) = glutin::platform::x11::X11GlConfigExt::x11_visual(gl_config)
{
return attributes.with_x_visual_id(Some(
- x11_visual.visual_id() as crate::windowing::window::XVisualID
+ crate::windowing::window::XVisualID::try_from(x11_visual.visual_id())
+ .expect("X visual ID is too large"),
));
}
diff --git a/engine/src/rendering/backend/opengl/graphics_mesh.rs b/engine/src/rendering/backend/opengl/graphics_mesh.rs
index 43cd254..899f50f 100644
--- a/engine/src/rendering/backend/opengl/graphics_mesh.rs
+++ b/engine/src/rendering/backend/opengl/graphics_mesh.rs
@@ -69,8 +69,7 @@ impl GraphicsMesh
max_value,
} => {
panic!(
- "Size of vertex ({}) is too large. Must be less than {max_value}",
- value
+ "Size of vertex ({value}) is too large. Must be less than {max_value}"
);
}
}
@@ -86,7 +85,7 @@ impl GraphicsMesh
vertex_arr.bind_element_buffer(current_context, &index_buffer);
return Ok(Self {
- vertex_buffer: vertex_buffer,
+ vertex_buffer,
vertex_attr_props: mesh.vertex_buf().vertex_attr_props().to_vec(),
last_max_vertex_attr_index: 0,
index_buffer: Some(index_buffer),
@@ -99,7 +98,7 @@ impl GraphicsMesh
}
Ok(Self {
- vertex_buffer: vertex_buffer,
+ vertex_buffer,
vertex_attr_props: mesh.vertex_buf().vertex_attr_props().to_vec(),
last_max_vertex_attr_index: 0,
index_buffer: None,
@@ -135,7 +134,7 @@ impl GraphicsMesh
.map_err(Error::StoreIndicesFailed)?;
self.vertex_arr
- .bind_element_buffer(current_context, &index_buffer);
+ .bind_element_buffer(current_context, index_buffer);
self.element_cnt = indices
.len()
diff --git a/engine/src/rendering/main_render_pass.rs b/engine/src/rendering/main_render_pass.rs
index c762231..cb38071 100644
--- a/engine/src/rendering/main_render_pass.rs
+++ b/engine/src/rendering/main_render_pass.rs
@@ -237,9 +237,9 @@ pub fn add_main_render_pass(
continue;
}
- let model_material = match model_spec.find_first_material(&assets) {
+ let model_material = match model_spec.find_first_material(assets) {
MaterialSearchResult::Found(model_material_asset)
- if let Some(model_material) = assets.get(&model_material_asset) =>
+ if let Some(model_material) = assets.get(model_material_asset) =>
{
model_material
}
@@ -251,7 +251,7 @@ pub fn add_main_render_pass(
if model_material
.textures()
- .any(|texture_asset| !assets.is_loaded_and_has_type(&texture_asset))
+ .any(|texture_asset| !assets.is_loaded_and_has_type(texture_asset))
{
continue;
}
@@ -273,13 +273,7 @@ pub fn add_main_render_pass(
.commands
.push(Command::ActivateShader(shaders.main_3d_shader_obj_id));
- if let Some(draw_flags) = draw_flags.as_deref().and_then(|draw_flags| {
- if draw_flags.polygon_mode_config != PolygonModeConfig::default() {
- Some(draw_flags)
- } else {
- None
- }
- }) {
+ if let Some(draw_flags) = draw_flags.as_deref().filter(|&draw_flags| draw_flags.polygon_mode_config != PolygonModeConfig::default()) {
render_pass.commands.push(Command::UpdateDrawProperties(
DrawProperties {
polygon_mode_config: draw_flags.polygon_mode_config.clone(),
@@ -310,7 +304,7 @@ pub fn add_main_render_pass(
if let Some(scene_skybox) = &scene_skybox {
let Some(sky_box_ids) = load_sky_box(
scene_ent_id,
- &scene_skybox,
+ scene_skybox,
scene_skybox_state.as_deref(),
assets,
object_store,
@@ -489,9 +483,9 @@ fn add_renderable_creation_commands(
debug_assert!(model_spec.materials.len() <= 1);
- let model_material = match model_spec.find_first_material(&assets) {
+ let model_material = match model_spec.find_first_material(assets) {
MaterialSearchResult::Found(model_material_asset) => {
- let Some(model_material) = assets.get(&model_material_asset) else {
+ let Some(model_material) = assets.get(model_material_asset) else {
return;
};
@@ -726,7 +720,7 @@ fn add_set_3d_shader_renderable_bindings(
{
let (material, material_flags, transform) = renderable;
- let transform = match transform.as_deref() {
+ let transform = match transform {
Some(transform) => transform,
None => &Transform::default(),
};
@@ -735,11 +729,10 @@ fn add_set_3d_shader_renderable_bindings(
let inverted_model_matrix = model_matrix.inverse();
let material_flags = material_flags
- .as_deref()
.unwrap_or(&const { MaterialFlags::builder().build() });
let env_lighting = match &scene_env_lighting {
- Some(env_lighting) => &env_lighting,
+ Some(env_lighting) => env_lighting,
None => &EnvironmentalLighting::default(),
};
@@ -754,8 +747,7 @@ fn add_set_3d_shader_renderable_bindings(
let diffuse_map_obj_id = material
.diffuse_map
.as_ref()
- .map(|diffuse_map| ObjectId::Asset(diffuse_map.id()))
- .unwrap_or(white_1x1_tex_obj_id);
+ .map_or(white_1x1_tex_obj_id, |diffuse_map| ObjectId::Asset(diffuse_map.id()));
render_pass.commands.extend(
[
@@ -766,10 +758,8 @@ fn add_set_3d_shader_renderable_bindings(
.field("model_inverted")
.binding(inverted_model_matrix.into())?,
material_shader_cursor.field("ambient").binding(
- material_flags
- .use_ambient_color
- .then_some(&material.ambient)
- .unwrap_or(&env_lighting.ambient_color)
+ if material_flags
+ .use_ambient_color { &material.ambient } else { &env_lighting.ambient_color }
.to_rgb_lossy()
.into(),
)?,
@@ -784,8 +774,7 @@ fn add_set_3d_shader_renderable_bindings(
material
.ambient_map
.as_ref()
- .map(|ambient_map| ObjectId::Asset(ambient_map.id()))
- .unwrap_or(diffuse_map_obj_id),
+ .map_or(diffuse_map_obj_id, |ambient_map| ObjectId::Asset(ambient_map.id())),
ShaderBindingTextureKind::Texture2D,
),
)?,
@@ -800,8 +789,7 @@ fn add_set_3d_shader_renderable_bindings(
material
.specular_map
.as_ref()
- .map(|specular_map| ObjectId::Asset(specular_map.id()))
- .unwrap_or(white_1x1_tex_obj_id),
+ .map_or(white_1x1_tex_obj_id, |specular_map| ObjectId::Asset(specular_map.id())),
ShaderBindingTextureKind::Texture2D,
),
)?,
@@ -907,24 +895,21 @@ fn load_sky_box(
actions: &mut Actions,
) -> Result<Option<SkyBoxIds>, crate::Error>
{
- let mesh_object_id = match &sky_box_state {
- Some(sky_box_state) => sky_box_state.mesh_object_id,
- None => {
- let sky_box_mesh =
- Mesh::cube(Dimens3 { width: 1.0, height: 1.0, depth: 1.0 });
+ let mesh_object_id = if let Some(sky_box_state) = &sky_box_state { sky_box_state.mesh_object_id } else {
+ let sky_box_mesh =
+ Mesh::cube(Dimens3 { width: 1.0, height: 1.0, depth: 1.0 });
- let mesh_object_id = ObjectId::new_sequential();
+ let mesh_object_id = ObjectId::new_sequential();
- object_store.insert_pending(mesh_object_id);
+ object_store.insert_pending(mesh_object_id);
- render_pass.commands.push(Command::CreateMesh {
- obj_id: mesh_object_id,
- mesh: AssetOrValue::Value(sky_box_mesh),
- usage: MeshUsage::Static,
- });
+ render_pass.commands.push(Command::CreateMesh {
+ obj_id: mesh_object_id,
+ mesh: AssetOrValue::Value(sky_box_mesh),
+ usage: MeshUsage::Static,
+ });
- mesh_object_id
- }
+ mesh_object_id
};
let texture_object_id = match &sky_box {
@@ -952,7 +937,7 @@ fn load_sky_box(
})
.collect::<Vec<_>>()
.as_array::<6>()
- .cloned()
+ .copied()
else {
return Ok(None);
};
diff --git a/engine/src/rendering/object.rs b/engine/src/rendering/object.rs
index 61e7ed5..d496eda 100644
--- a/engine/src/rendering/object.rs
+++ b/engine/src/rendering/object.rs
@@ -26,6 +26,7 @@ impl Id
))
}
+ #[must_use]
pub fn into_asset_id(self) -> Option<AssetId>
{
match self {
@@ -55,16 +56,19 @@ pub struct Store
impl Store
{
+ #[must_use]
pub fn get_obj(&self, id: &Id) -> Option<&Object>
{
self.objects.get(id).and_then(|obj| obj.as_ref())
}
+ #[must_use]
pub fn contains_maybe_pending_with_id(&self, id: &Id) -> bool
{
self.objects.contains_key(id)
}
+ #[must_use]
pub fn contains_non_pending_with_id(&self, id: &Id) -> bool
{
self.objects.get(id).and_then(|obj| obj.as_ref()).is_some()
@@ -96,16 +100,19 @@ pub struct Object
impl Object
{
+ #[must_use]
pub fn from_raw(raw: RawValue, kind: Kind) -> Self
{
Self { raw, kind }
}
+ #[must_use]
pub fn as_raw(&self) -> RawValue
{
self.raw
}
+ #[must_use]
pub fn kind(&self) -> Kind
{
self.kind
diff --git a/engine/src/rendering/shader.rs b/engine/src/rendering/shader.rs
index 3f07381..085773b 100644
--- a/engine/src/rendering/shader.rs
+++ b/engine/src/rendering/shader.rs
@@ -70,6 +70,7 @@ pub struct Module
impl Module
{
+ #[must_use]
pub fn entry_points(&self) -> impl ExactSizeIterator<Item = EntryPoint> + use<'_>
{
self.inner
@@ -77,6 +78,7 @@ impl Module
.map(|entry_point| EntryPoint { inner: entry_point })
}
+ #[must_use]
pub fn get_entry_point(&self, entry_point: &str) -> Option<EntryPoint>
{
let entry_point = self.inner.find_entry_point_by_name(entry_point)?;
@@ -84,6 +86,7 @@ impl Module
Some(EntryPoint { inner: entry_point })
}
+ #[must_use]
pub fn file_path(&self) -> &str
{
self.inner.file_path()
@@ -97,6 +100,7 @@ pub struct EntryPoint
impl EntryPoint
{
+ #[must_use]
pub fn function(&self) -> FunctionReflection<'_>
{
FunctionReflection {
@@ -110,8 +114,9 @@ pub struct FunctionReflection<'a>
inner: &'a shader_slang::reflection::Function,
}
-impl<'a> FunctionReflection<'a>
+impl FunctionReflection<'_>
{
+ #[must_use]
pub fn name(&self) -> Option<&str>
{
self.inner.name()
@@ -125,21 +130,25 @@ pub struct EntryPointReflection<'a>
impl<'a> EntryPointReflection<'a>
{
+ #[must_use]
pub fn name(&self) -> Option<&str>
{
self.inner.name()
}
+ #[must_use]
pub fn name_override(&self) -> Option<&str>
{
self.inner.name_override()
}
+ #[must_use]
pub fn stage(&self) -> Stage
{
Stage::from_slang_stage(self.inner.stage())
}
+ #[must_use]
pub fn parameters(&self) -> impl ExactSizeIterator<Item = VariableLayout<'a>>
{
self.inner
@@ -147,6 +156,7 @@ impl<'a> EntryPointReflection<'a>
.map(|param| VariableLayout { inner: param })
}
+ #[must_use]
pub fn var_layout(&self) -> Option<VariableLayout<'a>>
{
Some(VariableLayout { inner: self.inner.var_layout()? })
@@ -172,6 +182,7 @@ impl Program
})
}
+ #[must_use]
pub fn metadata(&self) -> &ProgramMetadata
{
&self.metadata
@@ -186,7 +197,7 @@ impl Program
pub fn reflection(&self, target: u32) -> Result<ProgramReflection<'_>, Error>
{
- let reflection = self.inner.layout(target as i64)?;
+ let reflection = self.inner.layout(i64::from(target))?;
Ok(ProgramReflection { inner: reflection })
}
@@ -209,6 +220,7 @@ pub struct ProgramReflection<'a>
impl<'a> ProgramReflection<'a>
{
+ #[must_use]
pub fn get_entry_point_by_index(&self, index: u32)
-> Option<EntryPointReflection<'a>>
{
@@ -217,6 +229,7 @@ impl<'a> ProgramReflection<'a>
})
}
+ #[must_use]
pub fn get_entry_point_by_name(&self, name: &str)
-> Option<EntryPointReflection<'a>>
{
@@ -225,6 +238,7 @@ impl<'a> ProgramReflection<'a>
})
}
+ #[must_use]
pub fn entry_points(
&self,
) -> impl ExactSizeIterator<Item = EntryPointReflection<'a>> + use<'a>
@@ -234,6 +248,7 @@ impl<'a> ProgramReflection<'a>
.map(|entry_point| EntryPointReflection { inner: entry_point })
}
+ #[must_use]
pub fn global_params_type_layout(&self) -> Option<TypeLayout<'a>>
{
Some(TypeLayout {
@@ -241,6 +256,7 @@ impl<'a> ProgramReflection<'a>
})
}
+ #[must_use]
pub fn global_params_var_layout(&self) -> Option<VariableLayout<'a>>
{
Some(VariableLayout {
@@ -248,6 +264,7 @@ impl<'a> ProgramReflection<'a>
})
}
+ #[must_use]
pub fn get_type(&self, name: &str) -> Option<TypeReflection<'a>>
{
Some(TypeReflection {
@@ -255,12 +272,13 @@ impl<'a> ProgramReflection<'a>
})
}
+ #[must_use]
pub fn get_type_layout(&self, ty: &TypeReflection<'a>) -> Option<TypeLayout<'a>>
{
Some(TypeLayout {
inner: self
.inner
- .type_layout(&ty.inner, shader_slang::LayoutRules::Default)?,
+ .type_layout(ty.inner, shader_slang::LayoutRules::Default)?,
})
}
}
@@ -273,16 +291,19 @@ pub struct VariableLayout<'a>
impl<'a> VariableLayout<'a>
{
+ #[must_use]
pub fn name(&self) -> Option<&'a str>
{
self.inner.name()
}
+ #[must_use]
pub fn semantic_name(&self) -> Option<&str>
{
self.inner.semantic_name()
}
+ #[must_use]
pub fn binding_index(&self) -> u32
{
self.inner
@@ -291,6 +312,7 @@ impl<'a> VariableLayout<'a>
// self.inner.binding_index()
}
+ #[must_use]
pub fn varying_input_offset(&self) -> Option<usize>
{
if !self
@@ -304,26 +326,31 @@ impl<'a> VariableLayout<'a>
Some(self.inner.offset(SlangParameterCategory::VaryingInput))
}
+ #[must_use]
pub fn binding_space(&self) -> u32
{
self.inner.binding_space()
}
+ #[must_use]
pub fn semantic_index(&self) -> usize
{
self.inner.semantic_index()
}
+ #[must_use]
pub fn offset(&self) -> usize
{
self.inner.offset(shader_slang::ParameterCategory::Uniform)
}
+ #[must_use]
pub fn ty(&self) -> Option<TypeReflection<'a>>
{
self.inner.ty().map(|ty| TypeReflection { inner: ty })
}
+ #[must_use]
pub fn type_layout(&self) -> Option<TypeLayout<'a>>
{
Some(TypeLayout { inner: self.inner.type_layout()? })
@@ -338,11 +365,13 @@ pub struct TypeLayout<'a>
impl<'a> TypeLayout<'a>
{
+ #[must_use]
pub fn kind(&self) -> TypeKind
{
TypeKind::from_slang_type_kind(self.inner.kind())
}
+ #[must_use]
pub fn scalar_type(&self) -> Option<ScalarType>
{
Some(ScalarType::from_slang_scalar_type(
@@ -350,6 +379,7 @@ impl<'a> TypeLayout<'a>
))
}
+ #[must_use]
pub fn resource_shape(&self) -> Option<ResourceShape>
{
Some(ResourceShape::from_bits_retain(
@@ -357,6 +387,7 @@ impl<'a> TypeLayout<'a>
))
}
+ #[must_use]
pub fn get_field_by_name(&self, name: &str) -> Option<VariableLayout<'a>>
{
let index = self.inner.find_field_index_by_name(name);
@@ -372,16 +403,19 @@ impl<'a> TypeLayout<'a>
Some(VariableLayout { inner: field })
}
+ #[must_use]
pub fn parameter_category(&self) -> ParameterCategory
{
ParameterCategory::from_slang_parameter_category(self.inner.parameter_category())
}
+ #[must_use]
pub fn binding_range_descriptor_set_index(&self, index: i64) -> i64
{
self.inner.binding_range_descriptor_set_index(index)
}
+ #[must_use]
pub fn get_field_binding_range_offset_by_name(&self, name: &str) -> Option<u64>
{
let field_index = self.inner.find_field_index_by_name(name);
@@ -400,40 +434,47 @@ impl<'a> TypeLayout<'a>
Some(field_binding_range_offset.cast_unsigned())
}
+ #[must_use]
pub fn ty(&self) -> Option<TypeReflection<'a>>
{
self.inner.ty().map(|ty| TypeReflection { inner: ty })
}
+ #[must_use]
pub fn fields(&self) -> FieldIter<'a>
{
FieldIter {
- type_layout: self.clone(),
+ type_layout: *self,
cnt: self.field_cnt(),
index: 0,
}
}
+ #[must_use]
pub fn field_cnt(&self) -> u32
{
self.inner.field_count()
}
+ #[must_use]
pub fn element_cnt(&self) -> Option<usize>
{
self.inner.element_count()
}
+ #[must_use]
pub fn row_cnt(&self) -> Option<u32>
{
self.inner.row_count()
}
+ #[must_use]
pub fn column_cnt(&self) -> Option<u32>
{
self.inner.column_count()
}
+ #[must_use]
pub fn element_type_layout(&self) -> Option<TypeLayout<'a>>
{
self.inner
@@ -441,6 +482,7 @@ impl<'a> TypeLayout<'a>
.map(|type_layout| TypeLayout { inner: type_layout })
}
+ #[must_use]
pub fn element_var_layout(&self) -> Option<VariableLayout<'a>>
{
self.inner
@@ -448,6 +490,7 @@ impl<'a> TypeLayout<'a>
.map(|var_layout| VariableLayout { inner: var_layout })
}
+ #[must_use]
pub fn container_var_layout(&self) -> Option<VariableLayout<'a>>
{
self.inner
@@ -455,6 +498,7 @@ impl<'a> TypeLayout<'a>
.map(|var_layout| VariableLayout { inner: var_layout })
}
+ #[must_use]
pub fn uniform_size(&self) -> Option<usize>
{
// tracing::debug!(
@@ -483,6 +527,7 @@ impl<'a> TypeLayout<'a>
Some(self.inner.size(SlangParameterCategory::Uniform))
}
+ #[must_use]
pub fn stride(&self) -> usize
{
self.inner.stride(self.inner.categories().next().unwrap())
@@ -556,6 +601,7 @@ pub struct TypeReflection<'a>
impl TypeReflection<'_>
{
+ #[must_use]
pub fn kind(&self) -> TypeKind
{
TypeKind::from_slang_type_kind(self.inner.kind())
@@ -787,6 +833,7 @@ pub struct Blob
impl Blob
{
+ #[must_use]
pub fn as_bytes(&self) -> &[u8]
{
self.inner.as_slice()
@@ -868,11 +915,13 @@ pub struct Context
impl Context
{
+ #[must_use]
pub fn get_module(&self, asset_id: &AssetId) -> Option<&Module>
{
self.modules.get(asset_id)
}
+ #[must_use]
pub fn get_program(&self, asset_id: &AssetId) -> Option<&Program>
{
self.programs.get(asset_id)
@@ -1008,19 +1057,13 @@ impl VertexDescription
);
}
- let scalar_type = match (
+ let (TypeKind::Scalar | TypeKind::Vector, Some(scalar_type)) = (
var_input.type_layout.kind(),
var_input.type_layout.scalar_type(),
- ) {
- (TypeKind::Scalar, Some(scalar_type)) => scalar_type,
- (TypeKind::Vector, Some(scalar_type)) => scalar_type,
- _ => {
- return Err(
- VertexDescriptionError::UnsupportedVertexInputType {
- name: name.to_owned(),
- },
- );
- }
+ ) else {
+ return Err(VertexDescriptionError::UnsupportedVertexInputType {
+ name: name.to_owned(),
+ });
};
seen_inputs.insert(semantic_name.clone());
@@ -1072,6 +1115,7 @@ impl VertexInputSemName
}
}
+ #[must_use]
pub fn matches_vertex_label(&self, vertex_label: &VertexLabel) -> bool
{
match (self, vertex_label) {
@@ -1291,7 +1335,7 @@ pub(super) fn prepare(collector: &mut crate::ecs::extension::Collector<'_>)
let session_desc = shader_slang::SessionDesc::default()
.targets(&targets)
- .search_paths(&[""])
+ .search_paths([""])
.options(&session_options);
let Some(session) = global_session.create_session(&session_desc) else {
@@ -1359,7 +1403,7 @@ fn load_modules(
context.modules.insert(*asset_id, module.clone());
if !module_source.link_entrypoints.is_empty() {
- assert!(context.programs.get(asset_id).is_none());
+ assert!(!context.programs.contains_key(asset_id));
let shader_program = match context
.compose_into_program(module, module_source.link_entrypoints)
diff --git a/engine/src/rendering/shader/cursor.rs b/engine/src/rendering/shader/cursor.rs
index 49f6b47..551830d 100644
--- a/engine/src/rendering/shader/cursor.rs
+++ b/engine/src/rendering/shader/cursor.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
use std::fmt::Display;
use std::hint::cold_path;
-use circular_buffer::FixedCircularBuffer;
+use circular_buffer::HeapCircularBuffer;
use crate::color::{Color, Rgb, Rgba};
use crate::data_types::matrix::Matrix;
@@ -27,6 +27,7 @@ pub struct Cursor<'a>
impl<'a> Cursor<'a>
{
+ #[must_use]
pub fn new(var_layout: VariableLayout<'a>) -> Self
{
let binding_location = BindingLocation {
@@ -38,10 +39,11 @@ impl<'a> Cursor<'a>
Self {
type_layout: var_layout.type_layout().unwrap(),
binding_location,
- location_path: LocationPath::default(),
+ location_path: LocationPath::new(),
}
}
+ #[must_use]
pub fn field(&self, name: impl Into<Cow<'static, str>>) -> Self
{
let name = name.into();
@@ -100,6 +102,7 @@ impl<'a> Cursor<'a>
}
}
+ #[must_use]
pub fn element(mut self, index: usize) -> Self
{
let element_type_layout = self.type_layout.element_type_layout().unwrap();
@@ -125,15 +128,23 @@ impl<'a> Cursor<'a>
}
/// Shader cursor location.
-#[derive(Debug, Clone, Default)]
+#[derive(Debug, Clone)]
pub struct LocationPath
{
- locations: FixedCircularBuffer<Location, 16>,
+ locations: HeapCircularBuffer<Location>,
is_truncated: bool,
}
impl LocationPath
{
+ fn new() -> Self
+ {
+ Self {
+ locations: HeapCircularBuffer::with_capacity(16),
+ is_truncated: false,
+ }
+ }
+
fn push(&mut self, location: Location)
{
if self.locations.push_back(location).is_some() {
@@ -231,12 +242,7 @@ impl BindingValue
Self::Float(_) => {
ty_kind == TypeKind::Scalar && scalar_ty == Some(ScalarType::Float32)
}
- Self::FVec3(_) => {
- ty_kind == TypeKind::Vector
- && element_scalar_ty == Some(ScalarType::Float32)
- && element_cnt == Some(3)
- }
- Self::Color(Color::Rgb(_)) => {
+ Self::FVec3(_) | Self::Color(Color::Rgb(_)) => {
ty_kind == TypeKind::Vector
&& element_scalar_ty == Some(ScalarType::Float32)
&& element_cnt == Some(3)
diff --git a/engine/src/texture.rs b/engine/src/texture.rs
index 8361f12..844d9eb 100644
--- a/engine/src/texture.rs
+++ b/engine/src/texture.rs
@@ -22,7 +22,7 @@ pub struct Tex2D
#[derive(Debug, Clone)]
pub struct TexCubeMap
{
- pub images: [(CubeMapFace, Image); 6],
+ pub images: Box<[(CubeMapFace, Image); 6]>,
pub properties: Properties,
}
@@ -53,6 +53,7 @@ pub struct Properties
impl Properties
{
+ #[must_use]
pub fn builder() -> PropertiesBuilder
{
PropertiesBuilder::default()
@@ -118,6 +119,7 @@ pub struct ImportSettings {
impl ImportSettings
{
+ #[must_use]
pub fn builder() -> ImportSettingsBuilder
{
ImportSettingsBuilder::default()
@@ -145,9 +147,7 @@ fn import(
{
asset_submitter.submit_store(Texture::Texture2D(Tex2D {
image: Image::open(path)?,
- properties: settings
- .map(|settings| settings.properties.clone())
- .unwrap_or_default(),
+ properties: settings.map_or_default(|settings| settings.properties.clone()),
}));
Ok(())
diff --git a/engine/src/transform.rs b/engine/src/transform.rs
index 8e768a6..67fbe23 100644
--- a/engine/src/transform.rs
+++ b/engine/src/transform.rs
@@ -14,18 +14,21 @@ pub struct Transform
impl Transform
{
+ #[must_use]
pub fn position(mut self, position: Vec3<f32>) -> Self
{
self.position = position;
self
}
+ #[must_use]
pub fn scale(mut self, scale: Dimens3<f32>) -> Self
{
self.scale = scale;
self
}
+ #[must_use]
pub fn to_matrix(&self) -> Matrix<f32, 4, 4>
{
let mut matrix = Matrix::new_identity();
diff --git a/engine/src/ui/dear_imgui.rs b/engine/src/ui/dear_imgui.rs
index 0a50ff7..c5f7ce2 100644
--- a/engine/src/ui/dear_imgui.rs
+++ b/engine/src/ui/dear_imgui.rs
@@ -130,12 +130,14 @@ pub struct Extension
impl Extension
{
+ #[must_use]
pub fn with_start_enabled(mut self, start_enabled: bool) -> Self
{
self.start_enabled = start_enabled;
self
}
+ #[must_use]
pub fn with_settings_ini_file(
mut self,
settings_ini_file_path: Option<PathBuf>,
@@ -164,10 +166,12 @@ impl ecs::extension::Extension for Extension
tracing::error!("Failed to set path of imgui settings ini file: {err}");
}
- assert!(
- dear_imgui_rs::HAS_FREETYPE,
- "Freetype font rasterizer support is not enabled"
- );
+ const {
+ assert!(
+ dear_imgui_rs::HAS_FREETYPE,
+ "Freetype font rasterizer support is not enabled"
+ );
+ }
unsafe {
context.ctx.font_atlas().add_font_from_memory_ttf(
@@ -223,8 +227,8 @@ fn handle_window_changed(
.set_display_framebuffer_scale([hidpi_factor as f32, hidpi_factor as f32]);
let window_size_logical = PhysicalSize {
- width: window.inner_size.width as f64,
- height: window.inner_size.height as f64,
+ width: f64::from(window.inner_size.width),
+ height: f64::from(window.inner_size.height),
}
.to_logical::<f64>(hidpi_factor);
@@ -272,7 +276,7 @@ fn update(
window_surface.id,
assets,
render_passes,
- &shader_context,
+ shader_context,
) else {
*state = State::NotInitialized;
return Ok(());
@@ -341,11 +345,9 @@ fn initialize_context(
shader_context: &ShaderContext,
) -> Option<(AssetHandle<ShaderModuleSource>, RenderingObjectId, Mesh)>
{
- let shader_asset = if let Some(shader_asset) =
+ let Some(shader_asset) =
assets.get_handle_to_loaded::<ShaderModuleSource>(SHADER_ASSET_LABEL.clone())
- {
- shader_asset
- } else {
+ else {
assets.store_with_label(
SHADER_ASSET_LABEL.clone(),
ShaderModuleSource {
@@ -362,19 +364,21 @@ fn initialize_context(
return None;
};
- let hidpi_factor = window.scale_factor().round();
+ #[allow(clippy::cast_possible_truncation)]
+ let hidpi_factor = window.scale_factor().round() as f32;
context
.ctx
.get_io_mut()
- .set_display_framebuffer_scale([hidpi_factor as f32, hidpi_factor as f32]);
+ .set_display_framebuffer_scale([hidpi_factor, hidpi_factor]);
let window_size = Dimens {
width: window.inner_size.width as f32,
height: window.inner_size.height as f32,
};
- let window_logical_size = window_size / (hidpi_factor as f32);
+ #[allow(clippy::cast_possible_truncation)]
+ let window_logical_size = window_size / hidpi_factor;
context
.ctx
@@ -455,6 +459,7 @@ fn update_inputs(
let mouse_pos = mouse.position.to_logical::<f64>(window.scale_factor());
+ #[allow(clippy::cast_possible_truncation)]
io.add_mouse_pos_event([mouse_pos.x as f32, mouse_pos.y as f32]);
if !mouse.curr_tick_scroll_delta.is_zero() {
@@ -610,8 +615,8 @@ fn add_drawing_render_pass(
height: rect.rect.h.into(),
},
offset: Vec2 {
- x: rect.rect.x as u32,
- y: rect.rect.y as u32,
+ x: u32::from(rect.rect.x),
+ y: u32::from(rect.rect.y),
},
},
});
@@ -715,7 +720,7 @@ fn add_drawing_render_pass(
},
MeshNamedVertexAttr {
label: VertexLabel::Color,
- value: vertex.rgba().map(|elem| (elem as f32) / 255.0),
+ value: vertex.rgba().map(|elem| f32::from(elem) / 255.0),
},
MeshNamedVertexAttr {
label: VertexLabel::UvFromTopLeft,
@@ -733,51 +738,47 @@ fn add_drawing_render_pass(
});
for command in draw_list.commands() {
- match command {
- ImguiDrawCmd::Elements { count, cmd_params } => {
- let Some(scissor_box) =
- calc_draw_cmd_scissor_box(draw_data, &cmd_params)
- else {
- continue;
- };
+ if let ImguiDrawCmd::Elements { count, cmd_params } = command {
+ let Some(scissor_box) = calc_draw_cmd_scissor_box(draw_data, &cmd_params)
+ else {
+ continue;
+ };
- let tex_id = cmd_params.texture_id;
+ let tex_id = cmd_params.texture_id;
- let Some(texture_object_id) =
- texture_lookup.get(TextureLookupId::from(tex_id))
- else {
- tracing::error!(
- "Unknown texture {}. Skipping skipping draw command",
- tex_id.id()
- );
- continue;
- };
+ let Some(texture_object_id) =
+ texture_lookup.get(TextureLookupId::from(tex_id))
+ else {
+ tracing::error!(
+ "Unknown texture {}. Skipping skipping draw command",
+ tex_id.id()
+ );
+ continue;
+ };
- render_pass.commands.extend([
- RenderingCommand::UpdateDrawProperties(
- DrawProperties { scissor_box, ..Default::default() },
- DrawPropertiesUpdateFlags::SCISSOR_BOX,
- ),
- RenderingCommand::SetShaderBinding(
- shader_object_id,
- shader_cursor.field("main_texture").binding(
- ShaderBindingValue::Texture(
- *texture_object_id,
- ShaderBindingTextureKind::Texture2D,
- ),
- )?,
- ),
- RenderingCommand::DrawMesh(
- mesh_obj_id,
- DrawMeshOptions::builder()
- .element_offset(cmd_params.idx_offset.try_into().unwrap())
- .vertex_offset(cmd_params.vtx_offset.try_into().unwrap())
- .element_cnt(count.try_into().unwrap())
- .build(),
- ),
- ]);
- }
- _ => {}
+ render_pass.commands.extend([
+ RenderingCommand::UpdateDrawProperties(
+ DrawProperties { scissor_box, ..Default::default() },
+ DrawPropertiesUpdateFlags::SCISSOR_BOX,
+ ),
+ RenderingCommand::SetShaderBinding(
+ shader_object_id,
+ shader_cursor.field("main_texture").binding(
+ ShaderBindingValue::Texture(
+ *texture_object_id,
+ ShaderBindingTextureKind::Texture2D,
+ ),
+ )?,
+ ),
+ RenderingCommand::DrawMesh(
+ mesh_obj_id,
+ DrawMeshOptions::builder()
+ .element_offset(cmd_params.idx_offset.try_into().unwrap())
+ .vertex_offset(cmd_params.vtx_offset.try_into().unwrap())
+ .element_cnt(count.try_into().unwrap())
+ .build(),
+ ),
+ ]);
}
}
}
@@ -973,12 +974,12 @@ mod inner_context_wrapper
ctx.io_mut()
.set_backend_flags(dear_imgui_rs::BackendFlags::RENDERER_HAS_TEXTURES);
- let _renderer_consumer = ctx.create_renderer_consumer().unwrap();
+ let renderer_consumer = ctx.create_renderer_consumer().unwrap();
Self {
ctx,
frame: null_mut(),
- _renderer_consumer,
+ _renderer_consumer: renderer_consumer,
}
}
diff --git a/engine/src/ui/view/transform_3d.rs b/engine/src/ui/view/transform_3d.rs
index a426b2a..9c3dbf1 100644
--- a/engine/src/ui/view/transform_3d.rs
+++ b/engine/src/ui/view/transform_3d.rs
@@ -124,5 +124,5 @@ fn flatten_matrix(mat: [[f32; 4]; 4]) -> [f32; 4 * 4]
unreachable!();
};
- flattened.clone()
+ *flattened
}
diff --git a/engine/src/ui/view/world.rs b/engine/src/ui/view/world.rs
index 6bb9755..95f29d0 100644
--- a/engine/src/ui/view/world.rs
+++ b/engine/src/ui/view/world.rs
@@ -39,8 +39,8 @@ const BUTTON_RED_ACTIVE: [f32; 4] = [162.0, 68.0, 51.0, 255.0];
pub struct State
{
spawning_entity: Option<Uid>,
- popup_state: Option<PopupState>,
- textures: Option<Textures>,
+ popup: Option<PopupState>,
+ icon_textures: Option<IconTextures>,
}
pub fn show(
@@ -55,11 +55,12 @@ pub fn show(
let State {
spawning_entity,
- popup_state,
- textures,
+ popup: popup_state,
+ icon_textures,
} = &mut *state;
- let textures = textures.get_or_insert_with(|| Textures::new(dear_imgui_context));
+ let icon_textures =
+ icon_textures.get_or_insert_with(|| IconTextures::new(dear_imgui_context));
let Some(frame) = dear_imgui_context.frame() else {
return Ok(());
@@ -84,7 +85,7 @@ pub fn show(
create_entity_widgets(
frame,
popup_state,
- textures,
+ icon_textures,
&ent_handle,
world,
&mut actions,
@@ -164,7 +165,7 @@ fn create_spawn_button_widgets(
fn create_entity_widgets(
frame: &dear_imgui_bindings::Ui,
popup_state: &mut Option<PopupState>,
- textures: &Textures,
+ icon_textures: &IconTextures,
ent_handle: &EntityHandle,
world: &World,
actions: &mut Actions,
@@ -182,12 +183,12 @@ fn create_entity_widgets(
return;
}
- let ent_title = create_entity_title(&ent_handle);
+ let ent_title = create_entity_title(ent_handle);
let mut is_open = false;
frame
- .table(&format!("ent_{}_table", ent_handle.uid()))
+ .table(format!("ent_{}_table", ent_handle.uid()))
.headers(false)
.sizing_policy(dear_imgui_bindings::TableSizingPolicy::FixedFit)
.columns([
@@ -209,7 +210,7 @@ fn create_entity_widgets(
create_add_component_button_widget(
frame,
- &ent_handle,
+ ent_handle,
&ent_title,
popup_state,
world,
@@ -217,13 +218,13 @@ fn create_entity_widgets(
frame.table_next_column();
- create_despawn_button_widget(frame, textures, ent_handle, actions);
+ create_despawn_button_widget(frame, icon_textures, ent_handle, actions);
frame.table_next_column();
create_rename_entity_button_widget(
frame,
- textures,
+ icon_textures,
ent_handle,
&ent_title,
popup_state,
@@ -235,7 +236,7 @@ fn create_entity_widgets(
if component_id.is_pair() {
create_pair_component_widgets(
frame,
- textures,
+ icon_textures,
ent_handle,
component_id,
world,
@@ -320,15 +321,15 @@ fn create_component_widgets(
ItemRef::Mutable(&mut *component),
&mut component_changed,
ItemInfo {
- item_title: component_info.name,
- item_tag: &format!(
+ title: component_info.name,
+ tag: &format!(
"world_view_entity_{}_component_{}",
ent_handle.uid(),
component_info.name,
),
- item_type_name: None,
- item_type,
- item_is_read_only: false,
+ type_name: None,
+ ty: item_type,
+ is_read_only: false,
},
&[],
);
@@ -342,7 +343,7 @@ fn create_component_widgets(
fn create_pair_component_widgets(
frame: &dear_imgui_bindings::Ui,
- textures: &Textures,
+ icon_textures: &IconTextures,
ent_handle: &EntityHandle,
pair_id: Uid,
world: &World,
@@ -418,7 +419,7 @@ fn create_pair_component_widgets(
let Some(pair_data_ty) = pair_data_comp_info.type_reflection else {
frame.same_line();
- frame.image(textures.warning_icon_tex_id, [16.0, 16.0]);
+ frame.image(icon_textures.warning, [16.0, 16.0]);
if frame.is_item_hovered() {
frame.tooltip_text(format!(
@@ -450,14 +451,14 @@ fn create_pair_component_widgets(
ItemRef::Mutable(&mut *pair_data),
&mut component_changed,
ItemInfo {
- item_title: pair_data_comp_info.name,
- item_tag: &format!(
+ title: pair_data_comp_info.name,
+ tag: &format!(
"world_view_entity_{}_pair_component_{pair_id}",
ent_handle.uid(),
),
- item_type_name: None,
- item_type,
- item_is_read_only: false,
+ type_name: None,
+ ty: item_type,
+ is_read_only: false,
},
&[],
);
@@ -519,7 +520,7 @@ fn create_add_component_button_widget(
fn create_despawn_button_widget(
frame: &dear_imgui_bindings::Ui,
- textures: &Textures,
+ icon_textures: &IconTextures,
ent_handle: &EntityHandle,
actions: &mut Actions,
)
@@ -541,8 +542,8 @@ fn create_despawn_button_widget(
if frame
.image_button_config(
- &format!("ent_{}_despawn_button", ent_handle.uid()),
- textures.despawn_icon_tex_id,
+ format!("ent_{}_despawn_button", ent_handle.uid()),
+ icon_textures.despawn,
[14.0, 14.0],
)
.build()
@@ -553,7 +554,7 @@ fn create_despawn_button_widget(
fn create_rename_entity_button_widget(
frame: &dear_imgui_bindings::Ui,
- textures: &Textures,
+ icon_textures: &IconTextures,
ent_handle: &EntityHandle,
ent_title: &str,
popup_state: &mut Option<PopupState>,
@@ -561,8 +562,8 @@ fn create_rename_entity_button_widget(
{
if frame
.image_button_config(
- &format!("ent_{}_rename_button", ent_handle.uid()),
- textures.edit_icon_tex_id,
+ format!("ent_{}_rename_button", ent_handle.uid()),
+ icon_textures.edit,
[16.0, 16.0],
)
.build()
@@ -716,7 +717,7 @@ fn enter_add_component_popup_state(
search_text: String::with_capacity(20),
searched_components: searchable_components.clone(),
searchable_components,
- selected_search_result: -1,
+ selected_search_result: None,
new_component: None,
}));
@@ -755,15 +756,15 @@ fn show_add_component_popup(
add_component_popup_state.searched_components = add_component_popup_state
.searchable_components
.iter()
- .cloned()
- .filter(|(_, searchable_comp_info, _)| {
+ .filter(|&(_, searchable_comp_info, _)| {
searchable_comp_info
.name
.contains(&add_component_popup_state.search_text)
})
+ .cloned()
.collect();
- add_component_popup_state.selected_search_result = -1;
+ add_component_popup_state.selected_search_result = None;
}
frame.spacing();
@@ -771,7 +772,7 @@ fn show_add_component_popup(
let _item_width_token = frame.push_item_width(-1.0);
- if frame
+ if let Some(selected_search_result_index) = frame
.list_box_config("##add_component_popup_search_results")
.build_extended(
frame,
@@ -793,8 +794,7 @@ fn show_add_component_popup(
)
{
let (selected_comp_id, selected_comp_info, _) = add_component_popup_state
- .searched_components
- [add_component_popup_state.selected_search_result as usize]
+ .searched_components[selected_search_result_index]
.clone();
let Some(selected_component_type) = selected_comp_info.type_reflection
@@ -844,14 +844,14 @@ fn show_add_component_popup(
ItemRef::Mutable(&mut **new_component),
&mut component_changed,
ItemInfo {
- item_title: new_component_info.name,
- item_tag: &format!(
+ title: new_component_info.name,
+ tag: &format!(
"add_component_popup_component_{}",
new_component_info.name,
),
- item_type_name: None,
- item_type,
- item_is_read_only: false,
+ type_name: None,
+ ty: item_type,
+ is_read_only: false,
},
&[],
);
@@ -914,11 +914,11 @@ pub enum ComponentUserCreatable
struct ItemInfo<'a>
{
- item_title: &'a str,
- item_tag: &'a str,
- item_type_name: Option<&'static str>,
- item_type: ItemType,
- item_is_read_only: bool,
+ title: &'a str,
+ tag: &'a str,
+ type_name: Option<&'static str>,
+ ty: ItemType,
+ is_read_only: bool,
}
enum ItemType
@@ -943,10 +943,10 @@ impl ItemType
Self::Reflected(TypeReflection::Reference(ref_ty)) => {
ItemType::Reflected(ref_ty.ty).spans_multiple_rows()
}
- Self::Color(..) => false,
- Self::Reflected(TypeReflection::Literal(_)) | Self::String | Self::CowStr => {
- false
- }
+ Self::Reflected(TypeReflection::Literal(_))
+ | Self::String
+ | Self::CowStr
+ | Self::Color(..) => false,
Self::Reflected(_) => unimplemented!(),
}
}
@@ -993,7 +993,7 @@ fn get_item_type(ty: Option<&'static TypeReflection>, type_id: TypeId)
}
if let Some(ty) = ty {
- return Some(ItemType::Reflected(ty));
+ Some(ItemType::Reflected(ty))
} else if type_id == TypeId::of::<String>() {
Some(ItemType::String)
} else if type_id == TypeId::of::<Cow<'static, str>>() {
@@ -1086,7 +1086,7 @@ impl<Value> Deref for OwnedOrRefMut<'_, Value>
fn deref(&self) -> &Self::Target
{
match self {
- Self::Ref(value) => *value,
+ Self::Ref(value) => value,
Self::Owned(value) => value,
}
}
@@ -1097,7 +1097,7 @@ impl<Value> DerefMut for OwnedOrRefMut<'_, Value>
fn deref_mut(&mut self) -> &mut Self::Target
{
match self {
- Self::Ref(value) => *value,
+ Self::Ref(value) => value,
Self::Owned(value) => value,
}
}
@@ -1111,7 +1111,7 @@ fn create_item_title_widget(
)
{
if !matches!(item_type, ItemType::Reflected(TypeReflection::Reference(_))) {
- frame.text(&item_title);
+ frame.text(item_title);
if let Some(item_type_name) = item_type_name {
if frame.is_item_hovered() {
@@ -1126,11 +1126,11 @@ fn add_item_to_frame<'a>(
mut item: ItemRef<'_>,
data_changed: &mut bool,
ItemInfo {
- item_title,
- item_tag,
- item_type_name,
- item_type,
- item_is_read_only,
+ title: item_title,
+ tag: item_tag,
+ type_name: item_type_name,
+ ty: item_type,
+ is_read_only: item_is_read_only,
}: ItemInfo<'a>,
prev_item_tags: &[&'a str],
)
@@ -1176,85 +1176,85 @@ fn add_item_to_frame<'a>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::I8 => create_scalar_item_input::<i8>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::U16 => create_scalar_item_input::<u16>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::I16 => create_scalar_item_input::<i16>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::U32 => create_scalar_item_input::<u32>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::I32 => create_scalar_item_input::<i32>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::U64 => create_scalar_item_input::<u64>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::I64 => create_scalar_item_input::<i64>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::F32 => create_scalar_item_input::<f32>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::F64 => create_scalar_item_input::<f64>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::Usize => create_scalar_item_input::<usize>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::Isize => create_scalar_item_input::<isize>(
frame,
&mut item,
data_changed,
- &item_tag,
- &prev_item_tags,
+ item_tag,
+ prev_item_tags,
),
LiteralType::U128 => {
let item = match item {
@@ -1315,7 +1315,7 @@ fn add_item_to_frame<'a>(
};
if frame.checkbox(
- create_item_label(&item_tag, "value_input", &prev_item_tags),
+ create_item_label(item_tag, "value_input", prev_item_tags),
item,
) {
*data_changed = true;
@@ -1383,11 +1383,11 @@ fn add_item_to_frame<'a>(
item_item,
data_changed,
ItemInfo {
- item_title: array_item_name.as_ref(),
- item_tag: array_item_name.as_ref(),
- item_type_name: Some(array_type.item_type_name()),
- item_type: array_item_type,
- item_is_read_only,
+ title: array_item_name.as_ref(),
+ tag: array_item_name.as_ref(),
+ type_name: Some(array_type.item_type_name()),
+ ty: array_item_type,
+ is_read_only: item_is_read_only,
},
&prev_item_tags,
);
@@ -1428,11 +1428,11 @@ fn add_item_to_frame<'a>(
ItemRef::Immutable(item_item),
&mut slice_item_changed,
ItemInfo {
- item_title: &item_name,
- item_tag: &item_name,
- item_type_name: Some(slice_type.item_type_name()),
- item_type: slice_item_type,
- item_is_read_only: true,
+ title: &item_name,
+ tag: &item_name,
+ type_name: Some(slice_type.item_type_name()),
+ ty: slice_item_type,
+ is_read_only: true,
},
&prev_item_tags,
);
@@ -1463,11 +1463,11 @@ fn add_item_to_frame<'a>(
ItemRef::Immutable(derefed_item),
&mut derefed_changed,
ItemInfo {
- item_title,
- item_tag: "derefed".into(),
- item_type_name,
- item_type: ref_item_type,
- item_is_read_only: true,
+ title: item_title,
+ tag: "derefed",
+ type_name: item_type_name,
+ ty: ref_item_type,
+ is_read_only: true,
},
prev_item_tags,
);
@@ -1494,7 +1494,7 @@ fn add_item_to_frame<'a>(
if frame
.input_text(
- create_item_label(&item_tag, "value_input", &prev_item_tags),
+ create_item_label(item_tag, "value_input", prev_item_tags),
item,
)
.build()
@@ -1522,7 +1522,7 @@ fn add_item_to_frame<'a>(
if frame
.input_text(
- create_item_label(&item_tag, "value_input", &prev_item_tags),
+ create_item_label(item_tag, "value_input", prev_item_tags),
item.to_mut(),
)
.build()
@@ -1537,7 +1537,7 @@ fn add_item_to_frame<'a>(
if frame
.color_edit3_config(
- create_item_label(&item_tag, "value_input", &prev_item_tags),
+ create_item_label(item_tag, "value_input", prev_item_tags),
&mut scratch,
)
.display_mode(dear_imgui_bindings::ColorDisplayMode::Hex)
@@ -1554,14 +1554,14 @@ fn add_item_to_frame<'a>(
let mut item = item.into_writable::<Rgb<u8>>();
let mut scratch = [
- item.r as f32 / 255.0,
- item.g as f32 / 255.0,
- item.b as f32 / 255.0,
+ f32::from(item.r) / 255.0,
+ f32::from(item.g) / 255.0,
+ f32::from(item.b) / 255.0,
];
if frame
.color_edit3_config(
- create_item_label(&item_tag, "value_input", &prev_item_tags),
+ create_item_label(item_tag, "value_input", prev_item_tags),
&mut scratch,
)
.display_mode(dear_imgui_bindings::ColorDisplayMode::Hex)
@@ -1570,9 +1570,9 @@ fn add_item_to_frame<'a>(
let [new_r, new_g, new_b] = scratch;
*item = Rgb {
- r: (new_r * 255.0) as u8,
- g: (new_g * 255.0) as u8,
- b: (new_b * 255.0) as u8,
+ r: float_to_u8_checked(new_r * 255.0).unwrap_or(0),
+ g: float_to_u8_checked(new_g * 255.0).unwrap_or(0),
+ b: float_to_u8_checked(new_b * 255.0).unwrap_or(0),
};
*data_changed = true;
@@ -1585,7 +1585,7 @@ fn add_item_to_frame<'a>(
if frame
.color_edit4_config(
- create_item_label(&item_tag, "value_input", &prev_item_tags),
+ create_item_label(item_tag, "value_input", prev_item_tags),
&mut scratch,
)
.display_mode(dear_imgui_bindings::ColorDisplayMode::Hex)
@@ -1607,15 +1607,15 @@ fn add_item_to_frame<'a>(
let mut item = item.into_writable::<Rgba<u8>>();
let mut scratch = [
- item.r as f32 / 255.0,
- item.g as f32 / 255.0,
- item.b as f32 / 255.0,
- item.a as f32 / 255.0,
+ f32::from(item.r) / 255.0,
+ f32::from(item.g) / 255.0,
+ f32::from(item.b) / 255.0,
+ f32::from(item.a) / 255.0,
];
if frame
.color_edit4_config(
- create_item_label(&item_tag, "value_input", &prev_item_tags),
+ create_item_label(item_tag, "value_input", prev_item_tags),
&mut scratch,
)
.display_mode(dear_imgui_bindings::ColorDisplayMode::Hex)
@@ -1624,17 +1624,16 @@ fn add_item_to_frame<'a>(
let [new_r, new_g, new_b, new_a] = scratch;
*item = Rgba {
- r: (new_r * 255.0) as u8,
- g: (new_g * 255.0) as u8,
- b: (new_b * 255.0) as u8,
- a: (new_a * 255.0) as u8,
+ r: float_to_u8_checked(new_r * 255.0).unwrap_or(0),
+ g: float_to_u8_checked(new_g * 255.0).unwrap_or(0),
+ b: float_to_u8_checked(new_b * 255.0).unwrap_or(0),
+ a: float_to_u8_checked(new_a * 255.0).unwrap_or(0),
};
*data_changed = true;
}
}
- ItemType::Color(ColorItemType::Rgb, _) => unreachable!(),
- ItemType::Color(ColorItemType::Rgba, _) => unreachable!(),
+ ItemType::Color(ColorItemType::Rgb | ColorItemType::Rgba, _) => unreachable!(),
ItemType::Reflected(_) => unimplemented!(),
}
}
@@ -1667,7 +1666,7 @@ fn create_scalar_item_input<Scalar>(
if frame
.input_scalar(
- create_item_label(item_tag, "value_input", &prev_item_tags),
+ create_item_label(item_tag, "value_input", prev_item_tags),
item,
)
.build()
@@ -1682,7 +1681,7 @@ fn item_layout_table<'frame>(
) -> dear_imgui_bindings::TableBuilder<'frame>
{
frame
- .table(create_item_label("item_layout", "table", &prev_item_tags))
+ .table(create_item_label("item_layout", "table", prev_item_tags))
.headers(false)
.sizing_policy(dear_imgui_bindings::TableSizingPolicy::StretchSame)
.columns([
@@ -1727,8 +1726,7 @@ fn create_struct_widgets(
let field_name = field
.name
- .map(Cow::Borrowed)
- .unwrap_or_else(|| field_index.to_string().into());
+ .map_or_else(|| field_index.to_string().into(), Cow::Borrowed);
let Ok(field_item) = item.get_struct_field(struct_ty, field_index) else {
unreachable!();
@@ -1748,11 +1746,11 @@ fn create_struct_widgets(
field_item,
data_changed,
ItemInfo {
- item_title: field_name.as_ref(),
- item_tag: field_name.as_ref(),
- item_type_name: Some(field.type_name()),
- item_type: field_item_type,
- item_is_read_only: item_is_read_only
+ title: field_name.as_ref(),
+ tag: field_name.as_ref(),
+ type_name: Some(field.type_name()),
+ ty: field_item_type,
+ is_read_only: item_is_read_only
|| matches!(
field.visibility,
Visibility::Private | Visibility::PubScoped(_)
@@ -1768,8 +1766,7 @@ fn create_struct_widgets(
{
let field_name = field
.name
- .map(Cow::Borrowed)
- .unwrap_or_else(|| field_index.to_string().into());
+ .map_or_else(|| field_index.to_string().into(), Cow::Borrowed);
let Ok(field_item) = item.get_struct_field(struct_ty, field_index) else {
unreachable!();
@@ -1789,11 +1786,11 @@ fn create_struct_widgets(
field_item,
data_changed,
ItemInfo {
- item_title: field_name.as_ref(),
- item_tag: field_name.as_ref(),
- item_type_name: Some(field.type_name()),
- item_type: field_item_type,
- item_is_read_only: item_is_read_only
+ title: field_name.as_ref(),
+ tag: field_name.as_ref(),
+ type_name: Some(field.type_name()),
+ ty: field_item_type,
+ is_read_only: item_is_read_only
|| matches!(
field.visibility,
Visibility::Private | Visibility::PubScoped(_)
@@ -1821,7 +1818,7 @@ fn create_enum_widgets(
if create_combo_box(
frame,
- create_item_label(&item_tag, "variant_select", &prev_item_tags),
+ create_item_label(item_tag, "variant_select", prev_item_tags),
&mut curr_variant_index,
enum_type.variants,
|variant| {
@@ -1849,8 +1846,7 @@ fn create_enum_widgets(
disabled: disabled.is_some(),
hover_tooltip: disabled.map(|(bad_field_name, bad_field_reason)| {
format!(
- "Variant cannot be selected since field {} {}",
- bad_field_name, bad_field_reason
+ "Variant cannot be selected since field {bad_field_name} {bad_field_reason}"
)
.into()
}),
@@ -1869,8 +1865,7 @@ fn create_enum_widgets(
&mut new_variant
.fields
.iter()
- .map(|fields| fields.fields())
- .flatten()
+ .flat_map(engine_reflection::EnumVariantFields::fields)
.map(|field| {
let Some(field_type) = field.type_reflection() else {
// Variants with any field that is missing type reflection is
@@ -1946,11 +1941,11 @@ fn create_enum_widgets(
field_item,
data_changed,
ItemInfo {
- item_title: field_name.as_ref(),
- item_tag: field_name.as_ref(),
- item_type_name: Some(field.type_name()),
- item_type: field_item_type,
- item_is_read_only: item_is_read_only,
+ title: field_name.as_ref(),
+ tag: field_name.as_ref(),
+ type_name: Some(field.type_name()),
+ ty: field_item_type,
+ is_read_only: item_is_read_only,
},
&prev_item_tags,
);
@@ -1986,11 +1981,11 @@ fn create_enum_widgets(
field_item,
data_changed,
ItemInfo {
- item_title: field_name.as_ref(),
- item_tag: field_name.as_ref(),
- item_type_name: Some(field.type_name()),
- item_type: field_item_type,
- item_is_read_only: item_is_read_only,
+ title: field_name.as_ref(),
+ tag: field_name.as_ref(),
+ type_name: Some(field.type_name()),
+ ty: field_item_type,
+ is_read_only: item_is_read_only,
},
&prev_item_tags,
);
@@ -2003,7 +1998,7 @@ fn create_item_label(item_tag: &str, value_name: &str, prev_item_tags: &[&str])
let mut item_label = String::with_capacity(
2 + item_tag.len()
+ prev_item_tags.len()
- + prev_item_tags.iter().max().unwrap_or(&"".into()).len(),
+ + prev_item_tags.iter().max().unwrap_or(&"").len(),
);
item_label.push_str("##");
@@ -2052,7 +2047,11 @@ fn get_whole_type_is_user_editable(
}
ItemType::Reflected(TypeReflection::Enum(enum_ty)) => {
enum_ty.variants.iter().any(|variant| {
- for field in variant.fields.iter().flat_map(|fields| fields.fields()) {
+ for field in variant
+ .fields
+ .iter()
+ .flat_map(engine_reflection::EnumVariantFields::fields)
+ {
if !get_whole_type_is_user_editable(
field.type_reflection(),
field.type_id,
@@ -2103,8 +2102,7 @@ where
label,
preview_label
.as_ref()
- .map(|preview_label| preview_label.as_ref())
- .unwrap_or(""),
+ .map_or("", std::convert::AsRef::as_ref),
) {
for (idx, item) in items.iter().enumerate() {
let is_selected = idx == *current_item;
@@ -2157,10 +2155,10 @@ trait ListBoxExt
fn build_extended<Item, ItemFn>(
self,
ui: &dear_imgui_bindings::Ui,
- current_item: &mut i32,
+ current_item: &mut Option<usize>,
items: &[Item],
item_fn: &ItemFn,
- ) -> bool
+ ) -> Option<usize>
where
for<'b> ItemFn: Fn(&'b Item) -> ListBoxItem<'b>;
}
@@ -2172,32 +2170,24 @@ where
fn build_extended<Item, ItemFn>(
self,
ui: &dear_imgui_bindings::Ui,
- current_item: &mut i32,
+ current_item: &mut Option<usize>,
items: &[Item],
item_fn: &ItemFn,
- ) -> bool
+ ) -> Option<usize>
where
for<'b> ItemFn: Fn(&'b Item) -> ListBoxItem<'b>,
{
- let mut result = false;
-
- let lb = self;
-
- if let Some(_cb) = lb.begin(ui) {
- for (idx, item) in items.iter().enumerate() {
- if idx > i32::MAX as usize {
- break;
- }
-
- let idx_i32 = idx as i32;
+ let mut result = None;
+ if let Some(_lb_token) = self.begin(ui) {
+ for (index, item) in items.iter().enumerate() {
let ListBoxItem {
label: item_label,
disabled: item_disabled,
hover_tooltip: item_hover_tooltip,
} = item_fn(item);
- let is_selected = idx_i32 == *current_item;
+ let is_selected = Some(index) == *current_item;
let disabled_token = ui.begin_disabled_with_cond(item_disabled);
@@ -2206,8 +2196,8 @@ where
.selected(is_selected)
.build()
{
- *current_item = idx_i32;
- result = true;
+ *current_item = Some(index);
+ result = Some(index);
}
disabled_token.end();
@@ -2234,24 +2224,23 @@ fn create_entity_title(ent_handle: &EntityHandle) -> String
"{} {}",
ent_name
.as_ref()
- .map(|ent_name| ent_name.name.as_ref())
- .unwrap_or("<unnamed>"),
+ .map_or("<unnamed>", |ent_name| ent_name.name.as_ref()),
ent_handle.uid()
)
}
-struct Textures
+struct IconTextures
{
- despawn_icon_tex_id: dear_imgui_bindings::ManagedTextureId,
- warning_icon_tex_id: dear_imgui_bindings::ManagedTextureId,
- edit_icon_tex_id: dear_imgui_bindings::ManagedTextureId,
+ despawn: dear_imgui_bindings::ManagedTextureId,
+ warning: dear_imgui_bindings::ManagedTextureId,
+ edit: dear_imgui_bindings::ManagedTextureId,
}
-impl Textures
+impl IconTextures
{
fn new(dear_imgui_context: &mut DearImguiContext) -> Self
{
- let despawn_icon_tex_id = create_texture(
+ let despawn = create_texture(
dear_imgui_context,
Image::from_reader(
Cursor::new(include_bytes!("../../../res/ui/delete.png")),
@@ -2260,7 +2249,7 @@ impl Textures
.unwrap(),
);
- let warning_icon_tex_id = create_texture(
+ let warning = create_texture(
dear_imgui_context,
Image::from_reader(
Cursor::new(include_bytes!("../../../res/ui/warning.png")),
@@ -2269,7 +2258,7 @@ impl Textures
.unwrap(),
);
- let edit_icon_tex_id = create_texture(
+ let edit = create_texture(
dear_imgui_context,
Image::from_reader(
Cursor::new(include_bytes!("../../../res/ui/edit.png")),
@@ -2278,11 +2267,7 @@ impl Textures
.unwrap(),
);
- Self {
- despawn_icon_tex_id,
- warning_icon_tex_id,
- edit_icon_tex_id,
- }
+ Self { despawn, warning, edit }
}
}
@@ -2294,7 +2279,7 @@ struct AddComponentPopupState
search_text: String,
searched_components: Vec<(Uid, ComponentInfo, ComponentUserCreatable)>,
searchable_components: Vec<(Uid, ComponentInfo, ComponentUserCreatable)>,
- selected_search_result: i32,
+ selected_search_result: Option<usize>,
new_component: Option<(Box<dyn Any>, ComponentInfo, Uid)>,
}
@@ -2312,3 +2297,20 @@ enum PopupState
AddComponent(AddComponentPopupState),
RenameEntity(RenameEntityPopupState),
}
+
+fn float_to_u8_checked(value: f32) -> Option<u8>
+{
+ if !value.is_finite() {
+ return None;
+ }
+
+ if value > f32::from(u8::MAX) {
+ return Some(u8::MAX);
+ }
+
+ if value < f32::from(u8::MIN) {
+ return Some(u8::MIN);
+ }
+
+ Some(unsafe { value.to_int_unchecked::<u8>() })
+}
diff --git a/engine/src/util.rs b/engine/src/util.rs
index f016ad3..61a8613 100644
--- a/engine/src/util.rs
+++ b/engine/src/util.rs
@@ -6,7 +6,7 @@ pub trait OptionExt<T>
{
/// Substitute for the currently experimental function
/// [`Option::get_or_try_insert_with`].
- /// See https://github.com/rust-lang/rust/issues/143648
+ /// See <https://github.com/rust-lang/rust/issues/143648>
fn get_or_try_insert_with_fn<Err>(
&mut self,
func: impl Fn() -> Result<T, Err>,
@@ -20,7 +20,7 @@ impl<T> OptionExt<T> for Option<T>
func: impl FnOnce() -> Result<T, Err>,
) -> Result<&mut T, Err>
{
- if let None = self {
+ if self.is_none() {
*self = Some(func()?);
}
@@ -160,7 +160,7 @@ impl<const BITS_PER_ITEM: usize> Iterator for BitArrayOccupiedIter<'_, BITS_PER_
self.mask &= (!Self::ITEM_MASK) << item_bit_index_in_byte;
- let item_index_in_byte = item_bit_index_in_byte as usize / BITS_PER_ITEM;
+ let item_index_in_byte = item_bit_index_in_byte / BITS_PER_ITEM;
let prev_bytes_item_cnt = (byte_index * 8) / BITS_PER_ITEM;
@@ -220,7 +220,7 @@ impl<const BITS_PER_ITEM: usize> StreamingIterator
self.mask &= (!Self::ITEM_MASK) << item_bit_index_in_byte;
- let item_index_in_byte = item_bit_index_in_byte as usize / BITS_PER_ITEM;
+ let item_index_in_byte = item_bit_index_in_byte / BITS_PER_ITEM;
let prev_bytes_item_cnt = (byte_index * 8) / BITS_PER_ITEM;
@@ -243,7 +243,7 @@ pub struct BitArrayItemMut<'a, const BITS_PER_ITEM: usize>
bit_index_in_byte: usize,
}
-impl<'a, const BITS_PER_ITEM: usize> BitArrayItemMut<'a, BITS_PER_ITEM>
+impl<const BITS_PER_ITEM: usize> BitArrayItemMut<'_, BITS_PER_ITEM>
{
const ITEM_MASK: u8 = !(u8::MAX << BITS_PER_ITEM);
diff --git a/engine/src/windowing.rs b/engine/src/windowing.rs
index 2493851..3e27075 100644
--- a/engine/src/windowing.rs
+++ b/engine/src/windowing.rs
@@ -24,7 +24,6 @@ use winit::window::{Window as WinitWindow, WindowId as WinitWindowId};
use crate::ecs::actions::Actions;
use crate::ecs::component::Component;
-use crate::ecs::entity::obtainer::Obtainer as EntityObtainer;
use crate::ecs::event::component::{Added, Changed, EventMatchExt, Removed};
use crate::ecs::pair::{ChildOf, Pair};
use crate::ecs::phase::{Phase, PRE_UPDATE as PRE_UPDATE_PHASE};
@@ -32,11 +31,11 @@ use crate::ecs::sole::Single;
use crate::ecs::system::observer::Observe;
use crate::ecs::uid::Uid;
use crate::ecs::util::StreamingIterator;
-use crate::ecs::{declare_entity, pair, Query, Sole};
+use crate::ecs::{declare_entity, pair, Query, Sole, World};
use crate::util::BitArray;
use crate::vector::Vec2;
-use crate::windowing::dpi::{PhysicalPosition, PhysicalSize, Position};
-use crate::windowing::keyboard::{Key, KeyState, Keyboard, UnknownKeyCodeError};
+use crate::windowing::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize, Position};
+use crate::windowing::keyboard::{Key, KeyState, Keyboard};
use crate::windowing::monitor::Handle as MonitorHandle;
use crate::windowing::mouse::{
Button as MouseButton,
@@ -82,7 +81,7 @@ impl crate::ecs::extension::Extension for Extension
fn collect(self, mut collector: crate::ecs::extension::Collector<'_>)
{
if !CONTEXT_CREATED.load(Ordering::Relaxed) {
- collector.add_sole(Context::new()).ok();
+ collector.add_sole(Context::new_global()).ok();
}
collector.add_sole(Keyboard::default()).ok();
@@ -135,118 +134,55 @@ fn update_stuff(
mut mouse: Single<Mouse>,
mut mouse_buttons: Single<MouseButtons>,
mut actions: Actions,
- entity_obtainer: EntityObtainer,
+ world: &World,
) -> Result<(), EngineError>
{
let Ok(context) = context.get_mut() else {
unreachable!();
};
- let keyboard = keyboard.get_mut()?;
- let mouse = mouse.get_mut()?;
- let mouse_buttons = mouse_buttons.get_mut()?;
-
if context.display_handle.is_none() {
cold_path();
actions.stop();
return Ok(());
}
- keyboard.make_key_states_previous();
-
- {
- let Some(mut input) = context
- .shared_state
- .input
- .try_lock_for(Duration::from_millis(100))
- else {
- tracing::error!("Locking input mutex timed out after 100ms");
- return Ok(());
- };
-
- mouse.curr_tick_position_delta = input.relative_mouse_pos_delta;
- mouse.position = input.absolute_mouse_pos.clone();
- mouse.curr_tick_scroll_delta = input.mouse_scroll_delta.clone();
-
- for (mouse_button, mouse_button_input) in input.mouse_buttons.iter_mut() {
- mouse_buttons.set_previous_to_current(mouse_button);
-
- if mouse_button_input.flags.is_all() {
- match mouse_buttons.get_previous(mouse_button) {
- MouseButtonState::Pressed => {
- mouse_buttons.set(mouse_button, MouseButtonState::Released);
-
- mouse_button_input.flags.remove(MouseButtonFlags::RELEASED);
- }
- MouseButtonState::Released => {
- mouse_buttons.set(mouse_button, MouseButtonState::Pressed);
-
- mouse_button_input.flags.remove(MouseButtonFlags::PRESSED);
- }
- }
-
- continue;
- }
-
- let mouse_button_state = if mouse_button_input.flags.is_empty() {
- let Some(mouse_button_state) = mouse_button_input.lagged.pop_front()
- else {
- continue;
- };
-
- mouse_button_state
- } else {
- bitflags_match!(mouse_button_input.flags, {
- MouseButtonFlags::PRESSED => MouseButtonState::Pressed,
- MouseButtonFlags::RELEASED => MouseButtonState::Released,
- _ => unreachable!()
- })
- };
-
- mouse_buttons.set(mouse_button, mouse_button_state);
-
- mouse_button_input.flags.clear();
- }
-
- let mut key_updates = input.keys.iter_occupied_mut();
-
- while let Some(mut key_item) = key_updates.streaming_next() {
- let key = Key::KEYS[key_item.index];
-
- if key_item.bits == KEY_PRESSED_BITS | KEY_RELEASED_BITS {
- match keyboard.get_key_state(key) {
- KeyState::Pressed => {
- keyboard.set_key_state(key, KeyState::Released);
+ let keyboard = keyboard.get_mut()?;
+ let mouse = mouse.get_mut()?;
+ let mouse_buttons = mouse_buttons.get_mut()?;
- key_item.clear_and_set(KEY_PRESSED_BITS, u8::MAX);
- }
- KeyState::Released => {
- keyboard.set_key_state(key, KeyState::Pressed);
+ update_inputs(context, keyboard, mouse, mouse_buttons);
- key_item.clear_and_set(KEY_RELEASED_BITS, u8::MAX);
- }
- }
+ receive_app_messages(context, &mut actions, world);
- continue;
- }
+ if context.shared_state.thread_panicked.load(Ordering::Relaxed) {
+ cold_path();
+ return Err(error!("Windowing app thread panicked"));
+ }
- let key_state = match key_item.bits {
- KEY_PRESSED_BITS => KeyState::Pressed,
- KEY_RELEASED_BITS => KeyState::Released,
- _ => unreachable!(),
- };
+ if context.shared_state.has_thread_err.load(Ordering::Relaxed) {
+ cold_path();
- keyboard.set_key_state(key, key_state);
+ let Ok(mut err) = context.shared_state.thread_err.try_lock() else {
+ // The windowing app thread always unlocks the thread_err mutex before
+ // setting the has_thread_err atomic
+ unreachable!();
+ };
- key_item.clear_and_set(0, u8::MAX);
- }
+ let Some(err) = err.take() else {
+ // The has_thread_err atomic is set to true so this option is always
+ // Some
+ unreachable!();
+ };
- input.relative_mouse_pos_delta = Vec2 { x: 0.0, y: 0.0 };
- input.mouse_scroll_delta = MouseScrollDelta { vert_lines: 0.0, hor_lines: 0.0 };
- };
+ return Err(err.into());
+ }
- keyboard.set_text_keys(iter_array_queue(&context.shared_state.text_keys));
+ Ok(())
+}
+fn receive_app_messages(context: &mut Context, actions: &mut Actions, world: &World)
+{
let Context {
ref mut windows, ref shared_state, ..
} = *context;
@@ -255,11 +191,11 @@ fn update_stuff(
tracing::trace!(message=?message, "Received message from app");
match message {
- MessageFromApp::WindowCreated(
+ MessageFromApp::Window(WindowMessage::Created(
window_ent_id,
winit_window,
window_creation_attrs,
- ) => {
+ )) => {
actions.add_components(
window_ent_id,
(Window::new(&winit_window, &window_creation_attrs),),
@@ -277,7 +213,10 @@ fn update_stuff(
"Window creation completed"
);
}
- MessageFromApp::WindowResized(window_id, new_window_size) => {
+ MessageFromApp::Window(WindowMessage::Resized(
+ window_id,
+ new_window_size,
+ )) => {
tracing::trace!(
window_id = ?window_id,
"Received window resized message"
@@ -293,7 +232,7 @@ fn update_stuff(
continue;
};
- let Some(window_ent) = entity_obtainer.get_entity(*window_ent_id) else {
+ let Some(window_ent) = world.get_entity(*window_ent_id) else {
continue;
};
@@ -305,7 +244,7 @@ fn update_stuff(
window.set_changed();
}
- MessageFromApp::WindowCloseRequested(window_id) => {
+ MessageFromApp::Window(WindowMessage::CloseRequested(window_id)) => {
let Some(window_ent_id) =
windows.get(window_id).map(|(_, ent_id)| ent_id)
else {
@@ -318,7 +257,10 @@ fn update_stuff(
actions.remove_comps::<(Window,)>(*window_ent_id);
}
- MessageFromApp::WindowScaleFactorChanged(window_id, scale_factor) => {
+ MessageFromApp::Window(WindowMessage::ScaleFactorChanged(
+ window_id,
+ scale_factor,
+ )) => {
let Some(window_ent_id) =
windows.get(window_id).map(|(_, ent_id)| ent_id)
else {
@@ -329,7 +271,7 @@ fn update_stuff(
continue;
};
- let Some(window_ent) = entity_obtainer.get_entity(*window_ent_id) else {
+ let Some(window_ent) = world.get_entity(*window_ent_id) else {
continue;
};
@@ -343,31 +285,109 @@ fn update_stuff(
}
}
}
+}
- if shared_state.thread_panicked.load(Ordering::Relaxed) {
- cold_path();
- return Err(error!("Windowing app thread panicked"));
- }
-
- if shared_state.has_thread_err.load(Ordering::Relaxed) {
- cold_path();
+fn update_inputs(
+ context: &Context,
+ keyboard: &mut Keyboard,
+ mouse: &mut Mouse,
+ mouse_buttons: &mut MouseButtons,
+)
+{
+ keyboard.make_key_states_previous();
- let Ok(mut err) = shared_state.thread_err.try_lock() else {
- // The windowing app thread always unlocks the thread_err mutex before
- // setting the has_thread_err atomic
- unreachable!();
+ {
+ let Some(mut input) = context
+ .shared_state
+ .input
+ .try_lock_for(Duration::from_millis(100))
+ else {
+ tracing::error!("Locking input mutex timed out after 100ms");
+ return;
};
- let Some(err) = err.take() else {
- // The has_thread_err atomic is set to true so this option is always
- // Some
- unreachable!();
- };
+ mouse.curr_tick_position_delta = input.relative_mouse_pos_delta;
+ mouse.position = input.absolute_mouse_pos;
+ mouse.curr_tick_scroll_delta = input.mouse_scroll_delta.clone();
- return Err(err.into());
- }
+ for (mouse_button, mouse_button_input) in &mut input.mouse_buttons {
+ mouse_buttons.set_previous_to_current(mouse_button);
- Ok(())
+ if mouse_button_input.flags.is_all() {
+ match mouse_buttons.get_previous(mouse_button) {
+ MouseButtonState::Pressed => {
+ mouse_buttons.set(mouse_button, MouseButtonState::Released);
+
+ mouse_button_input.flags.remove(MouseButtonFlags::RELEASED);
+ }
+ MouseButtonState::Released => {
+ mouse_buttons.set(mouse_button, MouseButtonState::Pressed);
+
+ mouse_button_input.flags.remove(MouseButtonFlags::PRESSED);
+ }
+ }
+
+ continue;
+ }
+
+ let mouse_button_state = if mouse_button_input.flags.is_empty() {
+ let Some(mouse_button_state) = mouse_button_input.lagged.pop_front()
+ else {
+ continue;
+ };
+
+ mouse_button_state
+ } else {
+ bitflags_match!(mouse_button_input.flags, {
+ MouseButtonFlags::PRESSED => MouseButtonState::Pressed,
+ MouseButtonFlags::RELEASED => MouseButtonState::Released,
+ _ => unreachable!()
+ })
+ };
+
+ mouse_buttons.set(mouse_button, mouse_button_state);
+
+ mouse_button_input.flags.clear();
+ }
+
+ let mut key_updates = input.keys.iter_occupied_mut();
+
+ while let Some(mut key_item) = key_updates.streaming_next() {
+ let key = Key::KEYS[key_item.index];
+
+ if key_item.bits == KEY_PRESSED_BITS | KEY_RELEASED_BITS {
+ match keyboard.get_key_state(key) {
+ KeyState::Pressed => {
+ keyboard.set_key_state(key, KeyState::Released);
+
+ key_item.clear_and_set(KEY_PRESSED_BITS, u8::MAX);
+ }
+ KeyState::Released => {
+ keyboard.set_key_state(key, KeyState::Pressed);
+
+ key_item.clear_and_set(KEY_RELEASED_BITS, u8::MAX);
+ }
+ }
+
+ continue;
+ }
+
+ let key_state = match key_item.bits {
+ KEY_PRESSED_BITS => KeyState::Pressed,
+ KEY_RELEASED_BITS => KeyState::Released,
+ _ => unreachable!(),
+ };
+
+ keyboard.set_key_state(key, key_state);
+
+ key_item.clear_and_set(0, u8::MAX);
+ }
+
+ input.relative_mouse_pos_delta = Vec2 { x: 0.0, y: 0.0 };
+ input.mouse_scroll_delta = MouseScrollDelta { vert_lines: 0.0, hor_lines: 0.0 };
+ };
+
+ keyboard.set_text_keys(iter_array_queue(&context.shared_state.text_keys));
}
fn handle_window_changed(
@@ -442,6 +462,7 @@ pub struct Context
impl Context
{
+ #[must_use]
pub fn display_handle(&self) -> Option<DisplayHandle<'_>>
{
self.display_handle.as_ref()?.display_handle().ok()
@@ -451,6 +472,7 @@ impl Context
///
/// # Safety
/// The Window handle must only be used with thread safe APIs.
+ #[must_use]
pub unsafe fn get_window_as_handle(
&self,
window_id: &WindowId,
@@ -476,6 +498,7 @@ impl Context
/// Returns the last known primary monitor. This monitor may or may not exist any
/// longer and it may or may not be the primary monitor any longer.
+ #[must_use]
pub fn get_primary_monitor(&self) -> Option<&MonitorHandle>
{
self.primary_monitor.as_ref()
@@ -509,11 +532,12 @@ impl Context
///
/// # Panics
/// Will panic if a windowing context have already been created.
- pub fn new() -> Self
+ pub fn new_global() -> Self
{
- if CONTEXT_CREATED.swap(true, Ordering::Relaxed) {
- panic!("A windowing context have already been created");
- }
+ assert!(
+ !CONTEXT_CREATED.swap(true, Ordering::Relaxed),
+ "A windowing context have already been created"
+ );
let shared_state = Arc::new(SharedState::default());
let shared_state_b = shared_state.clone();
@@ -521,58 +545,7 @@ impl Context
if let Err(err) = ThreadBuilder::new()
.name("windowing app".to_string())
.spawn(move || {
- let shared_state_c = shared_state_b.clone();
-
- match catch_unwind(move || {
- let mut app = App {
- shared_state: shared_state_b,
- windows: IntMap::with_capacity(1),
- };
-
- let event_loop = match create_event_loop() {
- Ok(event_loop) => event_loop,
- Err(err) => {
- return Err((app, AppThreadError::CreateEventLoop(err)));
- }
- };
-
- event_loop.set_control_flow(EventLoopControlFlow::Poll);
-
- event_loop
- .run_app(&mut app)
- .map_err(|err| (app, AppThreadError::StartEventLoop(err)))?;
-
- Ok(())
- }) {
- Ok(Ok(())) => {}
- Ok(Err((app, err))) => {
- {
- let Ok(mut thread_err) =
- app.shared_state.thread_err.try_lock()
- else {
- // The thread_err mutex is only locked by the main thread
- // when the has_thread_err atomic is set to true, which
- // it can not be set to yet
- unreachable!();
- };
-
- *thread_err = Some(err);
- }
-
- app.shared_state
- .has_thread_err
- .store(true, Ordering::Relaxed);
-
- app.shared_state.init_data_cond.notify_one();
- }
- Err(_) => {
- shared_state_c
- .thread_panicked
- .store(true, Ordering::Relaxed);
-
- shared_state_c.init_data_cond.notify_one();
- }
- };
+ app_thread_main(shared_state_b);
})
{
tracing::error!(
@@ -664,6 +637,58 @@ impl Drop for Context
}
}
+fn app_thread_main(shared_state: Arc<SharedState>)
+{
+ let shared_state_c = shared_state.clone();
+
+ match catch_unwind(move || {
+ let mut app = App {
+ shared_state,
+ windows: IntMap::with_capacity(1),
+ };
+
+ let event_loop = match create_event_loop() {
+ Ok(event_loop) => event_loop,
+ Err(err) => {
+ return Err(AppThreadError::CreateEventLoop(err));
+ }
+ };
+
+ event_loop.set_control_flow(EventLoopControlFlow::Poll);
+
+ event_loop
+ .run_app(&mut app)
+ .map_err(AppThreadError::StartEventLoop)?;
+
+ Ok(())
+ }) {
+ Ok(Ok(())) => {}
+ Ok(Err(err)) => {
+ {
+ let Ok(mut thread_err) = shared_state_c.thread_err.try_lock() else {
+ // The thread_err mutex is only locked by the main thread
+ // when the has_thread_err atomic is set to true, which
+ // it can not be set to yet
+ unreachable!();
+ };
+
+ *thread_err = Some(err);
+ }
+
+ shared_state_c.has_thread_err.store(true, Ordering::Relaxed);
+
+ shared_state_c.init_data_cond.notify_one();
+ }
+ Err(_) => {
+ shared_state_c
+ .thread_panicked
+ .store(true, Ordering::Relaxed);
+
+ shared_state_c.init_data_cond.notify_one();
+ }
+ };
+}
+
fn create_event_loop() -> Result<EventLoop<()>, EventLoopError>
{
let mut event_loop_builder = EventLoop::builder();
@@ -702,10 +727,16 @@ enum AppThreadError
#[derive(Debug)]
enum MessageFromApp
{
- WindowCreated(Uid, Arc<WinitWindow>, WindowCreationAttributes),
- WindowResized(WindowId, PhysicalSize<u32>),
- WindowCloseRequested(WindowId),
- WindowScaleFactorChanged(WindowId, f64),
+ Window(WindowMessage),
+}
+
+#[derive(Debug)]
+enum WindowMessage
+{
+ Created(Uid, Arc<WinitWindow>, WindowCreationAttributes),
+ Resized(WindowId, PhysicalSize<u32>),
+ CloseRequested(WindowId),
+ ScaleFactorChanged(WindowId, f64),
}
#[derive(Debug)]
@@ -855,11 +886,11 @@ impl App
),
);
- self.send_message(MessageFromApp::WindowCreated(
+ self.send_message(MessageFromApp::Window(WindowMessage::Created(
window_ent_id,
winit_window,
window_creation_attrs,
- ));
+ )));
}
MessageToApp::SetWindowCursorGrabMode(window_id, cursor_grab_mode) => {
let Some((_, window_settings)) = self.windows.get_mut(window_id)
@@ -896,6 +927,153 @@ impl App
.input
.try_lock_for(Duration::from_millis(100))
}
+
+ fn handle_keyboard_input(&self, keyboard_event: winit::event::KeyEvent)
+ {
+ if let Some(key_text) = keyboard_event
+ .text
+ .filter(|_| keyboard_event.state.is_pressed())
+ {
+ for character in key_text.chars() {
+ if self.shared_state.text_keys.is_full() {
+ cold_path();
+ tracing::warn!("Text key queue is full. Dropping oldest character");
+ }
+
+ self.shared_state.text_keys.force_push(character);
+ }
+ }
+
+ if keyboard_event.repeat {
+ return;
+ }
+
+ let key_code = match keyboard_event.physical_key {
+ PhysicalKey::Code(key_code) => key_code,
+ PhysicalKey::Unidentified(native_key) => {
+ tracing::warn!("Ignoring unidentified key: {native_key:?}");
+ return;
+ }
+ };
+
+ let key: Key = if let Ok(key) = key_code.try_into() {
+ key
+ } else {
+ tracing::warn!("Ignoring key with unknown key code {key_code:?}");
+ return;
+ };
+
+ let Some(mut input) = self.lock_input() else {
+ tracing::error!("Locking input mutex timed out after 100ms");
+ return;
+ };
+
+ let key_state_bits = match keyboard_event.state.into() {
+ KeyState::Pressed => KEY_PRESSED_BITS,
+ KeyState::Released => KEY_RELEASED_BITS,
+ };
+
+ input.keys.clear_and_set(key as usize, key_state_bits, 0);
+ }
+
+ fn handle_cursor_moved(&self, position: PhysicalPosition<f64>, window_id: WindowId)
+ {
+ {
+ let Some(mut input) = self.lock_input() else {
+ tracing::error!("Locking input mutex timed out after 100ms");
+ return;
+ };
+
+ input.absolute_mouse_pos = position;
+ }
+
+ let Some((window, window_settings)) = self.windows.get(window_id) else {
+ cold_path();
+ return;
+ };
+
+ if window_settings.cursor_grab_mode != CursorGrabMode::Locked {
+ return;
+ }
+
+ let Some(window) = window.upgrade() else {
+ cold_path();
+ return;
+ };
+
+ if !window.has_focus() {
+ return;
+ }
+
+ let window_size = window.inner_size().to_logical::<f64>(window.scale_factor());
+
+ if let Err(err) = window.set_cursor_position(Position::Logical(LogicalPosition {
+ x: window_size.width / 2.0,
+ y: window_size.height / 2.0,
+ })) {
+ cold_path();
+ tracing::error!(
+ window_id=?window_id,
+ "Failed to lock cursor position: {:#}",
+ crate::Error::new(err)
+ );
+ }
+ }
+
+ fn handle_mouse_wheel(&self, delta: winit::event::MouseScrollDelta)
+ {
+ let (hor_lines, vert_lines) = match delta {
+ winit::event::MouseScrollDelta::LineDelta(hor_lines, vert_lines) => {
+ (hor_lines, vert_lines)
+ }
+ winit::event::MouseScrollDelta::PixelDelta(pos_delta) => {
+ let hor_lines = match pos_delta.x.partial_cmp(&0.0) {
+ Some(std::cmp::Ordering::Greater) => 1.0,
+ Some(std::cmp::Ordering::Less) => -1.0,
+ _ => 0.0,
+ };
+
+ let vert_lines = match pos_delta.y.partial_cmp(&0.0) {
+ Some(std::cmp::Ordering::Greater) => 1.0,
+ Some(std::cmp::Ordering::Less) => -1.0,
+ _ => 0.0,
+ };
+
+ (hor_lines, vert_lines)
+ }
+ };
+
+ let Some(mut input) = self.lock_input() else {
+ tracing::error!("Locking input mutex timed out after 100ms");
+ return;
+ };
+
+ input.mouse_scroll_delta.hor_lines += hor_lines;
+ input.mouse_scroll_delta.vert_lines += vert_lines;
+ }
+
+ fn handle_mouse_input(&self, button: MouseButton, button_state: MouseButtonState)
+ {
+ let Some(mut input) = self.lock_input() else {
+ tracing::error!("Locking input mutex timed out after 100ms");
+ return;
+ };
+
+ let button_input = input
+ .mouse_buttons
+ .entry(button)
+ .or_insert_with(MouseButtonInput::default);
+
+ if button_input.flags.is_all() || !button_input.lagged.is_empty() {
+ button_input.lagged.push_back(button_state);
+ return;
+ }
+
+ button_input.flags.insert(match button_state {
+ MouseButtonState::Pressed => MouseButtonFlags::PRESSED,
+ MouseButtonState::Released => MouseButtonFlags::RELEASED,
+ });
+ }
}
impl ApplicationHandler for App
@@ -917,10 +1095,10 @@ impl ApplicationHandler for App
*init_data = Some(InitData {
display: event_loop.owned_display_handle(),
- available_monitors: available_monitors,
+ available_monitors,
primary_monitor: event_loop
.primary_monitor()
- .map(|monitor| MonitorHandle::from_winit_monitor_handle(monitor)),
+ .map(MonitorHandle::from_winit_monitor_handle),
});
self.shared_state.init_data_cond.notify_one();
@@ -960,173 +1138,39 @@ impl ApplicationHandler for App
{
match event {
WindowEvent::Resized(new_window_size) => {
- self.send_message(MessageFromApp::WindowResized(
+ self.send_message(MessageFromApp::Window(WindowMessage::Resized(
WindowId::from_inner(window_id),
new_window_size.into(),
- ));
+ )));
}
WindowEvent::CloseRequested => {
- self.send_message(MessageFromApp::WindowCloseRequested(
+ self.send_message(MessageFromApp::Window(WindowMessage::CloseRequested(
WindowId::from_inner(window_id),
- ));
+ )));
}
WindowEvent::KeyboardInput {
device_id: _,
event: keyboard_event,
is_synthetic: _,
- } => {
- if let Some(key_text) = keyboard_event
- .text
- .filter(|_| keyboard_event.state.is_pressed())
- {
- for character in key_text.chars() {
- if self.shared_state.text_keys.is_full() {
- cold_path();
- tracing::warn!(
- "Text key queue is full. Dropping oldest character"
- );
- }
-
- self.shared_state.text_keys.force_push(character);
- }
- }
-
- if keyboard_event.repeat {
- return;
- }
-
- let key_code = match keyboard_event.physical_key {
- PhysicalKey::Code(key_code) => key_code,
- PhysicalKey::Unidentified(native_key) => {
- tracing::warn!("Ignoring unidentified key: {native_key:?}");
- return;
- }
- };
-
- let key: Key = match key_code.try_into() {
- Ok(key) => key,
- Err(UnknownKeyCodeError) => {
- tracing::warn!("Ignoring key with unknown key code {key_code:?}");
- return;
- }
- };
-
- let Some(mut input) = self.lock_input() else {
- tracing::error!("Locking input mutex timed out after 100ms");
- return;
- };
-
- let key_state_bits = match keyboard_event.state.into() {
- KeyState::Pressed => KEY_PRESSED_BITS,
- KeyState::Released => KEY_RELEASED_BITS,
- };
-
- input.keys.clear_and_set(key as usize, key_state_bits, 0);
- }
+ } => self.handle_keyboard_input(keyboard_event),
WindowEvent::CursorMoved { device_id: _, position } => {
- {
- let Some(mut input) = self.lock_input() else {
- tracing::error!("Locking input mutex timed out after 100ms");
- return;
- };
-
- input.absolute_mouse_pos = position.into();
- }
-
- let Some((window, window_settings)) =
- self.windows.get(WindowId::from_inner(window_id))
- else {
- cold_path();
- return;
- };
-
- if window_settings.cursor_grab_mode != CursorGrabMode::Locked {
- return;
- }
-
- let Some(window) = window.upgrade() else {
- cold_path();
- return;
- };
-
- if !window.has_focus() {
- return;
- }
-
- let window_size = window.inner_size();
-
- if let Err(err) =
- window.set_cursor_position(Position::Physical(PhysicalPosition {
- x: window_size.width as i32 / 2,
- y: window_size.height as i32 / 2,
- }))
- {
- cold_path();
- tracing::error!(
- window_id=?window_id,
- "Failed to lock cursor position: {:#}",
- crate::Error::new(err)
- );
- };
+ self.handle_cursor_moved(
+ position.into(),
+ WindowId::from_inner(window_id),
+ );
}
WindowEvent::MouseWheel { device_id: _, delta, phase: _ } => {
- let (hor_lines, vert_lines) = match delta {
- winit::event::MouseScrollDelta::LineDelta(hor_lines, vert_lines) => {
- (hor_lines, vert_lines)
- }
- winit::event::MouseScrollDelta::PixelDelta(pos_delta) => {
- let hor_lines = match pos_delta.x.partial_cmp(&0.0) {
- Some(std::cmp::Ordering::Greater) => 1.0,
- Some(std::cmp::Ordering::Less) => -1.0,
- _ => 0.0,
- };
-
- let vert_lines = match pos_delta.y.partial_cmp(&0.0) {
- Some(std::cmp::Ordering::Greater) => 1.0,
- Some(std::cmp::Ordering::Less) => -1.0,
- _ => 0.0,
- };
-
- (hor_lines, vert_lines)
- }
- };
-
- let Some(mut input) = self.lock_input() else {
- tracing::error!("Locking input mutex timed out after 100ms");
- return;
- };
-
- input.mouse_scroll_delta.hor_lines += hor_lines;
- input.mouse_scroll_delta.vert_lines += vert_lines;
+ self.handle_mouse_wheel(delta);
}
WindowEvent::MouseInput { device_id: _, state, button } => {
- let Some(mut input) = self.lock_input() else {
- tracing::error!("Locking input mutex timed out after 100ms");
- return;
- };
-
- let button = MouseButton::from(button);
- let button_state = MouseButtonState::from(state);
-
- let button_input = input
- .mouse_buttons
- .entry(button)
- .or_insert_with(|| MouseButtonInput::default());
-
- if button_input.flags.is_all() || !button_input.lagged.is_empty() {
- button_input.lagged.push_back(button_state);
- return;
- }
-
- button_input.flags.insert(match button_state {
- MouseButtonState::Pressed => MouseButtonFlags::PRESSED,
- MouseButtonState::Released => MouseButtonFlags::RELEASED,
- });
+ self.handle_mouse_input(button.into(), state.into());
}
WindowEvent::ScaleFactorChanged { scale_factor, inner_size_writer: _ } => {
- self.send_message(MessageFromApp::WindowScaleFactorChanged(
- WindowId::from_inner(window_id),
- scale_factor,
+ self.send_message(MessageFromApp::Window(
+ WindowMessage::ScaleFactorChanged(
+ WindowId::from_inner(window_id),
+ scale_factor,
+ ),
));
}
_ => {}
@@ -1141,16 +1185,13 @@ impl ApplicationHandler for App
device_event: DeviceEvent,
)
{
- match device_event {
- DeviceEvent::MouseMotion { delta } => {
- let Some(mut input) = self.lock_input() else {
- tracing::error!("Locking input mutex timed out after 100ms");
- return;
- };
+ if let DeviceEvent::MouseMotion { delta } = device_event {
+ let Some(mut input) = self.lock_input() else {
+ tracing::error!("Locking input mutex timed out after 100ms");
+ return;
+ };
- input.relative_mouse_pos_delta += Vec2::from(delta);
- }
- _ => {}
+ input.relative_mouse_pos_delta += Vec2::from(delta);
}
}
}
diff --git a/engine/src/windowing/dpi.rs b/engine/src/windowing/dpi.rs
index e3b1be1..9bc42e1 100644
--- a/engine/src/windowing/dpi.rs
+++ b/engine/src/windowing/dpi.rs
@@ -75,6 +75,12 @@ impl<Pixel> PhysicalPosition<Pixel>
}
}
+ /// Attempts to convert the `x` and `y` values in `source` from the type `SourcePixel`
+ /// to the type `Pixel`.
+ ///
+ /// # Errors
+ /// Returns `Err` if conversion of either `x` or `y` by their respective `TryFrom`
+ /// implementations fails.
pub fn try_convert_from<SourcePixel>(
source: PhysicalPosition<SourcePixel>,
) -> Result<Self, Pixel::Error>
@@ -100,6 +106,12 @@ pub struct LogicalPosition<Pixel>
impl<Pixel> LogicalPosition<Pixel>
{
+ /// Attempts to convert the `x` and `y` values in `source` from the type `SourcePixel`
+ /// to the type `Pixel`.
+ ///
+ /// # Errors
+ /// Returns `Err` if conversion of either `x` or `y` by their respective `TryFrom`
+ /// implementations fails.
pub fn try_convert_from<SourcePixel>(
source: LogicalPosition<SourcePixel>,
) -> Result<Self, Pixel::Error>
@@ -159,6 +171,12 @@ impl<Pixel> PhysicalSize<Pixel>
impl<Pixel> PhysicalSize<Pixel>
{
+ /// Attempts to convert the `width` and `height` values in `source` from the type
+ /// `SourcePixel` to the type `Pixel`.
+ ///
+ /// # Errors
+ /// Returns `Err` if conversion of either `width` or `height` by their respective
+ /// `TryFrom` implementations fails.
pub fn try_convert_from<SourcePixel>(
source: PhysicalSize<SourcePixel>,
) -> Result<Self, Pixel::Error>
@@ -184,6 +202,12 @@ pub struct LogicalSize<Pixel>
impl<Pixel> LogicalSize<Pixel>
{
+ /// Attempts to convert the `width` and `height` values in `source` from the type
+ /// `SourcePixel` to the type `Pixel`.
+ ///
+ /// # Errors
+ /// Returns `Err` if conversion of either `width` or `height` by their respective
+ /// `TryFrom` implementations fails.
pub fn try_convert_from<SourcePixel>(
source: LogicalSize<SourcePixel>,
) -> Result<Self, Pixel::Error>
diff --git a/engine/src/windowing/keyboard.rs b/engine/src/windowing/keyboard.rs
index dffa95e..a8ec6df 100644
--- a/engine/src/windowing/keyboard.rs
+++ b/engine/src/windowing/keyboard.rs
@@ -14,6 +14,7 @@ impl Keyboard
{
/// Returns whether the given key was just pressed this frame. This function will
/// return `false` if the key was also pressed the previous frame.
+ #[must_use]
pub fn just_pressed(&self, key: Key) -> bool
{
self.get_key_state(key) == KeyState::Pressed
@@ -22,6 +23,7 @@ impl Keyboard
/// Returns whether the given key was just released this frame. This function will
/// return `false` if the key was also released the previous frame.
+ #[must_use]
pub fn just_released(&self, key: Key) -> bool
{
self.get_key_state(key) == KeyState::Released
@@ -29,12 +31,14 @@ impl Keyboard
}
/// Returns whether the given key is currently pressed.
+ #[must_use]
pub fn pressed(&self, key: Key) -> bool
{
self.get_key_state(key) == KeyState::Pressed
}
/// Returns whether the given key is currently released.
+ #[must_use]
pub fn released(&self, key: Key) -> bool
{
self.get_key_state(key) == KeyState::Released
@@ -66,13 +70,11 @@ impl Keyboard
{
let bits = self.keys.get(key as usize);
- let state = match bits & KEY_CURR_PRESSED_BITS {
+ match bits & KEY_CURR_PRESSED_BITS {
KEY_CURR_PRESSED_BITS => KeyState::Pressed,
0 => KeyState::Released,
_ => unreachable!(),
- };
-
- state
+ }
}
#[must_use]
@@ -80,15 +82,14 @@ impl Keyboard
{
let bits = self.keys.get(key as usize);
- let state = match bits & KEY_PREV_PRESSED_BITS {
+ match bits & KEY_PREV_PRESSED_BITS {
KEY_PREV_PRESSED_BITS => KeyState::Pressed,
0 => KeyState::Released,
_ => unreachable!(),
- };
-
- state
+ }
}
+ #[must_use]
pub fn text_keys(&self) -> &str
{
&self.text_keys
@@ -109,7 +110,7 @@ impl Keyboard
pub fn make_key_states_previous(&mut self)
{
for byte in self.keys.bytes_mut() {
- *byte = (*byte >> 1) & 0b01010101 | *byte & 0b10101010;
+ *byte = (*byte >> 1) & 0b0101_0101 | *byte & 0b1010_1010;
}
}
@@ -125,7 +126,7 @@ impl Keyboard
#[non_exhaustive]
pub enum Key
{
- /// <kbd>`</kbd> on a US keyboard. This is also called a backtick or grave.
+ #[doc = "<kbd>`</kbd> on a US keyboard. This is also called a backtick or grave."]
/// This is the <kbd>半角</kbd>/<kbd>全角</kbd>/<kbd>漢字</kbd>
/// (hankaku/zenkaku/kanji) key on Japanese keyboards
Backquote,
@@ -243,12 +244,12 @@ pub enum Key
/// <kbd>Alt</kbd>, <kbd>Option</kbd>, or <kbd>⌥</kbd>.
AltLeft,
/// <kbd>Alt</kbd>, <kbd>Option</kbd>, or <kbd>⌥</kbd>.
- /// This is labeled <kbd>AltGr</kbd> on many keyboard layouts.
+ /// This is labeled <kbd>`AltGr`</kbd> on many keyboard layouts.
AltRight,
/// <kbd>Backspace</kbd> or <kbd>⌫</kbd>.
/// Labeled <kbd>Delete</kbd> on Apple keyboards.
Backspace,
- /// <kbd>CapsLock</kbd> or <kbd>⇪</kbd>
+ /// <kbd>`CapsLock`</kbd> or <kbd>⇪</kbd>
CapsLock,
/// The application context menu key, which is typically found between the right
/// <kbd>Super</kbd> key and the right <kbd>Control</kbd> key.
@@ -276,7 +277,7 @@ pub enum Key
/// Japanese: <kbd>カタカナ</kbd>/<kbd>ひらがな</kbd>/<kbd>ローマ字</kbd>
/// (katakana/hiragana/romaji)
KanaMode,
- /// Korean: HangulMode <kbd>한/영</kbd> (han/yeong)
+ /// Korean: `HangulMode` <kbd>한/영</kbd> (han/yeong)
///
/// Japanese (Mac keyboard): <kbd>か</kbd> (kana)
Lang1,
@@ -306,9 +307,9 @@ pub enum Key
Home,
/// <kbd>Insert</kbd> or <kbd>Ins</kbd>. Not present on Apple keyboards.
Insert,
- /// <kbd>Page Down</kbd>, <kbd>PgDn</kbd>, or <kbd>⇟</kbd>
+ /// <kbd>Page Down</kbd>, <kbd>`PgDn`</kbd>, or <kbd>⇟</kbd>
PageDown,
- /// <kbd>Page Up</kbd>, <kbd>PgUp</kbd>, or <kbd>⇞</kbd>
+ /// <kbd>Page Up</kbd>, <kbd>`PgUp`</kbd>, or <kbd>⇞</kbd>
PageUp,
/// <kbd>↓</kbd>
ArrowDown,
@@ -327,7 +328,7 @@ pub enum Key
Numpad1,
/// <kbd>2 ↓</kbd> on a keyboard. <kbd>2 ABC</kbd> on a phone or remote control
Numpad2,
- /// <kbd>3 PgDn</kbd> on a keyboard. <kbd>3 DEF</kbd> on a phone or remote control
+ /// <kbd>3 `PgDn`</kbd> on a keyboard. <kbd>3 DEF</kbd> on a phone or remote control
Numpad3,
/// <kbd>4 ←</kbd> on a keyboard. <kbd>4 GHI</kbd> on a phone or remote control
Numpad4,
@@ -340,15 +341,15 @@ pub enum Key
Numpad7,
/// <kbd>8 ↑</kbd> on a keyboard. <kbd>8 TUV</kbd> on a phone or remote control
Numpad8,
- /// <kbd>9 PgUp</kbd> on a keyboard. <kbd>9 WXYZ</kbd> or <kbd>9 WXY</kbd> on a phone
- /// or remote control
+ /// <kbd>9 `PgUp`</kbd> on a keyboard. <kbd>9 WXYZ</kbd> or <kbd>9 WXY</kbd> on a
+ /// phone or remote control
Numpad9,
/// <kbd>+</kbd>
NumpadAdd,
/// Found on the Microsoft Natural Keyboard.
NumpadBackspace,
/// <kbd>C</kbd> or <kbd>A</kbd> (All Clear). Also for use with numpads that have a
- /// <kbd>Clear</kbd> key that is separate from the <kbd>NumLock</kbd> key. On the
+ /// <kbd>Clear</kbd> key that is separate from the <kbd>`NumLock`</kbd> key. On the
/// Mac, the numpad <kbd>Clear</kbd> key is encoded as [`NumLock`].
///
/// [`NumLock`]: Self::NumLock
@@ -393,7 +394,7 @@ pub enum Key
/// This key is typically found below the <kbd>7</kbd> key and to the left of
/// the <kbd>0</kbd> key.
///
- /// Use <kbd>"NumpadMultiply"</kbd> for the <kbd>*</kbd> key on
+ /// Use <kbd>"`NumpadMultiply`"</kbd> for the <kbd>*</kbd> key on
/// numeric keypads.
NumpadStar,
/// <kbd>-</kbd>
@@ -403,10 +404,10 @@ pub enum Key
/// <kbd>Fn</kbd> This is typically a hardware key that does not generate a separate
/// code.
Fn,
- /// <kbd>FLock</kbd> or <kbd>FnLock</kbd>. Function Lock key. Found on the Microsoft
- /// Natural Keyboard.
+ /// <kbd>`FLock`</kbd> or <kbd>`FnLock`</kbd>. Function Lock key. Found on the
+ /// Microsoft Natural Keyboard.
FnLock,
- /// <kbd>PrtScr SysRq</kbd> or <kbd>Print Screen</kbd>
+ /// <kbd>`PrtScr` `SysRq`</kbd> or <kbd>Print Screen</kbd>
PrintScreen,
/// <kbd>Scroll Lock</kbd>
ScrollLock,
@@ -577,6 +578,7 @@ impl TryFrom<winit::keyboard::KeyCode> for Key
{
type Error = UnknownKeyCodeError;
+ #[allow(clippy::too_many_lines)]
fn try_from(key_code: winit::keyboard::KeyCode) -> Result<Self, Self::Error>
{
match key_code {
diff --git a/engine/src/windowing/monitor.rs b/engine/src/windowing/monitor.rs
index 894448a..392489d 100644
--- a/engine/src/windowing/monitor.rs
+++ b/engine/src/windowing/monitor.rs
@@ -11,6 +11,7 @@ impl Handle
{
/// Returns a human-readable name of the monitor.
#[inline]
+ #[must_use]
pub fn name(&self) -> Option<String>
{
self.inner.name()
@@ -18,6 +19,7 @@ impl Handle
/// Returns the monitor's resolution.
#[inline]
+ #[must_use]
pub fn size(&self) -> PhysicalSize<u32>
{
self.inner.size().into()
@@ -26,6 +28,7 @@ impl Handle
/// Returns the top-left corner position of the monitor relative to the larger full
/// screen area.
#[inline]
+ #[must_use]
pub fn position(&self) -> PhysicalPosition<i32>
{
self.inner.position().into()
@@ -33,6 +36,7 @@ impl Handle
/// Returns the scale factor of the underlying monitor.
#[inline]
+ #[must_use]
pub fn scale_factor(&self) -> f64
{
self.inner.scale_factor()
diff --git a/engine/src/windowing/mouse.rs b/engine/src/windowing/mouse.rs
index 3a43e79..a5e4cc8 100644
--- a/engine/src/windowing/mouse.rs
+++ b/engine/src/windowing/mouse.rs
@@ -31,6 +31,7 @@ pub struct ScrollDelta
impl ScrollDelta
{
+ #[must_use]
pub fn is_zero(&self) -> bool
{
self.vert_lines == 0.0 && self.hor_lines == 0.0
@@ -46,6 +47,7 @@ pub struct Buttons
impl Buttons
{
+ #[must_use]
pub fn get(&self, button: Button) -> ButtonState
{
let Some(button_data) = self.map.get(&button) else {
@@ -55,6 +57,7 @@ impl Buttons
button_data.current_state
}
+ #[must_use]
pub fn get_previous(&self, button: Button) -> ButtonState
{
let Some(button_data) = self.map.get(&button) else {
@@ -70,7 +73,7 @@ impl Buttons
{
self.map
.iter()
- .map(|(button, button_data)| (button.clone(), button_data.current_state))
+ .map(|(button, button_data)| (*button, button_data.current_state))
}
pub fn set(&mut self, button: Button, button_state: ButtonState)
@@ -120,7 +123,7 @@ impl intmap::IntKey for Button
Self::Middle => 2,
Self::Back => 3,
Self::Forward => 4,
- Self::Other(other) => 5 + *other as u32,
+ Self::Other(other) => 5 + u32::from(*other),
}
}
}
diff --git a/engine/src/windowing/window.rs b/engine/src/windowing/window.rs
index 6d7a464..ae4a36b 100644
--- a/engine/src/windowing/window.rs
+++ b/engine/src/windowing/window.rs
@@ -59,6 +59,7 @@ macro_rules! gen_creation_attrs_with_fn {
paste::paste! {
impl CreationAttributes
{
+ #[must_use]
pub fn [<with_ $field>](mut self, new: impl Into<$field_type>) -> Self
{
self.$field = new.into();
@@ -93,12 +94,9 @@ impl CreationAttributes
.with_title(self.title.into_owned())
.with_transparent(self.transparent)
.with_maximized(self.maximized)
- .with_fullscreen(match self.fullscreen {
- Some(Fullscreen::Borderless) => {
- Some(winit::window::Fullscreen::Borderless(None))
- }
- None => None,
- })
+ .with_fullscreen(self.fullscreen.map(|Fullscreen::Borderless| {
+ winit::window::Fullscreen::Borderless(None)
+ }))
.with_visible(self.visible)
.with_resizable(self.resizable)
.with_window_icon(match self.icon {
@@ -212,11 +210,13 @@ pub struct Window
impl Window
{
+ #[must_use]
pub fn wid(&self) -> Id
{
self.wid
}
+ #[must_use]
pub fn scale_factor(&self) -> f64
{
self.scale_factor
@@ -243,11 +243,11 @@ impl Window
winit_window.set_title(&self.title);
winit_window.set_cursor_visible(self.cursor_visible);
- let curr_inner_size = winit_window.inner_size().clone().into();
+ let curr_inner_size = winit_window.inner_size().into();
- let inner_size_request_result = match winit_window.request_inner_size(
- winit::dpi::Size::Physical(self.inner_size.clone().into()),
- ) {
+ let inner_size_request_result = match winit_window
+ .request_inner_size(winit::dpi::Size::Physical(self.inner_size.into()))
+ {
// The comparison of curr_inner_size is in case the user's windowing system
// lies about using the requested inner size
None if curr_inner_size == self.inner_size => Ok(()),
diff --git a/engine/src/work_queue.rs b/engine/src/work_queue.rs
index 494d2b5..765aec3 100644
--- a/engine/src/work_queue.rs
+++ b/engine/src/work_queue.rs
@@ -32,7 +32,7 @@ impl<UserData: Send + Sync + 'static> WorkQueue<UserData>
Self {
work_sender,
- thread_panic: thread_panic,
+ thread_panic,
_thread: ThreadBuilder::new()
.name(name.to_string())
.spawn(move || {