rust/hedgewars-server/src/server/io.rs
changeset 14800 f43ab2bd76ae
parent 14478 98ef2913ec73
child 14801 65861ba8b4e8
--- a/rust/hedgewars-server/src/server/io.rs	Tue Apr 09 00:45:14 2019 +0200
+++ b/rust/hedgewars-server/src/server/io.rs	Tue Apr 09 21:08:35 2019 +0300
@@ -1,49 +1,73 @@
 use std::{
     fs::{File, OpenOptions},
     io::{Error, ErrorKind, Read, Result, Write},
+    sync::mpsc,
+    thread,
 };
 
-pub trait HWServerIO {
-    fn write_file(&mut self, name: &str, content: &str) -> Result<()>;
-    fn read_file(&mut self, name: &str) -> Result<String>;
+use crate::server::{
+    database::Database,
+    handlers::{IoResult, IoTask},
+};
+use mio::{Evented, Poll, PollOpt};
+use mio_extras::channel;
+
+pub type RequestId = u32;
+
+pub struct IOThread {
+    core_tx: mpsc::Sender<(RequestId, IoTask)>,
+    core_rx: channel::Receiver<(RequestId, IoResult)>,
 }
 
-pub struct EmptyServerIO {}
-
-impl EmptyServerIO {
+impl IOThread {
     pub fn new() -> Self {
-        Self {}
-    }
-}
+        let (core_tx, io_rx) = mpsc::channel();
+        let (io_tx, core_rx) = channel::channel();
+
+        let mut db = Database::new();
+        db.connect("localhost");
 
-impl HWServerIO for EmptyServerIO {
-    fn write_file(&mut self, _name: &str, _content: &str) -> Result<()> {
-        Ok(())
+        thread::spawn(move || {
+            while let Ok((request_id, task)) = io_rx.try_recv() {
+                match task {
+                    IoTask::GetAccount {
+                        nick,
+                        protocol,
+                        password_hash,
+                        client_salt,
+                        server_salt,
+                    } => {
+                        if let Ok(account) = db.get_account(
+                            &nick,
+                            protocol,
+                            &password_hash,
+                            &client_salt,
+                            &server_salt,
+                        ) {
+                            io_tx.send((request_id, IoResult::Account(account)));
+                        }
+                    }
+                }
+            }
+        });
+
+        Self { core_rx, core_tx }
     }
 
-    fn read_file(&mut self, _name: &str) -> Result<String> {
-        Ok("".to_string())
+    pub fn send(&self, request_id: RequestId, task: IoTask) {
+        self.core_tx.send((request_id, task)).unwrap();
     }
-}
 
-pub struct FileServerIO {}
+    pub fn try_recv(&self) -> Option<(RequestId, IoResult)> {
+        match self.core_rx.try_recv() {
+            Ok(result) => Some(result),
+            Err(mpsc::TryRecvError::Empty) => None,
+            Err(mpsc::TryRecvError::Disconnected) => unreachable!(),
+        }
+    }
 
-impl FileServerIO {
-    pub fn new() -> Self {
-        Self {}
+    pub fn register_rx(&self, poll: &mio::Poll, token: mio::Token) -> Result<()> {
+        self.core_rx
+            .register(poll, token, mio::Ready::readable(), PollOpt::edge())
     }
 }
-
-impl HWServerIO for FileServerIO {
-    fn write_file(&mut self, name: &str, content: &str) -> Result<()> {
-        let mut writer = OpenOptions::new().create(true).write(true).open(name)?;
-        writer.write_all(content.as_bytes())
-    }
-
-    fn read_file(&mut self, name: &str) -> Result<String> {
-        let mut reader = File::open(name)?;
-        let mut result = String::new();
-        reader.read_to_string(&mut result)?;
-        Ok(result)
-    }
-}