1
+ use crate :: notify_mutex:: NotifyableMutex ;
1
2
use crossbeam_channel:: { unbounded, Receiver } ;
2
3
use crossterm:: event:: { self , Event } ;
3
4
use std:: {
@@ -27,7 +28,7 @@ pub enum InputEvent {
27
28
28
29
///
29
30
pub struct Input {
30
- desired_state : Arc < AtomicBool > ,
31
+ desired_state : Arc < NotifyableMutex < bool > > ,
31
32
current_state : Arc < AtomicBool > ,
32
33
receiver : Receiver < InputEvent > ,
33
34
}
@@ -37,40 +38,39 @@ impl Input {
37
38
pub fn new ( ) -> Self {
38
39
let ( tx, rx) = unbounded ( ) ;
39
40
40
- let desired_state = Arc :: new ( AtomicBool :: new ( true ) ) ;
41
+ let desired_state = Arc :: new ( NotifyableMutex :: new ( true ) ) ;
41
42
let current_state = Arc :: new ( AtomicBool :: new ( true ) ) ;
42
43
43
44
let arc_desired = Arc :: clone ( & desired_state) ;
44
45
let arc_current = Arc :: clone ( & current_state) ;
45
46
46
- thread:: spawn ( move || {
47
- loop {
48
- //TODO: use condvar to not busy wait
49
- if arc_desired. load ( Ordering :: Relaxed ) {
50
- if !arc_current. load ( Ordering :: Relaxed ) {
51
- tx. send ( InputEvent :: State (
52
- InputState :: Polling ,
53
- ) )
54
- . expect ( "send failed" ) ;
55
- }
56
- arc_current. store ( true , Ordering :: Relaxed ) ;
57
-
58
- if let Some ( e) = Self :: poll ( POLL_DURATION )
59
- . expect ( "failed to pull events." )
60
- {
61
- tx. send ( InputEvent :: Input ( e) )
62
- . expect ( "send input event failed" ) ;
63
- }
64
- } else {
65
- if arc_current. load ( Ordering :: Relaxed ) {
66
- tx. send ( InputEvent :: State (
67
- InputState :: Paused ,
68
- ) )
69
- . expect ( "send failed" ) ;
70
- }
71
-
72
- arc_current. store ( false , Ordering :: Relaxed ) ;
47
+ thread:: spawn ( move || loop {
48
+ if arc_desired. get ( ) {
49
+ if !arc_current. load ( Ordering :: Relaxed ) {
50
+ log:: info!( "input polling resumed" ) ;
51
+
52
+ tx. send ( InputEvent :: State ( InputState :: Polling ) )
53
+ . expect ( "send state failed" ) ;
54
+ }
55
+ arc_current. store ( true , Ordering :: Relaxed ) ;
56
+
57
+ if let Some ( e) = Self :: poll ( POLL_DURATION )
58
+ . expect ( "failed to pull events." )
59
+ {
60
+ tx. send ( InputEvent :: Input ( e) )
61
+ . expect ( "send input failed" ) ;
62
+ }
63
+ } else {
64
+ if arc_current. load ( Ordering :: Relaxed ) {
65
+ log:: info!( "input polling suspended" ) ;
66
+
67
+ tx. send ( InputEvent :: State ( InputState :: Paused ) )
68
+ . expect ( "send state failed" ) ;
73
69
}
70
+
71
+ arc_current. store ( false , Ordering :: Relaxed ) ;
72
+
73
+ arc_desired. wait ( true ) ;
74
74
}
75
75
} ) ;
76
76
@@ -88,12 +88,16 @@ impl Input {
88
88
89
89
///
90
90
pub fn set_polling ( & mut self , enabled : bool ) {
91
- self . desired_state . store ( enabled, Ordering :: Relaxed ) ;
91
+ self . desired_state . set_and_notify ( enabled)
92
+ }
93
+
94
+ fn shall_poll ( & self ) -> bool {
95
+ self . desired_state . get ( )
92
96
}
93
97
94
98
///
95
99
pub fn is_state_changing ( & self ) -> bool {
96
- self . desired_state . load ( Ordering :: Relaxed )
100
+ self . shall_poll ( )
97
101
!= self . current_state . load ( Ordering :: Relaxed )
98
102
}
99
103
0 commit comments