File size: 1,784 Bytes
2409829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// TODO(TrueDoctor): Replace this with the more idiomatic approach instead of using `trait Clampable`.

/// A trait for types that can be clamped within a min/max range defined by f64.
pub trait Clampable: Sized {
	/// Clamps the value to be no less than `min`.
	fn clamp_hard_min(self, min: f64) -> Self;
	/// Clamps the value to be no more than `max`.
	fn clamp_hard_max(self, max: f64) -> Self;
}

// Implement for common numeric types
macro_rules! impl_clampable_float {
	($($ty:ty),*) => {
		$(
			impl Clampable for $ty {
				#[inline(always)]
				fn clamp_hard_min(self, min: f64) -> Self {
					self.max(min as $ty)
				}
				#[inline(always)]
				fn clamp_hard_max(self, max: f64) -> Self {
					self.min(max as $ty)
				}
			}
		)*
	};
}
impl_clampable_float!(f32, f64);

macro_rules! impl_clampable_int {
	($($ty:ty),*) => {
		$(
			impl Clampable for $ty {
				#[inline(always)]
				fn clamp_hard_min(self, min: f64) -> Self {
					// Using try_from to handle potential range issues safely, though min should ideally be valid.
					// Consider using a different approach if f64 precision vs integer range is a concern.
					<$ty>::try_from(min.ceil() as i64).ok().map_or(self, |min_val| self.max(min_val))
				}
				#[inline(always)]
				fn clamp_hard_max(self, max: f64) -> Self {
					<$ty>::try_from(max.floor() as i64).ok().map_or(self, |max_val| self.min(max_val))
				}
			}
		)*
	};
}
// Add relevant integer types (adjust as needed)
impl_clampable_int!(u32, u64, i32, i64);

// Implement for DVec2 (component-wise clamping)
use glam::DVec2;
impl Clampable for DVec2 {
	#[inline(always)]
	fn clamp_hard_min(self, min: f64) -> Self {
		self.max(DVec2::splat(min))
	}
	#[inline(always)]
	fn clamp_hard_max(self, max: f64) -> Self {
		self.min(DVec2::splat(max))
	}
}