@@ -5,9 +5,11 @@ use std::thread;
55use std:: time:: Duration ;
66
77use crossterm:: {
8- event:: { self , Event , KeyCode , KeyEventKind , KeyModifiers } ,
8+ event:: { Event , KeyCode , KeyEventKind , KeyModifiers , EventStream } ,
99 terminal:: { disable_raw_mode, enable_raw_mode} ,
1010} ;
11+ use futures:: { stream:: StreamExt } ;
12+ use tokio:: task:: { AbortHandle , spawn_blocking} ;
1113
1214type Tx = Box < dyn Write + Send > ;
1315type Rx = Box < dyn Read + Send > ;
@@ -83,64 +85,26 @@ impl SerialTerm {
8385 is_running : AtomicBool :: new ( true ) ,
8486 } ) ;
8587
88+ // 使用 EventStream 异步处理键盘事件
89+ let tx_handle = tokio:: spawn ( Self :: tx_work_async ( handle. clone ( ) , tx_port) ) ;
90+
91+ let tx_abort = tx_handle. abort_handle ( ) ;
8692 // 启动串口接收线程
87- let rx_handle = thread :: spawn ( {
93+ let rx_handle = spawn_blocking ( {
8894 let handle = handle. clone ( ) ;
89- move || Self :: handle_serial_receive ( rx_port, handle, on_line)
95+ move || Self :: handle_serial_receive ( rx_port, handle, tx_abort , on_line)
9096 } ) ;
91-
92- // 主线程处理键盘输入
93- let mut key_state = KeySequenceState :: Normal ;
94-
95- while handle. is_running ( ) {
96- // 非阻塞读取键盘事件
97- if event:: poll ( Duration :: from_millis ( 10 ) ) . is_ok ( )
98- && let Ok ( Event :: Key ( key) ) = event:: read ( )
99- && key. kind == KeyEventKind :: Press
100- {
101- // 检测 Ctrl+A+x 退出序列
102- match key_state {
103- KeySequenceState :: Normal => {
104- if key. code == KeyCode :: Char ( 'a' )
105- && key. modifiers . contains ( KeyModifiers :: CONTROL )
106- {
107- key_state = KeySequenceState :: CtrlAPressed ;
108- } else {
109- // 普通按键,发送到串口
110- Self :: send_key_to_serial ( & tx_port, key) ?;
111- }
112- }
113- KeySequenceState :: CtrlAPressed => {
114- if key. code == KeyCode :: Char ( 'x' ) {
115- // 用户请求退出
116- eprintln ! ( "\r \n Exit by: Ctrl+A+x" ) ;
117- handle. stop ( ) ;
118- break ;
119- } else {
120- // 不是x键,发送上一个按键并重置状态
121- if let KeyCode :: Char ( 'a' ) = key. code {
122- // 如果还是 Ctrl+A,保持状态
123- } else {
124- // 发送 Ctrl+A 和当前按键
125- Self :: send_ctrl_a_to_serial ( & tx_port) ?;
126- Self :: send_key_to_serial ( & tx_port, key) ?;
127- key_state = KeySequenceState :: Normal ;
128- }
129- }
130- }
131- }
132- }
133- }
134-
13597 // 等待接收线程结束
136- let _ = rx_handle. join ( ) ;
98+ let _ = rx_handle. await ?;
99+ let _ = tx_handle. await ;
137100 info ! ( "Serial terminal exited" ) ;
138101 Ok ( ( ) )
139102 }
140103
141104 fn handle_serial_receive < F > (
142105 rx_port : Arc < Mutex < Rx > > ,
143106 handle : Arc < TermHandle > ,
107+ tx_abort : AbortHandle ,
144108 on_line : F ,
145109 ) -> io:: Result < ( ) >
146110 where
@@ -189,7 +153,7 @@ impl SerialTerm {
189153 }
190154 }
191155 }
192-
156+ tx_abort . abort ( ) ;
193157 Ok ( ( ) )
194158 }
195159
@@ -489,4 +453,65 @@ impl SerialTerm {
489453 tx_port. lock ( ) . unwrap ( ) . flush ( ) ?;
490454 Ok ( ( ) )
491455 }
456+
457+ async fn tx_work_async ( handle : Arc < TermHandle > , tx_port : Arc < Mutex < Tx > > ) -> anyhow:: Result < ( ) > {
458+ // 使用 EventStream 异步处理键盘事件
459+ let mut reader = EventStream :: new ( ) ;
460+ let mut key_state = KeySequenceState :: Normal ;
461+
462+ while handle. is_running ( ) {
463+ // 使用 EventStream::next() 异步等待事件,不会阻塞
464+ match reader. next ( ) . await {
465+ Some ( Ok ( Event :: Key ( key) ) ) if key. kind == KeyEventKind :: Press => {
466+ // 检测 Ctrl+A+x 退出序列
467+ match key_state {
468+ KeySequenceState :: Normal => {
469+ if key. code == KeyCode :: Char ( 'a' )
470+ && key. modifiers . contains ( KeyModifiers :: CONTROL )
471+ {
472+ key_state = KeySequenceState :: CtrlAPressed ;
473+ } else {
474+ // 普通按键,发送到串口
475+ if let Err ( e) = Self :: send_key_to_serial ( & tx_port, key) {
476+ eprintln ! ( "\r \n 发送按键失败: {}" , e) ;
477+ }
478+ }
479+ }
480+ KeySequenceState :: CtrlAPressed => {
481+ if key. code == KeyCode :: Char ( 'x' ) {
482+ // 用户请求退出
483+ eprintln ! ( "\r \n Exit by: Ctrl+A+x" ) ;
484+ handle. stop ( ) ;
485+ break ;
486+ } else {
487+ // 不是x键,发送上一个按键并重置状态
488+ if key. code != KeyCode :: Char ( 'a' ) {
489+ if let Err ( e) = Self :: send_ctrl_a_to_serial ( & tx_port) {
490+ eprintln ! ( "\r \n 发送 Ctrl+A 失败: {}" , e) ;
491+ }
492+ if let Err ( e) = Self :: send_key_to_serial ( & tx_port, key) {
493+ eprintln ! ( "\r \n 发送按键失败: {}" , e) ;
494+ }
495+ key_state = KeySequenceState :: Normal ;
496+ }
497+ }
498+ }
499+ }
500+ }
501+ Some ( Err ( e) ) => {
502+ eprintln ! ( "\r \n 键盘事件错误: {}" , e) ;
503+ break ;
504+ }
505+ None => {
506+ // EventStream 结束
507+ break ;
508+ }
509+ Some ( Ok ( _) ) => {
510+ // 忽略非按键事件(鼠标、调整大小等)
511+ }
512+ }
513+ }
514+
515+ Ok ( ( ) )
516+ }
492517}
0 commit comments