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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::affine_transform::AffineTransform;
use std::cell::Cell;
/// A container for storing an [`AffineTransform`] along with its
/// associated “best score”. Internally uses [`Cell`], allowing for
/// interior mutability.
///
/// Typical usage includes:
/// - Storing an optional [`AffineTransform`] (or `None` if not set).
/// - Recording a floating-point “best score” value, which can
/// be updated based on some criteria (e.g., the transform quality).
#[derive(Debug, Clone)]
pub struct AffineTransformCell {
/// Holds the current [`AffineTransform`] (or `None` if none is set).
/// Wrapped in a [`Cell`] for interior mutability, allowing it to be
/// updated without requiring a mutable reference to `AffineTransformCell`.
cm: Cell<Option<AffineTransform>>,
/// A “best score” associated with the transform, typically used
/// to compare how optimal or preferable one transform is over another.
best_score: Cell<f32>,
}
impl AffineTransformCell {
/// Creates a new `AffineTransformCell` with no transform set
/// (`None`) and the `best_score` initialized to [`f32::MAX`].
///
/// # Examples
/// ```text
/// let cell = AffineTransformCell::new_empty();
/// assert_eq!(cell.get_affine_transform(), None);
/// assert_eq!(cell.get_score(), f32::MAX);
/// ```
pub fn new_empty() -> Self {
AffineTransformCell {
cm: Cell::new(None),
best_score: Cell::new(f32::MAX),
}
}
/// Updates the cell to store a given [`AffineTransform`] along with
/// a new “best score”. This overrides any previous transform and score.
///
/// # Parameters
/// - `cm`: The new [`AffineTransform`] to store.
/// - `new_score`: A floating-point value that describes how good
/// or optimal this transform is (lower or higher depending on usage).
///
/// # Examples
/// ```text
/// let cell = AffineTransformCell::new_empty();
/// let transform = AffineTransform {
/// origin_x: 0,
/// origin_y: 0,
/// translate_x: 10.0,
/// translate_y: 20.0,
/// a11: 1.0, a12: 0.0,
/// a21: 0.0, a22: 1.0,
/// };
///
/// cell.set(transform, 42.0);
/// assert_eq!(cell.get_score(), 42.0);
/// assert!(cell.get_affine_transform().is_some());
/// ```
pub fn set(&self, cm: AffineTransform, new_score: f32) {
self.cm.set(Some(cm));
self.best_score.set(new_score);
}
/// Retrieves the current “best score.”
///
/// # Returns
/// The floating-point “best score” stored in this cell.
///
/// # Examples
/// ```text
/// use pixelmap::affine_transform_cell::AffineTransformCell;
/// use pixelmap::affine_transform::AffineTransform;
/// let cell = AffineTransformCell::new_empty();
/// assert_eq!(cell.get_score(), f32::MAX);
/// ```
pub fn get_score(&self) -> f32 {
self.best_score.get()
}
/// Retrieves the current [`AffineTransform`], if any.
///
/// # Returns
/// An [`Option<AffineTransform>`], which is `Some(transform)` if a transform
/// has been set, or `None` if this cell is still empty.
///
/// # Examples
/// ```text
/// use pixelmap::affine_transform::AffineTransform;
/// use pixelmap::affine_transform_cell::AffineTransformCell;
/// let cell = AffineTransformCell::new_empty();
/// assert_eq!(cell.get_affine_transform(), None);
///
/// let transform = AffineTransform {
/// origin_x: 0,
/// origin_y: 0,
/// translate_x: 10.0,
/// translate_y: 20.0,
/// a11: 1.0, a12: 0.0,
/// a21: 0.0, a22: 1.0,
/// };
/// cell.set(transform, 42.0);
/// let maybe_transform = cell.get_affine_transform();
/// assert!(maybe_transform.is_some());
/// ```
pub fn get_affine_transform(&self) -> Option<AffineTransform> {
self.cm.get()
}
}