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
use std::collections::LinkedList;
use std::thread;
use std::sync::{Arc, Mutex, Condvar};
use std::time::Duration;
use crate::handler::{Handler, HandlerMsg};
type Messages<T> = Arc<(Mutex<LinkedList<HandlerMsg<T>>>, Condvar)>;
pub struct Looper<T>
where
T: LooperMsg,
T: Send + 'static
{
msgs: Messages<T>,
thread: Option<thread::JoinHandle<()>>,
}
pub trait LooperMsg {
fn handle_message(self);
}
impl<T: LooperMsg + Send + 'static> Looper<T> {
pub fn new() -> Looper<T> {
let msgs = Arc::new((Mutex::new(LinkedList::new()), Condvar::new()));
let mut handler = Handler::new(msgs.clone());
let thread = thread::spawn(move || handler.run());
Looper {
msgs: msgs.clone(),
thread: Some(thread),
}
}
pub fn send_msg(&self, msg: T) {
self.put_msg(HandlerMsg::new(Option::<T>::Some(msg), Duration::from_millis(0)));
}
pub fn send_msg_delay(&self, msg: T, delay: Duration) {
self.put_msg(HandlerMsg::new(Option::<T>::Some(msg), delay));
}
pub fn terminate(&mut self) {
self.put_msg(HandlerMsg::with_terminate());
if let Some(h) = self.thread.take() {
h.join().unwrap();
}
}
fn put_msg(&self, hmsg: HandlerMsg<T>) {
let (lock, cvar) = &*self.msgs;
if let Ok(mut lst) = lock.lock() {
let mut cur = lst.cursor_front_mut();
while let Some(msg) = cur.current() {
if hmsg.when >= msg.when {
cur.move_next()
} else {
break;
}
}
cur.insert_before(hmsg);
#[cfg(feature = "debug")]
println!("cvar notify");
cvar.notify_one();
}
}
}