mirror of
https://codeberg.org/demostf/sync.git
synced 2026-06-03 16:44:07 +02:00
cleanup
This commit is contained in:
parent
1c251412de
commit
b298c8d2d9
1 changed files with 115 additions and 59 deletions
150
src/main.rs
150
src/main.rs
|
|
@ -1,9 +1,9 @@
|
||||||
use mio::Token;
|
use mio::Token;
|
||||||
use std::collections::HashMap;
|
|
||||||
use ws::{listen, Handler, Sender, Result, Message, CloseCode, Error};
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use ws::{listen, CloseCode, Error, Handler, Message, Result, Sender};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
|
|
@ -17,7 +17,7 @@ enum SyncCommand {
|
||||||
|
|
||||||
struct Session {
|
struct Session {
|
||||||
owner: Token,
|
owner: Token,
|
||||||
clients: HashMap<Token, Sender>,
|
clients: HashMap<Token, Client>,
|
||||||
tick: u64,
|
tick: u64,
|
||||||
playing: bool,
|
playing: bool,
|
||||||
}
|
}
|
||||||
|
|
@ -31,26 +31,67 @@ impl Session {
|
||||||
tick: 0,
|
tick: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn join(&mut self, client: &Client) {
|
||||||
|
self.clients.insert(client.token(), client.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Session {
|
impl Session {
|
||||||
pub fn send_command(&self, command: &SyncCommand) {
|
pub fn send_command(&self, command: &SyncCommand) {
|
||||||
let command_text = serde_json::to_string(command).unwrap();
|
let command_text = serde_json::to_string(command).unwrap();
|
||||||
for client in self.clients.values() {
|
for client in self.clients.values() {
|
||||||
client.send(Message::from(command_text.clone())).ok();
|
client.send(&command_text).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_command(command: SyncCommand, sessions: &mut HashMap<String, Session>, client: Sender) {
|
trait ClientTrait {
|
||||||
match command {
|
fn send(&self, msg: &str) -> Result<()>;
|
||||||
SyncCommand::Create { session } => {
|
|
||||||
sessions.insert(session, Session::new(client.token()));
|
fn token(&self) -> Token;
|
||||||
}
|
}
|
||||||
SyncCommand::Join { session: session_name } => {
|
|
||||||
match sessions.get_mut(&session_name) {
|
#[derive(Clone, Debug)]
|
||||||
|
struct Client(Sender);
|
||||||
|
|
||||||
|
impl ClientTrait for Client {
|
||||||
|
fn send(&self, msg: &str) -> Result<()> {
|
||||||
|
self.0.send(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn token(&self) -> Token {
|
||||||
|
self.0.token()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Sender> for Client {
|
||||||
|
fn from(sender: Sender) -> Self {
|
||||||
|
Client(sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Server {
|
||||||
|
out: Client,
|
||||||
|
sessions: Rc<RefCell<HashMap<String, Session>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_command(
|
||||||
|
command: SyncCommand,
|
||||||
|
sender: &Client,
|
||||||
|
sessions: &RefCell<HashMap<String, Session>>,
|
||||||
|
) {
|
||||||
|
match &command {
|
||||||
|
SyncCommand::Create { session } => {
|
||||||
|
sessions
|
||||||
|
.borrow_mut()
|
||||||
|
.insert(session.clone(), Session::new(sender.token()));
|
||||||
|
}
|
||||||
|
SyncCommand::Join {
|
||||||
|
session: session_name,
|
||||||
|
} => match sessions.borrow_mut().get_mut(session_name) {
|
||||||
Some(session) => {
|
Some(session) => {
|
||||||
session.clients.insert(client.token(), client);
|
session.join(sender);
|
||||||
session.send_command(&SyncCommand::Tick {
|
session.send_command(&SyncCommand::Tick {
|
||||||
tick: session.tick,
|
tick: session.tick,
|
||||||
session: session_name.clone(),
|
session: session_name.clone(),
|
||||||
|
|
@ -60,53 +101,59 @@ fn handle_command(command: SyncCommand, sessions: &mut HashMap<String, Session>,
|
||||||
session: session_name.clone(),
|
session: session_name.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
None => println!("session {} not found", session_name)
|
None => println!("session {} not found", session_name),
|
||||||
}
|
},
|
||||||
}
|
SyncCommand::Tick {
|
||||||
SyncCommand::Tick { tick, session: session_name } => {
|
|
||||||
match sessions.get_mut(&session_name) {
|
|
||||||
Some(session) => {
|
|
||||||
if session.owner == client.token() {
|
|
||||||
session.tick = tick;
|
|
||||||
session.send_command(&SyncCommand::Tick {
|
|
||||||
tick,
|
tick,
|
||||||
session: session_name,
|
session: session_name,
|
||||||
});
|
} => update_session_and_forward(
|
||||||
}
|
sender,
|
||||||
}
|
sessions,
|
||||||
None => println!("session {} not found", session_name)
|
session_name,
|
||||||
}
|
|session| session.tick = *tick,
|
||||||
}
|
&command,
|
||||||
SyncCommand::Play { play, session: session_name } => {
|
),
|
||||||
match sessions.get_mut(&session_name) {
|
SyncCommand::Play {
|
||||||
Some(session) => {
|
|
||||||
if session.owner == client.token() {
|
|
||||||
session.playing = play;
|
|
||||||
session.send_command(&SyncCommand::Play {
|
|
||||||
play,
|
play,
|
||||||
session: session_name,
|
session: session_name,
|
||||||
});
|
} => update_session_and_forward(
|
||||||
}
|
sender,
|
||||||
}
|
sessions,
|
||||||
None => println!("session {} not found", session_name)
|
session_name,
|
||||||
}
|
|session| session.playing = *play,
|
||||||
}
|
&command,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Server {
|
fn update_session_and_forward<F>(
|
||||||
out: Sender,
|
sender: &Client,
|
||||||
sessions: Rc<RefCell<HashMap<String, Session>>>,
|
sessions: &RefCell<HashMap<String, Session>>,
|
||||||
|
session_name: &str,
|
||||||
|
mut update_fn: F,
|
||||||
|
command: &SyncCommand,
|
||||||
|
) where
|
||||||
|
F: FnMut(&mut Session),
|
||||||
|
{
|
||||||
|
match sessions.borrow_mut().get_mut(session_name) {
|
||||||
|
Some(session) => {
|
||||||
|
if session.owner == sender.token() {
|
||||||
|
update_fn(session);
|
||||||
|
session.send_command(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => println!("session {} not found", session_name),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handler for Server {
|
impl Handler for Server {
|
||||||
fn on_message(&mut self, msg: Message) -> Result<()> {
|
fn on_message(&mut self, msg: Message) -> Result<()> {
|
||||||
match serde_json::from_str::<SyncCommand>(msg.as_text().unwrap_or_default()) {
|
match serde_json::from_str::<SyncCommand>(msg.as_text().unwrap_or_default()) {
|
||||||
Ok(command) => {
|
Ok(command) => {
|
||||||
handle_command(command, &mut self.sessions.borrow_mut(), self.out.clone());
|
handle_command(command, &self.out, &self.sessions);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(_) => Ok(())
|
Err(_) => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,7 +180,11 @@ fn main() {
|
||||||
|
|
||||||
let sessions: Rc<RefCell<HashMap<String, Session>>> = Rc::new(RefCell::new(HashMap::new()));
|
let sessions: Rc<RefCell<HashMap<String, Session>>> = Rc::new(RefCell::new(HashMap::new()));
|
||||||
|
|
||||||
listen(listen_address, |out| { Server { out, sessions: sessions.clone() } }).unwrap()
|
listen(listen_address, |out| Server {
|
||||||
|
out: out.into(),
|
||||||
|
sessions: sessions.clone(),
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
@ -143,6 +194,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_deserialize() {
|
fn test_deserialize() {
|
||||||
let input = "{\"type\": \"create\", \"session\": \"foo\"}";
|
let input = "{\"type\": \"create\", \"session\": \"foo\"}";
|
||||||
assert_eq!(SyncCommand::Create { session: "foo".to_string() }, serde_json::from_str(input).unwrap());
|
assert_eq!(
|
||||||
|
SyncCommand::Create {
|
||||||
|
session: "foo".to_string()
|
||||||
|
},
|
||||||
|
serde_json::from_str(input).unwrap()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue