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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
mod err;
pub use self::err::{DrawError, Result};
use std::fmt;
use std::mem;
pub const SPEC_MAX_X: usize = 10;
pub const SPEC_MAX_Y: usize = 5;
pub const SPEC_MAX_XY: usize = SPEC_MAX_X * SPEC_MAX_Y;
pub const SPEC_MAX_PRE_XY: usize = SPEC_MAX_XY - 1;
use ::Cursor;
pub use super::{Emotion, EmotionError};
pub use super::{Posture, PostureError};
pub use super::Texel;
pub use super::texel::part::Part;
use ::time;
#[derive(Copy)]
pub struct Draw {
posture: Posture,
duration: time::Duration,
board: Cursor<[(Emotion, Texel); SPEC_MAX_XY]>,
}
impl Draw {
pub fn new(position: &Posture,
duration: i64,
buf: &[(Emotion, Texel)])
-> Result<Self> {
let len: usize = buf.len();
if len.eq(&SPEC_MAX_XY) {
unsafe {
let mut line: [(Emotion, Texel); SPEC_MAX_XY] =
mem::uninitialized();
line.copy_from_slice(buf);
Ok(Draw {
posture: *position,
duration: time::Duration::milliseconds(duration),
board: Cursor::new(line),
})
}
} else {
Err(DrawError::OutOfSize(format!("{}/{}", len, SPEC_MAX_XY)))
}
}
pub fn current(&self) -> Option<(&Emotion, &Texel)> {
self.board
.get_ref()
.get(self.get_position())
.and_then(|&(ref emotion, ref texel)| Some((emotion, texel)))
}
pub fn get_current_part(&self) -> Option<&Part> {
self.current()
.and_then(|(_, ref texel)|
Some(texel.get_part()))
}
pub fn set_current(&mut self,
(emotion, texels): (&Emotion, &Vec<Texel>)) {
if let Some(texel) = texels.first() {
let part: &Part = texel.get_part();
self.board
.get_mut()
.iter_mut()
.filter(|&&mut (_, cell_texel)| cell_texel.get_part().eq(part))
.zip(texels.iter())
.all(|(&mut (ref mut cell_emotion,
ref mut cell_texel),
texel):
(&mut (Emotion, Texel), &Texel)| {
cell_emotion.clone_from(emotion);
cell_texel.set_glyph(texel.get_glyph());
true
});
}
}
pub fn get_posture(&self) -> &Posture {
&self.posture
}
pub fn get_position(&self) -> usize {
self.board.position()
}
pub fn set_position(&mut self, position: usize) {
self.board.set_position(position);
}
pub fn add_position(&mut self, position: usize) -> Option<()> {
if let Some(pos @ 0...SPEC_MAX_PRE_XY) = self.get_position()
.checked_add(position) {
Some(self.set_position(pos))
} else {
None
}
}
pub fn sub_position(&mut self, position: usize) -> Option<()> {
self.get_position()
.checked_sub(position)
.and_then(|pos| Some(self.set_position(pos)))
}
pub fn get_duration(&self) -> &time::Duration {
&self.duration
}
pub fn set_cell_at(&mut self,
index: usize, texel: &Texel, emotion: &Emotion
) {
self.board.get_mut()
.iter_mut()
.filter(|&&mut (_, ref cur_texel)| cur_texel.eq(&texel))
.nth(index)
.and_then(|&mut (ref mut cur_emotion, ref mut cur_texel)| {
cur_emotion.clone_from(emotion);
cur_texel.clone_from(texel);
Some(())
});
}
pub fn next(&mut self) -> Option<(&Emotion, &Texel)> {
let position: usize = self.get_position();
self.board.set_position(position+1);
self.board
.get_ref()
.get(position)
.and_then(|&(ref emotion, ref texel)| Some((emotion, texel)))
}
}
impl<'a> IntoIterator for &'a Draw {
type Item = &'a (Emotion, Texel);
type IntoIter = ::std::slice::Iter<'a, (Emotion, Texel)>;
fn into_iter(self) -> Self::IntoIter {
self.board.get_ref().into_iter()
}
}
impl fmt::Debug for Draw {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "(Posture: {:?}, sprite: {:?})",
self.posture,
self.board
.get_ref()
.iter()
.filter(|&&(ref emotion, _)| emotion.is_none())
.collect::<Vec<&(Emotion, Texel)>>())
}
}
impl Clone for Draw {
fn clone(&self) -> Draw {
Draw {
posture: self.posture,
duration: self.duration,
board: Cursor::new(*self.board.get_ref()),
}
}
fn clone_from(&mut self, source: &Self) {
self.posture.clone_from(&source.posture);
self.duration.clone_from(&source.duration);
self.board.get_mut().copy_from_slice(source.board.get_ref());
}
}
impl Default for Draw {
fn default() -> Draw {
unsafe {
let mut board: [(Emotion, Texel); SPEC_MAX_XY] =
mem::uninitialized();
assert!(board.iter_mut().all(|mut tuple| {
*tuple = (Emotion::default(), Texel::default());
true
}));
Draw {
posture: Posture::default(),
duration: time::Duration::milliseconds(0),
board: Cursor::new(board),
}
}
}
}