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
115
116
117
118
119
120
121
122
use {
crate::{
gpu::{
write::{Write, WriteMode},
BlendMode,
},
math::{Coord, Extent, Rect},
DynScreen, Gpu, Input, Render, Screen,
},
std::{
time::{Duration, Instant},
u8,
},
};
pub struct Fade {
a: Option<DynScreen>,
b: Option<DynScreen>,
duration: Duration,
mode: BlendMode,
started: Instant,
}
impl Fade {
pub fn new(a: DynScreen, b: DynScreen, duration: Duration) -> Self {
Self {
a: Some(a),
b: Some(b),
duration,
mode: Default::default(),
started: Instant::now(),
}
}
pub fn with_blend_mode(&mut self, mode: BlendMode) {
self.mode = mode;
}
}
impl Screen for Fade {
fn render(&self, gpu: &Gpu, dims: Extent) -> Render {
let mut a = self.a.as_ref().unwrap().render(gpu, dims);
let b = self.b.as_ref().unwrap().render(gpu, dims);
let elapsed = match Instant::now() - self.started {
elapsed if elapsed < self.duration => elapsed,
_ => self.duration,
};
let ab = ((elapsed.as_millis() as f32 / self.duration.as_millis() as f32).min(1.0)
* u8::MAX as f32) as u8;
#[cfg(debug_assertions)]
debug!("Fade AB: {}", ab);
let dims = b.dims();
let b = gpu.resolve(b);
a.write(
#[cfg(feature = "debug-names")]
"Fade write B",
)
.with_mode(WriteMode::Blend((ab, self.mode)))
.record(&mut [Write::region(
&b,
Rect {
pos: Coord::ZERO,
dims,
},
)]);
a
}
fn update(mut self: Box<Self>, _: &Gpu, _: &Input) -> DynScreen {
if Instant::now() - self.started > self.duration {
self.b.take().unwrap()
} else {
self
}
}
}