livesplit_core/rendering/resource/
handles.rs1use core::{
2 hash::{Hash, Hasher},
3 ops::{Deref, DerefMut},
4};
5
6use crate::settings::Font;
7
8use super::{Label, PathBuilder, ResourceAllocator, SharedOwnership};
9
10pub struct Handles<A> {
11 next_id: usize,
12 allocator: A,
13}
14
15impl<A> Handles<A> {
16 pub const fn new(next_id: usize, allocator: A) -> Self {
17 Self { next_id, allocator }
18 }
19
20 pub fn next<T>(&mut self, element: T) -> Handle<T> {
21 let id = self.next_id;
22 self.next_id = self.next_id.wrapping_add(1);
23 Handle { id, inner: element }
24 }
25
26 #[allow(clippy::missing_const_for_fn)] pub fn into_next_id(self) -> usize {
29 self.next_id
30 }
31}
32
33pub struct HandlePathBuilder<PB: PathBuilder>(PB, usize);
34
35impl<PB: PathBuilder> PathBuilder for HandlePathBuilder<PB> {
36 type Path = Handle<PB::Path>;
37
38 fn move_to(&mut self, x: f32, y: f32) {
39 self.0.move_to(x, y);
40 }
41
42 fn line_to(&mut self, x: f32, y: f32) {
43 self.0.line_to(x, y)
44 }
45
46 fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) {
47 self.0.quad_to(x1, y1, x, y)
48 }
49
50 fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {
51 self.0.curve_to(x1, y1, x2, y2, x, y)
52 }
53
54 fn close(&mut self) {
55 self.0.close()
56 }
57
58 fn finish(self) -> Self::Path {
59 Handle::new(self.1, self.0.finish())
60 }
61}
62
63impl<A: ResourceAllocator> ResourceAllocator for Handles<A> {
64 type PathBuilder = HandlePathBuilder<A::PathBuilder>;
65 type Path = Handle<A::Path>;
66 type Image = Handle<A::Image>;
67 type Font = Handle<A::Font>;
68 type Label = LabelHandle<A::Label>;
69
70 fn path_builder(&mut self) -> Self::PathBuilder {
71 let id = self.next_id;
72 self.next_id = self.next_id.wrapping_add(1);
73 HandlePathBuilder(self.allocator.path_builder(), id)
74 }
75
76 fn build_circle(&mut self, x: f32, y: f32, r: f32) -> Self::Path {
77 let circle = self.allocator.build_circle(x, y, r);
78 self.next(circle)
79 }
80
81 fn create_image(&mut self, data: &[u8]) -> Option<(Self::Image, f32)> {
82 let (image, aspect_ratio) = self.allocator.create_image(data)?;
83 Some((self.next(image), aspect_ratio))
84 }
85
86 fn create_font(&mut self, font: Option<&Font>, kind: super::FontKind) -> Self::Font {
87 let font = self.allocator.create_font(font, kind);
88 self.next(font)
89 }
90
91 fn create_label(
92 &mut self,
93 text: &str,
94 font: &mut Self::Font,
95 max_width: Option<f32>,
96 ) -> Self::Label {
97 let label = self.allocator.create_label(text, font, max_width);
98 LabelHandle {
99 update_counter: 0,
100 handle: self.next(label),
101 }
102 }
103
104 fn update_label(
105 &mut self,
106 label: &mut Self::Label,
107 text: &str,
108 font: &mut Self::Font,
109 max_width: Option<f32>,
110 ) {
111 self.allocator
112 .update_label(&mut label.handle, text, font, max_width);
113 label.update_counter += 1;
114 }
115}
116
117pub struct LabelHandle<L> {
120 update_counter: usize,
121 handle: Handle<L>,
122}
123
124impl<T> Deref for LabelHandle<T> {
125 type Target = T;
126
127 fn deref(&self) -> &Self::Target {
128 &self.handle
129 }
130}
131
132impl<T> Hash for LabelHandle<T> {
133 fn hash<H: Hasher>(&self, state: &mut H) {
134 self.update_counter.hash(state);
135 self.handle.hash(state);
136 }
137}
138
139impl<L: Label> SharedOwnership for LabelHandle<L> {
140 fn share(&self) -> Self {
141 LabelHandle {
142 update_counter: self.update_counter,
143 handle: self.handle.share(),
144 }
145 }
146}
147
148impl<L: Label> Label for LabelHandle<L> {
149 fn width(&self, scale: f32) -> f32 {
150 self.handle.inner.width(scale)
151 }
152
153 fn width_without_max_width(&self, scale: f32) -> f32 {
154 self.handle.inner.width_without_max_width(scale)
155 }
156}
157
158impl<T> Eq for LabelHandle<T> {}
159
160impl<T> PartialEq for LabelHandle<T> {
161 fn eq(&self, other: &Self) -> bool {
162 self.update_counter.eq(&other.update_counter) && self.handle.eq(&other.handle)
163 }
164}
165
166pub struct Handle<T> {
168 pub(crate) id: usize,
169 inner: T,
170}
171
172impl<T: SharedOwnership> SharedOwnership for Handle<T> {
173 fn share(&self) -> Self {
174 Self {
175 id: self.id,
176 inner: self.inner.share(),
177 }
178 }
179}
180
181impl<T: SharedOwnership> Handle<T> {
182 pub const fn new(id: usize, resource: T) -> Self {
184 Self {
185 id,
186 inner: resource,
187 }
188 }
189}
190
191impl<T> Deref for Handle<T> {
192 type Target = T;
193
194 fn deref(&self) -> &Self::Target {
195 &self.inner
196 }
197}
198
199impl<T> DerefMut for Handle<T> {
200 fn deref_mut(&mut self) -> &mut Self::Target {
201 &mut self.inner
202 }
203}
204
205impl<T> Hash for Handle<T> {
206 fn hash<H: Hasher>(&self, state: &mut H) {
207 self.id.hash(state)
208 }
209}
210
211impl<T> Eq for Handle<T> {}
212
213impl<T> PartialEq for Handle<T> {
214 fn eq(&self, other: &Self) -> bool {
215 self.id.eq(&other.id)
216 }
217}