From 71056a3552778cc6fbe87da9579f1959988ccaec Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Tue, 27 Sep 2022 19:12:57 +0200 Subject: [PATCH 01/21] made resource_scope work for non-send resources --- crates/bevy_ecs/src/lib.rs | 31 +++++++++++++++++++++++++++++++ crates/bevy_ecs/src/world/mod.rs | 15 ++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 102df951f89a0..9374cdd935d06 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -1263,6 +1263,37 @@ mod tests { assert_eq!(world.resource::().0, 1); } + #[test] + fn non_send_resource_scope() { + let mut world = World::default(); + world.insert_non_send_resource(A(0)); + world.resource_scope(|world: &mut World, mut value: Mut| { + value.0 += 1; + assert!(!world.contains_resource::()); + }); + assert_eq!(world.non_send_resource::().0, 1); + } + + #[test] + #[should_panic] + fn non_send_resource_scope_from_different_thread() { + let mut world = World::default(); + world.insert_non_send_resource(A(0)); + + std::thread::scope(|s| { + s.spawn(|| { + // Accessing the non-send resource on a different thread + // Should result in a panic + world.resource_scope(|world: &mut World, mut value: Mut| { + value.0 += 1; + assert!(!world.contains_resource::()); + }); + }); + }); + + assert_eq!(world.get_non_send_resource::().unwrap().0, 1); + } + #[test] fn insert_overwrite_drop() { let (dropck1, dropped1) = DropCk::new_pair(); diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 914046526af12..128c5e8dcf094 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -1149,7 +1149,13 @@ impl World { /// }); /// assert_eq!(world.get_resource::().unwrap().0, 2); /// ``` - pub fn resource_scope(&mut self, f: impl FnOnce(&mut World, Mut) -> U) -> U { + pub fn resource_scope< + R: 'static, /* The resource doesn't need to be Send nor Sync. */ + U, + >( + &mut self, + f: impl FnOnce(&mut World, Mut) -> U, + ) -> U { let last_change_tick = self.last_change_tick(); let change_tick = self.change_tick(); @@ -1157,6 +1163,13 @@ impl World { .components .get_resource_id(TypeId::of::()) .unwrap_or_else(|| panic!("resource does not exist: {}", std::any::type_name::())); + + // If the resource isn't send and sync, validate that we are on the main thread, so that we can access it. + let component_info = self.components().get_info(component_id).unwrap(); + if !component_info.is_send_and_sync() { + self.validate_non_send_access::(); + } + let (ptr, mut ticks) = { let resource_archetype = self.archetypes.resource_mut(); let unique_components = resource_archetype.unique_components_mut(); From 83f241771cdd671ae6e13fe1f7879b62886918b3 Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Tue, 27 Sep 2022 21:31:37 +0200 Subject: [PATCH 02/21] fixed the non-send resource scope tests --- crates/bevy_ecs/src/lib.rs | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index b695ea91049e1..f04b4a5da8aa3 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -69,6 +69,7 @@ mod tests { atomic::{AtomicUsize, Ordering}, Arc, Mutex, }, + marker::PhantomData, }; #[derive(Component, Resource, Debug, PartialEq, Eq, Clone, Copy)] @@ -78,6 +79,9 @@ mod tests { #[derive(Component, Debug, PartialEq, Eq, Clone, Copy)] struct C; + #[derive(Default)] + struct NonSend(usize, PhantomData<*mut ()>); + #[derive(Component, Clone, Debug)] struct DropCk(Arc); impl DropCk { @@ -1265,32 +1269,31 @@ mod tests { #[test] fn non_send_resource_scope() { let mut world = World::default(); - world.insert_non_send_resource(A(0)); - world.resource_scope(|world: &mut World, mut value: Mut| { + world.insert_non_send_resource(NonSend::default()); + world.resource_scope(|world: &mut World, mut value: Mut| { value.0 += 1; - assert!(!world.contains_resource::()); + assert!(!world.contains_resource::()); }); - assert_eq!(world.non_send_resource::().0, 1); + assert_eq!(world.non_send_resource::().0, 1); } #[test] - #[should_panic] + #[should_panic(expected = "attempted to access NonSend resource bevy_ecs::tests::NonSend off of the main thread")] fn non_send_resource_scope_from_different_thread() { let mut world = World::default(); - world.insert_non_send_resource(A(0)); - - std::thread::scope(|s| { - s.spawn(|| { - // Accessing the non-send resource on a different thread - // Should result in a panic - world.resource_scope(|world: &mut World, mut value: Mut| { - value.0 += 1; - assert!(!world.contains_resource::()); - }); + world.insert_non_send_resource(NonSend::default()); + + let thread = std::thread::spawn(move || { + // Accessing the non-send resource on a different thread + // Should result in a panic + world.resource_scope(|_: &mut World, mut value: Mut| { + value.0 += 1; }); }); - assert_eq!(world.get_non_send_resource::().unwrap().0, 1); + if let Err(err) = thread.join() { + panic!("{}", err.downcast::().unwrap()); + } } #[test] From 6da0e41d5eb02e78175f74dcf2287ab355889d2f Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Tue, 27 Sep 2022 22:56:06 +0200 Subject: [PATCH 03/21] formatting --- crates/bevy_ecs/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index f04b4a5da8aa3..5fae64cfcad60 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -65,11 +65,11 @@ mod tests { use bevy_tasks::{ComputeTaskPool, TaskPool}; use std::{ any::TypeId, + marker::PhantomData, sync::{ atomic::{AtomicUsize, Ordering}, Arc, Mutex, }, - marker::PhantomData, }; #[derive(Component, Resource, Debug, PartialEq, Eq, Clone, Copy)] @@ -1278,7 +1278,9 @@ mod tests { } #[test] - #[should_panic(expected = "attempted to access NonSend resource bevy_ecs::tests::NonSend off of the main thread")] + #[should_panic( + expected = "attempted to access NonSend resource bevy_ecs::tests::NonSend off of the main thread" + )] fn non_send_resource_scope_from_different_thread() { let mut world = World::default(); world.insert_non_send_resource(NonSend::default()); From 3500039d02175084bbbb66e597e6d758d80013d6 Mon Sep 17 00:00:00 2001 From: Dawid Piotrowski <41804418+Pietrek14@users.noreply.github.com> Date: Wed, 28 Sep 2022 11:10:24 +0200 Subject: [PATCH 04/21] simplified panic in a non-send resource scope test Co-authored-by: Mike --- crates/bevy_ecs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 5fae64cfcad60..3e9ebde63a961 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -1294,7 +1294,7 @@ mod tests { }); if let Err(err) = thread.join() { - panic!("{}", err.downcast::().unwrap()); + std::panic::resume_unwind(err); } } From f68eb33f42c0124010cd49a09986a553b0451b4d Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Wed, 28 Sep 2022 12:16:53 +0200 Subject: [PATCH 05/21] changed the name of non-send struct used for testing --- crates/bevy_ecs/src/lib.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 3e9ebde63a961..6143036737dbb 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -80,7 +80,7 @@ mod tests { struct C; #[derive(Default)] - struct NonSend(usize, PhantomData<*mut ()>); + struct NonSendA(usize, PhantomData<*mut ()>); #[derive(Component, Clone, Debug)] struct DropCk(Arc); @@ -1269,26 +1269,26 @@ mod tests { #[test] fn non_send_resource_scope() { let mut world = World::default(); - world.insert_non_send_resource(NonSend::default()); - world.resource_scope(|world: &mut World, mut value: Mut| { + world.insert_non_send_resource(NonSendA::default()); + world.resource_scope(|world: &mut World, mut value: Mut| { value.0 += 1; - assert!(!world.contains_resource::()); + assert!(!world.contains_resource::()); }); - assert_eq!(world.non_send_resource::().0, 1); + assert_eq!(world.non_send_resource::().0, 1); } #[test] #[should_panic( - expected = "attempted to access NonSend resource bevy_ecs::tests::NonSend off of the main thread" + expected = "attempted to access NonSend resource bevy_ecs::tests::NonSendA off of the main thread" )] fn non_send_resource_scope_from_different_thread() { let mut world = World::default(); - world.insert_non_send_resource(NonSend::default()); + world.insert_non_send_resource(NonSendA::default()); let thread = std::thread::spawn(move || { // Accessing the non-send resource on a different thread // Should result in a panic - world.resource_scope(|_: &mut World, mut value: Mut| { + world.resource_scope(|_: &mut World, mut value: Mut| { value.0 += 1; }); }); From 56a5dd76249a43f8d6d39c8ef49d52d0f302a07f Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Thu, 29 Sep 2022 18:22:57 +0200 Subject: [PATCH 06/21] added arithmetic functions for Val --- crates/bevy_ui/src/ui_node.rs | 196 ++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index a8d3776e01f8f..08fdcff0c0672 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -8,6 +8,7 @@ use bevy_render::{ color::Color, texture::{Image, DEFAULT_IMAGE_HANDLE}, }; +use bevy_utils::tracing::warn; use serde::{Deserialize, Serialize}; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; @@ -122,6 +123,83 @@ impl DivAssign for Val { } } +#[derive(Debug, Eq, PartialEq)] +pub enum ValArithmeticError { + NonIdenticalVariants, + NonEvaluateable, +} + +impl Val { + /// Tries to add the values of two [`Val`]s. + /// Returns [`ValArithmeticError::NonIdenticalVariants`] if two [`Val`]s are of different variants. + /// When adding non-numeric [`Val`]s, it returns the value unchanged. + pub fn try_add(&self, rhs: Val) -> Result { + match (self, rhs) { + (Val::Undefined, Val::Undefined) => { + warn!("Adding to Val::Undefined is a redundant operation"); + Ok(*self) + } + (Val::Auto, Val::Auto) => { + warn!("Adding to Val::Auto is a redundant operation"); + Ok(*self) + } + (Val::Px(value), Val::Px(rhs_value)) => Ok(Val::Px(value + rhs_value)), + (Val::Percent(value), Val::Percent(rhs_value)) => Ok(Val::Percent(value + rhs_value)), + _ => Err(ValArithmeticError::NonIdenticalVariants), + } + } + + /// Tries to subtract the values of two [`Val`]s. + /// Returns [`ValArithmeticError::NonIdenticalVariants`] if two [`Val`]s are of different variants. + /// When adding non-numeric [`Val`]s, it returns the value unchanged. + pub fn try_sub(&self, rhs: Val) -> Result { + match (self, rhs) { + (Val::Undefined, Val::Undefined) => { + warn!("Subtracting from Val::Undefined is a redundant operation"); + Ok(*self) + } + (Val::Auto, Val::Auto) => { + warn!("Subtracting from Val::Auto is a redundant operation"); + Ok(*self) + } + (Val::Px(value), Val::Px(rhs_value)) => Ok(Val::Px(value - rhs_value)), + (Val::Percent(value), Val::Percent(rhs_value)) => Ok(Val::Percent(value - rhs_value)), + _ => Err(ValArithmeticError::NonIdenticalVariants), + } + } + + /// A convenience function for simple evaluation of [`Val::Percent`] variant into a concrete [`Val::Px`] value. + /// Returns a [`ValArithmeticError::NonEvaluateable`] if the [`Val`] is impossible to evaluate into [`Val::Px`]. + /// Otherwise it returns a [`Val::Px`] containing the evaluated value. + /// + /// **Note:** If a [`Val::Px`] value is evaluated, it's returned unchanged. + pub fn evaluate(&self, size: f32) -> Result { + match self { + Val::Percent(value) => Ok(Val::Px(size * value / 100.0)), + Val::Px(_) => Ok(*self), + _ => Err(ValArithmeticError::NonEvaluateable), + } + } + + /// Similar to [`Val::try_add`], but performs [`Val::evaluate`] on both values before adding. + /// Both values have to be evaluatable (numeric). + pub fn try_add_with_size(&self, rhs: Val, size: f32) -> Result { + let lhs = self.evaluate(size)?; + let rhs = rhs.evaluate(size)?; + + lhs.try_add(rhs) + } + + /// Similar to [`Val::try_sub`], but performs [`Val::evaluate`] on both values before subtracting. + /// Both values have to be evaluatable (numeric). + pub fn try_sub_with_size(&self, rhs: Val, size: f32) -> Result { + let lhs = self.evaluate(size)?; + let rhs = rhs.evaluate(size)?; + + lhs.try_sub(rhs) + } +} + /// Describes the style of a UI node /// /// It uses the [Flexbox](https://cssreference.io/flexbox/) system. @@ -413,3 +491,121 @@ pub struct CalculatedClip { /// The rect of the clip pub clip: Rect, } + +#[cfg(test)] +mod tests { + use crate::ValArithmeticError; + + use super::Val; + + #[test] + fn val_try_add() { + let undefined_sum = Val::Undefined.try_add(Val::Undefined).unwrap(); + let auto_sum = Val::Auto.try_add(Val::Auto).unwrap(); + let px_sum = Val::Px(20.).try_add(Val::Px(22.)).unwrap(); + let percent_sum = Val::Percent(50.).try_add(Val::Percent(50.)).unwrap(); + + assert_eq!(undefined_sum, Val::Undefined); + assert_eq!(auto_sum, Val::Auto); + assert_eq!(px_sum, Val::Px(42.)); + assert_eq!(percent_sum, Val::Percent(100.)); + } + + #[test] + fn val_try_sub() { + let undefined_sum = Val::Undefined.try_sub(Val::Undefined).unwrap(); + let auto_sum = Val::Auto.try_sub(Val::Auto).unwrap(); + let px_sum = Val::Px(72.).try_sub(Val::Px(30.)).unwrap(); + let percent_sum = Val::Percent(100.).try_sub(Val::Percent(50.)).unwrap(); + + assert_eq!(undefined_sum, Val::Undefined); + assert_eq!(auto_sum, Val::Auto); + assert_eq!(px_sum, Val::Px(42.)); + assert_eq!(percent_sum, Val::Percent(50.)); + } + + #[test] + fn different_variant_val_try_add() { + let different_variant_sum_1 = Val::Undefined.try_add(Val::Auto); + let different_variant_sum_2 = Val::Px(50.).try_add(Val::Percent(50.)); + let different_variant_sum_3 = Val::Percent(50.).try_add(Val::Undefined); + + assert_eq!(different_variant_sum_1, Err(ValArithmeticError::NonIdenticalVariants)); + assert_eq!(different_variant_sum_2, Err(ValArithmeticError::NonIdenticalVariants)); + assert_eq!(different_variant_sum_3, Err(ValArithmeticError::NonIdenticalVariants)); + } + + #[test] + fn different_variant_val_try_sub() { + let different_variant_diff_1 = Val::Undefined.try_sub(Val::Auto); + let different_variant_diff_2 = Val::Px(50.).try_sub(Val::Percent(50.)); + let different_variant_diff_3 = Val::Percent(50.).try_sub(Val::Undefined); + + assert_eq!(different_variant_diff_1, Err(ValArithmeticError::NonIdenticalVariants)); + assert_eq!(different_variant_diff_2, Err(ValArithmeticError::NonIdenticalVariants)); + assert_eq!(different_variant_diff_3, Err(ValArithmeticError::NonIdenticalVariants)); + } + + #[test] + fn val_evaluate() { + let size = 250.; + let result = Val::Percent(80.).evaluate(size).unwrap(); + + assert_eq!(result, Val::Px(size * 0.8)); + } + + #[test] + fn val_evaluate_px() { + let size = 250.; + let result = Val::Px(10.).evaluate(size).unwrap(); + + assert_eq!(result, Val::Px(10.)); + } + + #[test] + fn val_invalid_evaluation() { + let size = 250.; + let evaluate_undefined = Val::Undefined.evaluate(size); + let evaluate_auto = Val::Auto.evaluate(size); + + assert_eq!(evaluate_undefined, Err(ValArithmeticError::NonEvaluateable)); + assert_eq!(evaluate_auto, Err(ValArithmeticError::NonEvaluateable)); + } + + #[test] + fn val_try_add_with_size() { + let size = 250.; + + let px_sum = Val::Px(21.).try_add_with_size(Val::Px(21.), size).unwrap(); + let percent_sum = Val::Percent(20.).try_add_with_size(Val::Percent(30.), size).unwrap(); + let mixed_sum = Val::Px(20.).try_add_with_size(Val::Percent(30.), size).unwrap(); + + assert_eq!(px_sum, Val::Px(42.)); + assert_eq!(percent_sum, Val::Px(0.5 * size)); + assert_eq!(mixed_sum, Val::Px(20. + 0.3 * size)); + } + + #[test] + fn val_try_sub_with_size() { + let size = 250.; + + let px_sum = Val::Px(60.).try_sub_with_size(Val::Px(18.), size).unwrap(); + let percent_sum = Val::Percent(80.).try_sub_with_size(Val::Percent(30.), size).unwrap(); + let mixed_sum = Val::Percent(50.).try_sub_with_size(Val::Px(30.), size).unwrap(); + + assert_eq!(px_sum, Val::Px(42.)); + assert_eq!(percent_sum, Val::Px(0.5 * size)); + assert_eq!(mixed_sum, Val::Px(0.5 * size - 30.)); + } + + #[test] + fn val_try_add_non_numeric_with_size() { + let size = 250.; + + let undefined_sum = Val::Undefined.try_add_with_size(Val::Undefined, size); + let percent_sum = Val::Auto.try_add_with_size(Val::Auto, size); + + assert_eq!(undefined_sum, Err(ValArithmeticError::NonEvaluateable)); + assert_eq!(percent_sum, Err(ValArithmeticError::NonEvaluateable)); + } +} \ No newline at end of file From ad9da5f1c716342d07e8c6e4aab54ee593288371 Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Thu, 29 Sep 2022 20:07:38 +0200 Subject: [PATCH 07/21] removed adding and subtracting of val with f32 --- crates/bevy_ui/src/geometry.rs | 41 ++++++------ crates/bevy_ui/src/ui_node.rs | 115 +++++++++++++++++---------------- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/crates/bevy_ui/src/geometry.rs b/crates/bevy_ui/src/geometry.rs index 13c8de3bbc7ce..402dcfae9926c 100644 --- a/crates/bevy_ui/src/geometry.rs +++ b/crates/bevy_ui/src/geometry.rs @@ -1,5 +1,4 @@ use crate::Val; -use bevy_math::Vec2; use bevy_reflect::Reflect; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; @@ -356,39 +355,39 @@ impl Size { }; } -impl Add for Size { +impl Add<(Val, Val)> for Size { type Output = Size; - fn add(self, rhs: Vec2) -> Self::Output { + fn add(self, rhs: (Val, Val)) -> Self::Output { Self { - width: self.width + rhs.x, - height: self.height + rhs.y, + width: self.width.try_add(rhs.0).unwrap(), + height: self.height.try_add(rhs.1).unwrap(), } } } -impl AddAssign for Size { - fn add_assign(&mut self, rhs: Vec2) { - self.width += rhs.x; - self.height += rhs.y; +impl AddAssign<(Val, Val)> for Size { + fn add_assign(&mut self, rhs: (Val, Val)) { + self.width.try_add_to_self(rhs.0).unwrap(); + self.height.try_add_to_self(rhs.1).unwrap(); } } -impl Sub for Size { +impl Sub<(Val, Val)> for Size { type Output = Size; - fn sub(self, rhs: Vec2) -> Self::Output { + fn sub(self, rhs: (Val, Val)) -> Self::Output { Self { - width: self.width - rhs.x, - height: self.height - rhs.y, + width: self.width.try_sub(rhs.0).unwrap(), + height: self.height.try_sub(rhs.1).unwrap(), } } } -impl SubAssign for Size { - fn sub_assign(&mut self, rhs: Vec2) { - self.width -= rhs.x; - self.height -= rhs.y; +impl SubAssign<(Val, Val)> for Size { + fn sub_assign(&mut self, rhs: (Val, Val)) { + self.width.try_sub_from_self(rhs.0).unwrap(); + self.height.try_sub_from_self(rhs.1).unwrap(); } } @@ -435,24 +434,24 @@ mod tests { #[test] fn test_size_add() { assert_eq!( - Size::new(Val::Px(10.), Val::Px(10.)) + Vec2::new(10., 10.), + Size::new(Val::Px(10.), Val::Px(10.)) + (Val::Px(10.), Val::Px(10.)), Size::new(Val::Px(20.), Val::Px(20.)) ); let mut size = Size::new(Val::Px(10.), Val::Px(10.)); - size += Vec2::new(10., 10.); + size += (Val::Px(10.), Val::Px(10.)); assert_eq!(size, Size::new(Val::Px(20.), Val::Px(20.))); } #[test] fn test_size_sub() { assert_eq!( - Size::new(Val::Px(20.), Val::Px(20.)) - Vec2::new(10., 10.), + Size::new(Val::Px(20.), Val::Px(20.)) - (Val::Px(10.), Val::Px(10.)), Size::new(Val::Px(10.), Val::Px(10.)) ); let mut size = Size::new(Val::Px(20.), Val::Px(20.)); - size -= Vec2::new(10., 10.); + size -= (Val::Px(10.), Val::Px(10.)); assert_eq!(size, Size::new(Val::Px(10.), Val::Px(10.))); } diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 08fdcff0c0672..6dea16a454c0e 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -10,7 +10,7 @@ use bevy_render::{ }; use bevy_utils::tracing::warn; use serde::{Deserialize, Serialize}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; +use std::ops::{Div, DivAssign, Mul, MulAssign}; /// Describes the size of a UI node #[derive(Component, Debug, Clone, Default, Reflect)] @@ -35,50 +35,6 @@ pub enum Val { Percent(f32), } -impl Add for Val { - type Output = Val; - - fn add(self, rhs: f32) -> Self::Output { - match self { - Val::Undefined => Val::Undefined, - Val::Auto => Val::Auto, - Val::Px(value) => Val::Px(value + rhs), - Val::Percent(value) => Val::Percent(value + rhs), - } - } -} - -impl AddAssign for Val { - fn add_assign(&mut self, rhs: f32) { - match self { - Val::Undefined | Val::Auto => {} - Val::Px(value) | Val::Percent(value) => *value += rhs, - } - } -} - -impl Sub for Val { - type Output = Val; - - fn sub(self, rhs: f32) -> Self::Output { - match self { - Val::Undefined => Val::Undefined, - Val::Auto => Val::Auto, - Val::Px(value) => Val::Px(value - rhs), - Val::Percent(value) => Val::Percent(value - rhs), - } - } -} - -impl SubAssign for Val { - fn sub_assign(&mut self, rhs: f32) { - match self { - Val::Undefined | Val::Auto => {} - Val::Px(value) | Val::Percent(value) => *value -= rhs, - } - } -} - impl Mul for Val { type Output = Val; @@ -149,6 +105,11 @@ impl Val { } } + pub fn try_add_to_self(&mut self, rhs: Val) -> Result<(), ValArithmeticError> { + *self = self.try_add(rhs)?; + Ok(()) + } + /// Tries to subtract the values of two [`Val`]s. /// Returns [`ValArithmeticError::NonIdenticalVariants`] if two [`Val`]s are of different variants. /// When adding non-numeric [`Val`]s, it returns the value unchanged. @@ -168,10 +129,15 @@ impl Val { } } + pub fn try_sub_from_self(&mut self, rhs: Val) -> Result<(), ValArithmeticError> { + *self = self.try_sub(rhs)?; + Ok(()) + } + /// A convenience function for simple evaluation of [`Val::Percent`] variant into a concrete [`Val::Px`] value. /// Returns a [`ValArithmeticError::NonEvaluateable`] if the [`Val`] is impossible to evaluate into [`Val::Px`]. /// Otherwise it returns a [`Val::Px`] containing the evaluated value. - /// + /// /// **Note:** If a [`Val::Px`] value is evaluated, it's returned unchanged. pub fn evaluate(&self, size: f32) -> Result { match self { @@ -511,6 +477,15 @@ mod tests { assert_eq!(percent_sum, Val::Percent(100.)); } + #[test] + fn val_try_add_to_self() { + let mut val = Val::Px(5.); + + val.try_add_to_self(Val::Px(3.)).unwrap(); + + assert_eq!(val, Val::Px(8.)); + } + #[test] fn val_try_sub() { let undefined_sum = Val::Undefined.try_sub(Val::Undefined).unwrap(); @@ -530,9 +505,18 @@ mod tests { let different_variant_sum_2 = Val::Px(50.).try_add(Val::Percent(50.)); let different_variant_sum_3 = Val::Percent(50.).try_add(Val::Undefined); - assert_eq!(different_variant_sum_1, Err(ValArithmeticError::NonIdenticalVariants)); - assert_eq!(different_variant_sum_2, Err(ValArithmeticError::NonIdenticalVariants)); - assert_eq!(different_variant_sum_3, Err(ValArithmeticError::NonIdenticalVariants)); + assert_eq!( + different_variant_sum_1, + Err(ValArithmeticError::NonIdenticalVariants) + ); + assert_eq!( + different_variant_sum_2, + Err(ValArithmeticError::NonIdenticalVariants) + ); + assert_eq!( + different_variant_sum_3, + Err(ValArithmeticError::NonIdenticalVariants) + ); } #[test] @@ -541,9 +525,18 @@ mod tests { let different_variant_diff_2 = Val::Px(50.).try_sub(Val::Percent(50.)); let different_variant_diff_3 = Val::Percent(50.).try_sub(Val::Undefined); - assert_eq!(different_variant_diff_1, Err(ValArithmeticError::NonIdenticalVariants)); - assert_eq!(different_variant_diff_2, Err(ValArithmeticError::NonIdenticalVariants)); - assert_eq!(different_variant_diff_3, Err(ValArithmeticError::NonIdenticalVariants)); + assert_eq!( + different_variant_diff_1, + Err(ValArithmeticError::NonIdenticalVariants) + ); + assert_eq!( + different_variant_diff_2, + Err(ValArithmeticError::NonIdenticalVariants) + ); + assert_eq!( + different_variant_diff_3, + Err(ValArithmeticError::NonIdenticalVariants) + ); } #[test] @@ -577,8 +570,12 @@ mod tests { let size = 250.; let px_sum = Val::Px(21.).try_add_with_size(Val::Px(21.), size).unwrap(); - let percent_sum = Val::Percent(20.).try_add_with_size(Val::Percent(30.), size).unwrap(); - let mixed_sum = Val::Px(20.).try_add_with_size(Val::Percent(30.), size).unwrap(); + let percent_sum = Val::Percent(20.) + .try_add_with_size(Val::Percent(30.), size) + .unwrap(); + let mixed_sum = Val::Px(20.) + .try_add_with_size(Val::Percent(30.), size) + .unwrap(); assert_eq!(px_sum, Val::Px(42.)); assert_eq!(percent_sum, Val::Px(0.5 * size)); @@ -590,8 +587,12 @@ mod tests { let size = 250.; let px_sum = Val::Px(60.).try_sub_with_size(Val::Px(18.), size).unwrap(); - let percent_sum = Val::Percent(80.).try_sub_with_size(Val::Percent(30.), size).unwrap(); - let mixed_sum = Val::Percent(50.).try_sub_with_size(Val::Px(30.), size).unwrap(); + let percent_sum = Val::Percent(80.) + .try_sub_with_size(Val::Percent(30.), size) + .unwrap(); + let mixed_sum = Val::Percent(50.) + .try_sub_with_size(Val::Px(30.), size) + .unwrap(); assert_eq!(px_sum, Val::Px(42.)); assert_eq!(percent_sum, Val::Px(0.5 * size)); @@ -608,4 +609,4 @@ mod tests { assert_eq!(undefined_sum, Err(ValArithmeticError::NonEvaluateable)); assert_eq!(percent_sum, Err(ValArithmeticError::NonEvaluateable)); } -} \ No newline at end of file +} From c9dfd369141c4c0315e562eb1767969edf8ae348 Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Sat, 1 Oct 2022 21:50:24 +0200 Subject: [PATCH 08/21] changed the names of val methods to be more in line with the standard api and added add/sub assigning with size --- crates/bevy_ui/src/geometry.rs | 8 ++++---- crates/bevy_ui/src/ui_node.rs | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/crates/bevy_ui/src/geometry.rs b/crates/bevy_ui/src/geometry.rs index 402dcfae9926c..e122ae458942e 100644 --- a/crates/bevy_ui/src/geometry.rs +++ b/crates/bevy_ui/src/geometry.rs @@ -368,8 +368,8 @@ impl Add<(Val, Val)> for Size { impl AddAssign<(Val, Val)> for Size { fn add_assign(&mut self, rhs: (Val, Val)) { - self.width.try_add_to_self(rhs.0).unwrap(); - self.height.try_add_to_self(rhs.1).unwrap(); + self.width.try_add_assign(rhs.0).unwrap(); + self.height.try_add_assign(rhs.1).unwrap(); } } @@ -386,8 +386,8 @@ impl Sub<(Val, Val)> for Size { impl SubAssign<(Val, Val)> for Size { fn sub_assign(&mut self, rhs: (Val, Val)) { - self.width.try_sub_from_self(rhs.0).unwrap(); - self.height.try_sub_from_self(rhs.1).unwrap(); + self.width.try_sub_assign(rhs.0).unwrap(); + self.height.try_sub_assign(rhs.1).unwrap(); } } diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 6dea16a454c0e..5a8009e6a2922 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -105,7 +105,7 @@ impl Val { } } - pub fn try_add_to_self(&mut self, rhs: Val) -> Result<(), ValArithmeticError> { + pub fn try_add_assign(&mut self, rhs: Val) -> Result<(), ValArithmeticError> { *self = self.try_add(rhs)?; Ok(()) } @@ -129,7 +129,7 @@ impl Val { } } - pub fn try_sub_from_self(&mut self, rhs: Val) -> Result<(), ValArithmeticError> { + pub fn try_sub_assign(&mut self, rhs: Val) -> Result<(), ValArithmeticError> { *self = self.try_sub(rhs)?; Ok(()) } @@ -156,6 +156,13 @@ impl Val { lhs.try_add(rhs) } + /// Similar to [`Val::try_add_assign`], but performs [`Val::evaluate`] on both values before adding. + /// Both values have to be evaluatable (numeric). + pub fn try_add_assign_with_size(&mut self, rhs: Val, size: f32) -> Result<(), ValArithmeticError> { + *self = self.try_add_with_size(rhs, size)?; + Ok(()) + } + /// Similar to [`Val::try_sub`], but performs [`Val::evaluate`] on both values before subtracting. /// Both values have to be evaluatable (numeric). pub fn try_sub_with_size(&self, rhs: Val, size: f32) -> Result { @@ -164,6 +171,13 @@ impl Val { lhs.try_sub(rhs) } + + /// Similar to [`Val::try_sub_assign`], but performs [`Val::evaluate`] on both values before adding. + /// Both values have to be evaluatable (numeric). + pub fn try_sub_assign_with_size(&mut self, rhs: Val, size: f32) -> Result<(), ValArithmeticError> { + *self = self.try_add_with_size(rhs, size)?; + Ok(()) + } } /// Describes the style of a UI node @@ -481,7 +495,7 @@ mod tests { fn val_try_add_to_self() { let mut val = Val::Px(5.); - val.try_add_to_self(Val::Px(3.)).unwrap(); + val.try_add_assign(Val::Px(3.)).unwrap(); assert_eq!(val, Val::Px(8.)); } From cb577bc90cb414486365fc27abed7dd22843fdcc Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Sat, 1 Oct 2022 21:53:39 +0200 Subject: [PATCH 09/21] formatting --- crates/bevy_ui/src/ui_node.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 5a8009e6a2922..6851ff4899e93 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -158,7 +158,11 @@ impl Val { /// Similar to [`Val::try_add_assign`], but performs [`Val::evaluate`] on both values before adding. /// Both values have to be evaluatable (numeric). - pub fn try_add_assign_with_size(&mut self, rhs: Val, size: f32) -> Result<(), ValArithmeticError> { + pub fn try_add_assign_with_size( + &mut self, + rhs: Val, + size: f32, + ) -> Result<(), ValArithmeticError> { *self = self.try_add_with_size(rhs, size)?; Ok(()) } @@ -174,7 +178,11 @@ impl Val { /// Similar to [`Val::try_sub_assign`], but performs [`Val::evaluate`] on both values before adding. /// Both values have to be evaluatable (numeric). - pub fn try_sub_assign_with_size(&mut self, rhs: Val, size: f32) -> Result<(), ValArithmeticError> { + pub fn try_sub_assign_with_size( + &mut self, + rhs: Val, + size: f32, + ) -> Result<(), ValArithmeticError> { *self = self.try_add_with_size(rhs, size)?; Ok(()) } From 1fb60498de4fdaaf155bed42ef2fa0f009999621 Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Tue, 4 Oct 2022 21:46:52 +0200 Subject: [PATCH 10/21] deleted warnings from Val::try_add and Val::try_sub --- crates/bevy_ui/src/ui_node.rs | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 6851ff4899e93..21ab7229aa1a2 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -91,14 +91,8 @@ impl Val { /// When adding non-numeric [`Val`]s, it returns the value unchanged. pub fn try_add(&self, rhs: Val) -> Result { match (self, rhs) { - (Val::Undefined, Val::Undefined) => { - warn!("Adding to Val::Undefined is a redundant operation"); - Ok(*self) - } - (Val::Auto, Val::Auto) => { - warn!("Adding to Val::Auto is a redundant operation"); - Ok(*self) - } + (Val::Undefined, Val::Undefined) => Ok(*self), + (Val::Auto, Val::Auto) => Ok(*self), (Val::Px(value), Val::Px(rhs_value)) => Ok(Val::Px(value + rhs_value)), (Val::Percent(value), Val::Percent(rhs_value)) => Ok(Val::Percent(value + rhs_value)), _ => Err(ValArithmeticError::NonIdenticalVariants), @@ -115,14 +109,8 @@ impl Val { /// When adding non-numeric [`Val`]s, it returns the value unchanged. pub fn try_sub(&self, rhs: Val) -> Result { match (self, rhs) { - (Val::Undefined, Val::Undefined) => { - warn!("Subtracting from Val::Undefined is a redundant operation"); - Ok(*self) - } - (Val::Auto, Val::Auto) => { - warn!("Subtracting from Val::Auto is a redundant operation"); - Ok(*self) - } + (Val::Undefined, Val::Undefined) => Ok(*self), + (Val::Auto, Val::Auto) => Ok(*self), (Val::Px(value), Val::Px(rhs_value)) => Ok(Val::Px(value - rhs_value)), (Val::Percent(value), Val::Percent(rhs_value)) => Ok(Val::Percent(value - rhs_value)), _ => Err(ValArithmeticError::NonIdenticalVariants), From 7b3328216648d7db92e950fa2fd60a0a159d884e Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Tue, 4 Oct 2022 21:48:21 +0200 Subject: [PATCH 11/21] deleted unnecessary use --- crates/bevy_ui/src/ui_node.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 21ab7229aa1a2..455237431e6ef 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -8,7 +8,6 @@ use bevy_render::{ color::Color, texture::{Image, DEFAULT_IMAGE_HANDLE}, }; -use bevy_utils::tracing::warn; use serde::{Deserialize, Serialize}; use std::ops::{Div, DivAssign, Mul, MulAssign}; From bd2240f0a4a6f9098133a2d7ee54b0d25e73178d Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Tue, 4 Oct 2022 23:15:00 +0200 Subject: [PATCH 12/21] Val::evaluate returns f32 --- crates/bevy_ui/src/ui_node.rs | 46 +++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 455237431e6ef..3a4c0bce4ec91 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -123,54 +123,54 @@ impl Val { /// A convenience function for simple evaluation of [`Val::Percent`] variant into a concrete [`Val::Px`] value. /// Returns a [`ValArithmeticError::NonEvaluateable`] if the [`Val`] is impossible to evaluate into [`Val::Px`]. - /// Otherwise it returns a [`Val::Px`] containing the evaluated value. + /// Otherwise it returns an [`f32`] containing the evaluated value in pixels. /// - /// **Note:** If a [`Val::Px`] value is evaluated, it's returned unchanged. - pub fn evaluate(&self, size: f32) -> Result { + /// **Note:** If a [`Val::Px`] is evaluated, it's innver value returned unchanged. + pub fn evaluate(&self, size: f32) -> Result { match self { - Val::Percent(value) => Ok(Val::Px(size * value / 100.0)), - Val::Px(_) => Ok(*self), + Val::Percent(value) => Ok(size * value / 100.0), + Val::Px(value) => Ok(*value), _ => Err(ValArithmeticError::NonEvaluateable), } } /// Similar to [`Val::try_add`], but performs [`Val::evaluate`] on both values before adding. - /// Both values have to be evaluatable (numeric). - pub fn try_add_with_size(&self, rhs: Val, size: f32) -> Result { + /// Returns an [`f32`] value in pixels. + pub fn try_add_with_size(&self, rhs: Val, size: f32) -> Result { let lhs = self.evaluate(size)?; let rhs = rhs.evaluate(size)?; - lhs.try_add(rhs) + Ok(lhs + rhs) } /// Similar to [`Val::try_add_assign`], but performs [`Val::evaluate`] on both values before adding. - /// Both values have to be evaluatable (numeric). + /// [`self`] gets converted to [`Val::Px`]. pub fn try_add_assign_with_size( &mut self, rhs: Val, size: f32, ) -> Result<(), ValArithmeticError> { - *self = self.try_add_with_size(rhs, size)?; + *self = Val::Px(self.evaluate(size)? + rhs.evaluate(size)?); Ok(()) } /// Similar to [`Val::try_sub`], but performs [`Val::evaluate`] on both values before subtracting. - /// Both values have to be evaluatable (numeric). - pub fn try_sub_with_size(&self, rhs: Val, size: f32) -> Result { + /// Returns an [`f32`] value in pixels. + pub fn try_sub_with_size(&self, rhs: Val, size: f32) -> Result { let lhs = self.evaluate(size)?; let rhs = rhs.evaluate(size)?; - lhs.try_sub(rhs) + Ok(lhs - rhs) } /// Similar to [`Val::try_sub_assign`], but performs [`Val::evaluate`] on both values before adding. - /// Both values have to be evaluatable (numeric). + /// [`self`] gets converted to [`Val::Px`]. pub fn try_sub_assign_with_size( &mut self, rhs: Val, size: f32, ) -> Result<(), ValArithmeticError> { - *self = self.try_add_with_size(rhs, size)?; + *self = Val::Px(self.try_add_with_size(rhs, size)?); Ok(()) } } @@ -553,7 +553,7 @@ mod tests { let size = 250.; let result = Val::Percent(80.).evaluate(size).unwrap(); - assert_eq!(result, Val::Px(size * 0.8)); + assert_eq!(result, size * 0.8); } #[test] @@ -561,7 +561,7 @@ mod tests { let size = 250.; let result = Val::Px(10.).evaluate(size).unwrap(); - assert_eq!(result, Val::Px(10.)); + assert_eq!(result, 10.); } #[test] @@ -586,9 +586,9 @@ mod tests { .try_add_with_size(Val::Percent(30.), size) .unwrap(); - assert_eq!(px_sum, Val::Px(42.)); - assert_eq!(percent_sum, Val::Px(0.5 * size)); - assert_eq!(mixed_sum, Val::Px(20. + 0.3 * size)); + assert_eq!(px_sum, 42.); + assert_eq!(percent_sum, 0.5 * size); + assert_eq!(mixed_sum, 20. + 0.3 * size); } #[test] @@ -603,9 +603,9 @@ mod tests { .try_sub_with_size(Val::Px(30.), size) .unwrap(); - assert_eq!(px_sum, Val::Px(42.)); - assert_eq!(percent_sum, Val::Px(0.5 * size)); - assert_eq!(mixed_sum, Val::Px(0.5 * size - 30.)); + assert_eq!(px_sum, 42.); + assert_eq!(percent_sum, 0.5 * size); + assert_eq!(mixed_sum, 0.5 * size - 30.); } #[test] From 3c577953e690a4f2031e98711aeed0d1bd0c633a Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Tue, 4 Oct 2022 23:21:07 +0200 Subject: [PATCH 13/21] clippy --- crates/bevy_ui/src/ui_node.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 3a4c0bce4ec91..513beb4865bf4 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -90,8 +90,7 @@ impl Val { /// When adding non-numeric [`Val`]s, it returns the value unchanged. pub fn try_add(&self, rhs: Val) -> Result { match (self, rhs) { - (Val::Undefined, Val::Undefined) => Ok(*self), - (Val::Auto, Val::Auto) => Ok(*self), + (Val::Undefined, Val::Undefined) | (Val::Auto, Val::Auto) => Ok(*self), (Val::Px(value), Val::Px(rhs_value)) => Ok(Val::Px(value + rhs_value)), (Val::Percent(value), Val::Percent(rhs_value)) => Ok(Val::Percent(value + rhs_value)), _ => Err(ValArithmeticError::NonIdenticalVariants), @@ -108,8 +107,7 @@ impl Val { /// When adding non-numeric [`Val`]s, it returns the value unchanged. pub fn try_sub(&self, rhs: Val) -> Result { match (self, rhs) { - (Val::Undefined, Val::Undefined) => Ok(*self), - (Val::Auto, Val::Auto) => Ok(*self), + (Val::Undefined, Val::Undefined) | (Val::Auto, Val::Auto) => Ok(*self), (Val::Px(value), Val::Px(rhs_value)) => Ok(Val::Px(value - rhs_value)), (Val::Percent(value), Val::Percent(rhs_value)) => Ok(Val::Percent(value - rhs_value)), _ => Err(ValArithmeticError::NonIdenticalVariants), From e039468fc9b3330d72a11fa9384a91c56fccf481 Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Tue, 4 Oct 2022 23:27:41 +0200 Subject: [PATCH 14/21] added docs for Add and Subs impls for Size struct --- crates/bevy_ui/src/geometry.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/bevy_ui/src/geometry.rs b/crates/bevy_ui/src/geometry.rs index e122ae458942e..542a6227ef2cb 100644 --- a/crates/bevy_ui/src/geometry.rs +++ b/crates/bevy_ui/src/geometry.rs @@ -358,6 +358,10 @@ impl Size { impl Add<(Val, Val)> for Size { type Output = Size; + /// Adds ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. + /// + /// # Panics + /// If the [`Val`]s can't be added correctly (if they are of different variants). fn add(self, rhs: (Val, Val)) -> Self::Output { Self { width: self.width.try_add(rhs.0).unwrap(), @@ -367,6 +371,10 @@ impl Add<(Val, Val)> for Size { } impl AddAssign<(Val, Val)> for Size { + /// Add-assigns ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. + /// + /// # Panics + /// If the [`Val`]s can't be added correctly (if they are of different variants). fn add_assign(&mut self, rhs: (Val, Val)) { self.width.try_add_assign(rhs.0).unwrap(); self.height.try_add_assign(rhs.1).unwrap(); @@ -376,6 +384,10 @@ impl AddAssign<(Val, Val)> for Size { impl Sub<(Val, Val)> for Size { type Output = Size; + /// Subtracts ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. + /// + /// # Panics + /// If the [`Val`]s can't be subtracted correctly (if they are of different variants). fn sub(self, rhs: (Val, Val)) -> Self::Output { Self { width: self.width.try_sub(rhs.0).unwrap(), @@ -385,6 +397,10 @@ impl Sub<(Val, Val)> for Size { } impl SubAssign<(Val, Val)> for Size { + /// Subtract-assigns ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. + /// + /// # Panics + /// If the [`Val`]s can't be subtracted correctly (if they are of different variants). fn sub_assign(&mut self, rhs: (Val, Val)) { self.width.try_sub_assign(rhs.0).unwrap(); self.height.try_sub_assign(rhs.1).unwrap(); From 69fa05449c09039a0f1ee8768dd7faf19b06fbaa Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Wed, 5 Oct 2022 17:31:26 +0200 Subject: [PATCH 15/21] formatting --- crates/bevy_ui/src/geometry.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/bevy_ui/src/geometry.rs b/crates/bevy_ui/src/geometry.rs index 542a6227ef2cb..d9e2aa29f9615 100644 --- a/crates/bevy_ui/src/geometry.rs +++ b/crates/bevy_ui/src/geometry.rs @@ -359,7 +359,7 @@ impl Add<(Val, Val)> for Size { type Output = Size; /// Adds ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. - /// + /// /// # Panics /// If the [`Val`]s can't be added correctly (if they are of different variants). fn add(self, rhs: (Val, Val)) -> Self::Output { @@ -372,7 +372,7 @@ impl Add<(Val, Val)> for Size { impl AddAssign<(Val, Val)> for Size { /// Add-assigns ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. - /// + /// /// # Panics /// If the [`Val`]s can't be added correctly (if they are of different variants). fn add_assign(&mut self, rhs: (Val, Val)) { @@ -385,7 +385,7 @@ impl Sub<(Val, Val)> for Size { type Output = Size; /// Subtracts ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. - /// + /// /// # Panics /// If the [`Val`]s can't be subtracted correctly (if they are of different variants). fn sub(self, rhs: (Val, Val)) -> Self::Output { @@ -398,7 +398,7 @@ impl Sub<(Val, Val)> for Size { impl SubAssign<(Val, Val)> for Size { /// Subtract-assigns ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. - /// + /// /// # Panics /// If the [`Val`]s can't be subtracted correctly (if they are of different variants). fn sub_assign(&mut self, rhs: (Val, Val)) { From 2fdb45c5ab7e923bcec30eebe8c400696e97fff9 Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Wed, 5 Oct 2022 23:18:40 +0200 Subject: [PATCH 16/21] replace add and sub impls for Size struct with from<(Val, Val)> --- crates/bevy_ui/src/geometry.rs | 78 ++++++---------------------------- 1 file changed, 12 insertions(+), 66 deletions(-) diff --git a/crates/bevy_ui/src/geometry.rs b/crates/bevy_ui/src/geometry.rs index d9e2aa29f9615..5525988a9a8e1 100644 --- a/crates/bevy_ui/src/geometry.rs +++ b/crates/bevy_ui/src/geometry.rs @@ -1,6 +1,6 @@ use crate::Val; use bevy_reflect::Reflect; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; +use std::ops::{Div, DivAssign, Mul, MulAssign}; /// A type which is commonly used to define positions, margins, paddings and borders. /// @@ -355,58 +355,15 @@ impl Size { }; } -impl Add<(Val, Val)> for Size { - type Output = Size; - - /// Adds ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. - /// - /// # Panics - /// If the [`Val`]s can't be added correctly (if they are of different variants). - fn add(self, rhs: (Val, Val)) -> Self::Output { - Self { - width: self.width.try_add(rhs.0).unwrap(), - height: self.height.try_add(rhs.1).unwrap(), - } - } -} - -impl AddAssign<(Val, Val)> for Size { - /// Add-assigns ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. - /// - /// # Panics - /// If the [`Val`]s can't be added correctly (if they are of different variants). - fn add_assign(&mut self, rhs: (Val, Val)) { - self.width.try_add_assign(rhs.0).unwrap(); - self.height.try_add_assign(rhs.1).unwrap(); - } -} - -impl Sub<(Val, Val)> for Size { - type Output = Size; - - /// Subtracts ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. - /// - /// # Panics - /// If the [`Val`]s can't be subtracted correctly (if they are of different variants). - fn sub(self, rhs: (Val, Val)) -> Self::Output { +impl From<(Val, Val)> for Size { + fn from(vals: (Val, Val)) -> Self { Self { - width: self.width.try_sub(rhs.0).unwrap(), - height: self.height.try_sub(rhs.1).unwrap(), + width: vals.0, + height: vals.1, } } } -impl SubAssign<(Val, Val)> for Size { - /// Subtract-assigns ([`Val`], [`Val`]) respectively to the width and the height of the [`Size`] struct. - /// - /// # Panics - /// If the [`Val`]s can't be subtracted correctly (if they are of different variants). - fn sub_assign(&mut self, rhs: (Val, Val)) { - self.width.try_sub_assign(rhs.0).unwrap(); - self.height.try_sub_assign(rhs.1).unwrap(); - } -} - impl Mul for Size { type Output = Size; @@ -448,27 +405,16 @@ mod tests { use super::*; #[test] - fn test_size_add() { - assert_eq!( - Size::new(Val::Px(10.), Val::Px(10.)) + (Val::Px(10.), Val::Px(10.)), - Size::new(Val::Px(20.), Val::Px(20.)) - ); + fn test_size_from() { + let size: Size = (Val::Px(20.), Val::Px(30.)).into(); - let mut size = Size::new(Val::Px(10.), Val::Px(10.)); - size += (Val::Px(10.), Val::Px(10.)); - assert_eq!(size, Size::new(Val::Px(20.), Val::Px(20.))); - } - - #[test] - fn test_size_sub() { assert_eq!( - Size::new(Val::Px(20.), Val::Px(20.)) - (Val::Px(10.), Val::Px(10.)), - Size::new(Val::Px(10.), Val::Px(10.)) + size, + Size { + width: Val::Px(20.), + height: Val::Px(30.), + } ); - - let mut size = Size::new(Val::Px(20.), Val::Px(20.)); - size -= (Val::Px(10.), Val::Px(10.)); - assert_eq!(size, Size::new(Val::Px(10.), Val::Px(10.))); } #[test] From da417505da1dd4ea2a17188d821d280daca08805 Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Wed, 5 Oct 2022 23:20:46 +0200 Subject: [PATCH 17/21] ValArithmeticError derives Clone and Copy --- crates/bevy_ui/src/ui_node.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 513beb4865bf4..25be5b7710372 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -78,7 +78,7 @@ impl DivAssign for Val { } } -#[derive(Debug, Eq, PartialEq)] +#[derive(Debug, Eq, PartialEq, Clone, Copy)] pub enum ValArithmeticError { NonIdenticalVariants, NonEvaluateable, From 769362c457dfc7c0c9726f1f8de090795a8c454e Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Wed, 5 Oct 2022 23:40:13 +0200 Subject: [PATCH 18/21] added error messages to ValArithmeticError --- crates/bevy_ui/Cargo.toml | 1 + crates/bevy_ui/src/ui_node.rs | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ui/Cargo.toml b/crates/bevy_ui/Cargo.toml index 24c4305251d95..caf95361fdbad 100644 --- a/crates/bevy_ui/Cargo.toml +++ b/crates/bevy_ui/Cargo.toml @@ -34,3 +34,4 @@ taffy = "0.1.0" serde = { version = "1", features = ["derive"] } smallvec = { version = "1.6", features = ["union", "const_generics"] } bytemuck = { version = "1.5", features = ["derive"] } +thiserror = "1.0.37" diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 25be5b7710372..8b9659c0819fd 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -9,6 +9,7 @@ use bevy_render::{ texture::{Image, DEFAULT_IMAGE_HANDLE}, }; use serde::{Deserialize, Serialize}; +use thiserror::Error; use std::ops::{Div, DivAssign, Mul, MulAssign}; /// Describes the size of a UI node @@ -78,9 +79,11 @@ impl DivAssign for Val { } } -#[derive(Debug, Eq, PartialEq, Clone, Copy)] +#[derive(Debug, Eq, PartialEq, Clone, Copy, Error)] pub enum ValArithmeticError { + #[error("the variants of the Vals don't match")] NonIdenticalVariants, + #[error("the given variant of Val is not evaluateable (non-numeric)")] NonEvaluateable, } @@ -616,4 +619,10 @@ mod tests { assert_eq!(undefined_sum, Err(ValArithmeticError::NonEvaluateable)); assert_eq!(percent_sum, Err(ValArithmeticError::NonEvaluateable)); } + + #[test] + fn val_arithmetic_error_messages() { + assert_eq!(format!("{}", ValArithmeticError::NonIdenticalVariants), "the variants of the Vals don't match"); + assert_eq!(format!("{}", ValArithmeticError::NonEvaluateable), "the given variant of Val is not evaluateable (non-numeric)"); + } } From 495fef9cd1cf5c0b82bb328ba8ae3363a6ba9ff0 Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Wed, 5 Oct 2022 23:42:28 +0200 Subject: [PATCH 19/21] made the docs for Val::try_add_assign_with_size not reference self which is private --- crates/bevy_ui/src/ui_node.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 8b9659c0819fd..9b177e6298e1d 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -145,7 +145,7 @@ impl Val { } /// Similar to [`Val::try_add_assign`], but performs [`Val::evaluate`] on both values before adding. - /// [`self`] gets converted to [`Val::Px`]. + /// The value gets converted to [`Val::Px`]. pub fn try_add_assign_with_size( &mut self, rhs: Val, @@ -165,7 +165,7 @@ impl Val { } /// Similar to [`Val::try_sub_assign`], but performs [`Val::evaluate`] on both values before adding. - /// [`self`] gets converted to [`Val::Px`]. + /// The value gets converted to [`Val::Px`]. pub fn try_sub_assign_with_size( &mut self, rhs: Val, From 54ef7979f51b19f1e8ecf334991fc3337860a998 Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Wed, 5 Oct 2022 23:42:47 +0200 Subject: [PATCH 20/21] formatting --- crates/bevy_ui/src/ui_node.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 9b177e6298e1d..e009240c3a297 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -9,8 +9,8 @@ use bevy_render::{ texture::{Image, DEFAULT_IMAGE_HANDLE}, }; use serde::{Deserialize, Serialize}; -use thiserror::Error; use std::ops::{Div, DivAssign, Mul, MulAssign}; +use thiserror::Error; /// Describes the size of a UI node #[derive(Component, Debug, Clone, Default, Reflect)] @@ -622,7 +622,13 @@ mod tests { #[test] fn val_arithmetic_error_messages() { - assert_eq!(format!("{}", ValArithmeticError::NonIdenticalVariants), "the variants of the Vals don't match"); - assert_eq!(format!("{}", ValArithmeticError::NonEvaluateable), "the given variant of Val is not evaluateable (non-numeric)"); + assert_eq!( + format!("{}", ValArithmeticError::NonIdenticalVariants), + "the variants of the Vals don't match" + ); + assert_eq!( + format!("{}", ValArithmeticError::NonEvaluateable), + "the given variant of Val is not evaluateable (non-numeric)" + ); } } From a8e9ca99266a589079bb68346c1978fd743596e2 Mon Sep 17 00:00:00 2001 From: Pietrek14 Date: Mon, 17 Oct 2022 16:29:33 +0200 Subject: [PATCH 21/21] doc comments for Val::try_add_assign and Val::try_sub_assign --- crates/bevy_ui/src/ui_node.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index e009240c3a297..e48057cf37724 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -100,6 +100,7 @@ impl Val { } } + /// Adds `rhs` to `self` and assigns the result to `self` (see [`Val::try_add`]) pub fn try_add_assign(&mut self, rhs: Val) -> Result<(), ValArithmeticError> { *self = self.try_add(rhs)?; Ok(()) @@ -117,6 +118,7 @@ impl Val { } } + /// Subtracts `rhs` from `self` and assigns the result to `self` (see [`Val::try_sub`]) pub fn try_sub_assign(&mut self, rhs: Val) -> Result<(), ValArithmeticError> { *self = self.try_sub(rhs)?; Ok(())