diff options
Diffstat (limited to 'src/bin/client/repl.rs')
| -rw-r--r-- | src/bin/client/repl.rs | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/src/bin/client/repl.rs b/src/bin/client/repl.rs index c13fc58..bc4238d 100644 --- a/src/bin/client/repl.rs +++ b/src/bin/client/repl.rs | |||
| @@ -13,7 +13,8 @@ use crossterm::{ | |||
| 13 | 13 | ||
| 14 | use sha2::{Digest, Sha256}; | 14 | use sha2::{Digest, Sha256}; |
| 15 | 15 | ||
| 16 | use zagan_bet::client::core::{ClientCore, Effect, InteractiveCommand, Key}; | 16 | use zagan_bet::client::core::{ClientCore, Effect, InteractiveCommand}; |
| 17 | use zagan_bet::client::input::{game_input, GameInput, Input, Key, Editor}; | ||
| 17 | use zagan_bet::client::database; | 18 | use zagan_bet::client::database; |
| 18 | use zagan_bet::client::ui::{ | 19 | use zagan_bet::client::ui::{ |
| 19 | display_width, format_pong, host_lines, input_cursor_column, lines_to_move_up, | 20 | display_width, format_pong, host_lines, input_cursor_column, lines_to_move_up, |
| @@ -30,6 +31,7 @@ pub struct ClientState { | |||
| 30 | pub addr: Option<String>, | 31 | pub addr: Option<String>, |
| 31 | pub default_port: u16, | 32 | pub default_port: u16, |
| 32 | core: ClientCore, | 33 | core: ClientCore, |
| 34 | editor: Editor, | ||
| 33 | cleanup_done: Arc<Mutex<bool>>, | 35 | cleanup_done: Arc<Mutex<bool>>, |
| 34 | /// Number of visual terminal lines currently occupied by the game board. | 36 | /// Number of visual terminal lines currently occupied by the game board. |
| 35 | game_lines: usize, | 37 | game_lines: usize, |
| @@ -59,6 +61,7 @@ impl ClientState { | |||
| 59 | addr, | 61 | addr, |
| 60 | default_port, | 62 | default_port, |
| 61 | core: ClientCore::new(), | 63 | core: ClientCore::new(), |
| 64 | editor: Editor::new(), | ||
| 62 | cleanup_done: Arc::new(Mutex::new(false)), | 65 | cleanup_done: Arc::new(Mutex::new(false)), |
| 63 | game_lines: 0, | 66 | game_lines: 0, |
| 64 | prompt_text: String::new(), | 67 | prompt_text: String::new(), |
| @@ -112,9 +115,29 @@ impl ClientState { | |||
| 112 | Event::Key(key) => { | 115 | Event::Key(key) => { |
| 113 | if key.kind == KeyEventKind::Press { | 116 | if key.kind == KeyEventKind::Press { |
| 114 | if let Some(key) = map_key(key) { | 117 | if let Some(key) = map_key(key) { |
| 115 | let effects = self.core.handle_key(key); | 118 | let effects = if self.core.is_in_game() { |
| 119 | match game_input( | ||
| 120 | self.core.current_game_type().unwrap_or(""), | ||
| 121 | key, | ||
| 122 | ) { | ||
| 123 | GameInput::Quit => vec![Effect::Quit], | ||
| 124 | GameInput::Command(command) => { | ||
| 125 | self.core.command(command) | ||
| 126 | } | ||
| 127 | GameInput::None => Vec::new(), | ||
| 128 | } | ||
| 129 | } else { | ||
| 130 | match self.editor.handle(key) { | ||
| 131 | Input::Quit => vec![Effect::Quit], | ||
| 132 | Input::Submit(line) => self.core.submit_line(&line), | ||
| 133 | Input::Print(lines) => vec![Effect::Print(lines)], | ||
| 134 | Input::Prompt | Input::None => Vec::new(), | ||
| 135 | } | ||
| 136 | }; | ||
| 116 | quit = self.apply_effects(effects); | 137 | quit = self.apply_effects(effects); |
| 117 | self.apply_prompt(); | 138 | if !quit { |
| 139 | self.apply_prompt(); | ||
| 140 | } | ||
| 118 | } | 141 | } |
| 119 | } | 142 | } |
| 120 | } | 143 | } |
| @@ -222,7 +245,6 @@ impl ClientState { | |||
| 222 | } | 245 | } |
| 223 | } | 246 | } |
| 224 | Effect::ClearRegion => self.clear_region(), | 247 | Effect::ClearRegion => self.clear_region(), |
| 225 | Effect::SetPrompt { text, cursor_col } => self.draw_prompt(&text, cursor_col), | ||
| 226 | Effect::SendLine(line) => { | 248 | Effect::SendLine(line) => { |
| 227 | let is_ping = line == "PING"; | 249 | let is_ping = line == "PING"; |
| 228 | let started = Instant::now(); | 250 | let started = Instant::now(); |
| @@ -293,9 +315,12 @@ impl ClientState { | |||
| 293 | } | 315 | } |
| 294 | 316 | ||
| 295 | fn apply_prompt(&mut self) { | 317 | fn apply_prompt(&mut self) { |
| 296 | if let Some(prompt) = self.core.prompt_effect() { | 318 | if self.core.is_in_game() { |
| 297 | let _ = self.apply_effects(vec![prompt]); | 319 | return; |
| 298 | } | 320 | } |
| 321 | let text = self.editor.input().to_string(); | ||
| 322 | let column = self.editor.cursor_column(); | ||
| 323 | self.draw_prompt(&text, column); | ||
| 299 | } | 324 | } |
| 300 | 325 | ||
| 301 | /// Leave the command currently on the prompt line visible in the | 326 | /// Leave the command currently on the prompt line visible in the |
