Manage ctrl c when it's user turn to input
This commit is contained in:
@ -1,10 +1,16 @@
|
||||
extern crate ctrlc;
|
||||
use shakmaty::fen::Fen;
|
||||
use shakmaty::{Chess, Color, Outcome, Position, Setup};
|
||||
use std::io;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::os::unix::net::UnixStream;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time;
|
||||
|
||||
fn main() {
|
||||
let running = setupctrlc();
|
||||
let username = std::env::args().nth(1).expect("no name given");
|
||||
let public_key = std::env::args().nth(2).expect("no public key given");
|
||||
println!("Name: {}, Public key: {}", username, public_key);
|
||||
@ -18,7 +24,6 @@ fn main() {
|
||||
//send username and public key to server
|
||||
clichess::write_to_stream(&mut stream, username);
|
||||
clichess::write_to_stream(&mut stream, public_key);
|
||||
let mut buffer = String::new();
|
||||
let (client, chess) = get_connection_info_from_stream(&stream);
|
||||
//First prompt when connecting to the server
|
||||
println!(
|
||||
@ -28,6 +33,7 @@ fn main() {
|
||||
);
|
||||
//then we get the initial role of the connected client.
|
||||
let mut current_position = chess;
|
||||
let input_buffer = setup_input_buffer();
|
||||
loop {
|
||||
println!(
|
||||
"{}",
|
||||
@ -39,18 +45,18 @@ fn main() {
|
||||
}
|
||||
if clichess::is_player_turn(&client, current_position.turn()) {
|
||||
//it's the user turn, taking user input
|
||||
io::stdin().read_line(&mut buffer).unwrap();
|
||||
println!("trying to play {}", buffer);
|
||||
clichess::write_to_stream(&mut stream, String::from(buffer.trim()));
|
||||
buffer.clear();
|
||||
let input = read_user_input(running.clone(), input_buffer.clone());
|
||||
println!("trying to play {}", input);
|
||||
clichess::write_to_stream(&mut stream, String::from(input.trim()));
|
||||
if input.trim() == "exit" {
|
||||
break;
|
||||
}
|
||||
}
|
||||
//update position after playing.
|
||||
current_position = get_current_position(&stream);
|
||||
|
||||
//come back at the beginning of the loop to wait for incoming moves.
|
||||
}
|
||||
match current_position.outcome() {
|
||||
None => panic!("Game should be over."),
|
||||
None => println!("Bye"),
|
||||
Some(Outcome::Draw) => println!("Draw game."),
|
||||
Some(Outcome::Decisive { winner }) => {
|
||||
if winner == Color::White {
|
||||
@ -62,9 +68,62 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_input_buffer() -> Arc<Mutex<String>> {
|
||||
let buf = Arc::new(Mutex::new(String::new()));
|
||||
let buf2 = buf.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
let mut buffer = String::new();
|
||||
//wait for user input
|
||||
io::stdin().read_line(&mut buffer).unwrap();
|
||||
{
|
||||
let mut user_input = buf2.lock().unwrap();
|
||||
if user_input.is_empty() {
|
||||
*user_input = buffer;
|
||||
} else {
|
||||
println!("It's not your turn !");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
buf
|
||||
}
|
||||
|
||||
fn setupctrlc() -> Arc<AtomicBool> {
|
||||
let running = Arc::new(AtomicBool::new(true));
|
||||
let r = running.clone();
|
||||
ctrlc::set_handler(move || {
|
||||
r.store(false, Ordering::SeqCst);
|
||||
})
|
||||
.expect("Error setting Ctrl-C handler");
|
||||
running
|
||||
}
|
||||
|
||||
fn read_user_input(running: Arc<AtomicBool>, input_buffer: Arc<Mutex<String>>) -> String {
|
||||
let mut input = String::new();
|
||||
while running.load(Ordering::SeqCst) {
|
||||
thread::sleep(time::Duration::from_millis(10));
|
||||
{
|
||||
let user_input = input_buffer.lock().unwrap();
|
||||
if user_input.is_empty() {
|
||||
continue;
|
||||
} else {
|
||||
input = user_input.clone();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if running.load(Ordering::SeqCst) {
|
||||
input
|
||||
} else {
|
||||
String::from("exit")
|
||||
}
|
||||
}
|
||||
|
||||
//wait for next position from server, then return the current board.
|
||||
fn get_current_position(stream: &UnixStream) -> Chess {
|
||||
let response = clichess::read_line_from_stream(&stream);
|
||||
let response = clichess::read_line_from_stream(&stream).expect("Server disconnected.");
|
||||
parse_position(&response)
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,17 @@ fn handle_client(mut stream: UnixStream, server: Server) {
|
||||
if clichess::is_player_turn(&client, player_turn) {
|
||||
//let go of the lock while waiting for user input.
|
||||
println!("server {}, waiting for client move..", server.id);
|
||||
let input = clichess::read_line_from_stream(&stream);
|
||||
let input;
|
||||
match clichess::read_line_from_stream(&stream) {
|
||||
Ok(i) => input = i,
|
||||
Err(e) => {
|
||||
println!("Error while getting user input: {}", e);
|
||||
break;
|
||||
}
|
||||
};
|
||||
if input == "exit" {
|
||||
break;
|
||||
}
|
||||
{
|
||||
let mut chess = server.chess_position.lock().unwrap();
|
||||
let clients = server.clients.lock().unwrap();
|
||||
@ -109,6 +119,7 @@ fn handle_client(mut stream: UnixStream, server: Server) {
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("Client disconnected.")
|
||||
}
|
||||
|
||||
fn create_client(server: &Server, stream: &UnixStream) -> Client {
|
||||
@ -120,12 +131,12 @@ fn create_client(server: &Server, stream: &UnixStream) -> Client {
|
||||
//first, username.
|
||||
reader
|
||||
.read_line(&mut buf)
|
||||
.expect("Server closed connection.");
|
||||
.expect("Client closed connection.");
|
||||
let username = String::from(buf.trim());
|
||||
buf.clear();
|
||||
reader
|
||||
.read_line(&mut buf)
|
||||
.expect("Server closed connection.");
|
||||
.expect("Client closed connection.");
|
||||
let public_key = String::from(buf.trim());
|
||||
let role = match server.id {
|
||||
0 => UserRole::White,
|
||||
|
@ -4,6 +4,7 @@ use shakmaty::san::ParseSanError;
|
||||
use shakmaty::san::San;
|
||||
use shakmaty::san::SanError;
|
||||
use shakmaty::{Chess, Color, IllegalMoveError, Position, Setup, Square};
|
||||
use std::io;
|
||||
use std::fmt;
|
||||
use std::io::prelude::*;
|
||||
use std::io::{BufReader, Write};
|
||||
@ -186,12 +187,12 @@ fn piece_char_to_utf8(piece: char) -> char {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_line_from_stream(stream: &UnixStream) -> String {
|
||||
pub fn read_line_from_stream(stream: &UnixStream) -> Result<String, io::Error> {
|
||||
let mut result = String::new();
|
||||
let mut reader = BufReader::new(stream);
|
||||
|
||||
reader.read_line(&mut result).unwrap();
|
||||
String::from(result.trim_end())
|
||||
reader.read_line(&mut result)?;
|
||||
Ok(String::from(result.trim_end()))
|
||||
}
|
||||
|
||||
pub fn write_to_stream(stream: &mut UnixStream, msg: String) {
|
||||
|
Reference in New Issue
Block a user