kozan_platform/
view_thread.rs1use std::sync::mpsc;
6use std::thread;
7
8use kozan_scheduler::WakeSender;
9
10use crate::event::ViewEvent;
11
12#[derive(Debug)]
14pub enum SpawnError {
15 ThreadSpawn(std::io::Error),
16 SetupFailed,
17}
18
19impl std::fmt::Display for SpawnError {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 match self {
22 SpawnError::ThreadSpawn(e) => write!(f, "failed to spawn thread: {e}"),
23 SpawnError::SetupFailed => write!(f, "thread setup failed"),
24 }
25 }
26}
27
28impl std::error::Error for SpawnError {}
29
30pub struct ViewThreadHandle {
32 sender: mpsc::Sender<ViewEvent>,
33 wake_sender: WakeSender,
34 join_handle: Option<thread::JoinHandle<()>>,
35}
36
37impl ViewThreadHandle {
38 pub fn from_parts(
39 sender: mpsc::Sender<ViewEvent>,
40 wake_sender: WakeSender,
41 join_handle: thread::JoinHandle<()>,
42 ) -> Self {
43 Self {
44 sender,
45 wake_sender,
46 join_handle: Some(join_handle),
47 }
48 }
49
50 pub fn send(&self, event: ViewEvent) -> bool {
51 self.sender.send(event).is_ok()
52 }
53
54 pub fn wake_sender(&self) -> WakeSender {
55 self.wake_sender.clone()
56 }
57
58 pub fn shutdown(&mut self) {
59 let _ = self.sender.send(ViewEvent::Shutdown);
60 if let Some(h) = self.join_handle.take() {
61 let _ = h.join();
62 }
63 }
64}
65
66impl Drop for ViewThreadHandle {
67 fn drop(&mut self) {
68 self.shutdown();
69 }
70}