From 9c55f69a91887dd2707455cad136a55bf496c3fe Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Fri, 17 Jun 2022 11:46:04 -0500 Subject: [PATCH] Experimental game controllers --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/controller.rs | 99 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 src/controller.rs diff --git a/Cargo.lock b/Cargo.lock index c551aec..cb6345d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -756,7 +756,7 @@ checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "gamenite" -version = "0.1.0" +version = "0.1.1" dependencies = [ "image", "serde", diff --git a/Cargo.toml b/Cargo.toml index 35078ee..f965bfb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "gamenite" description = "A graph library for board games" -version = "0.1.1" +version = "0.1.2" edition = "2021" license = "GPL-3.0-or-later" homepage = "https://git.danejohnson.org/dane/gamenite" diff --git a/src/controller.rs b/src/controller.rs new file mode 100644 index 0000000..4bd41b6 --- /dev/null +++ b/src/controller.rs @@ -0,0 +1,99 @@ +use std::sync::mpsc; +use mpsc::{ Sender, Receiver, SendError, RecvError }; + +use std::collections::VecDeque; + +pub struct Controller { + server: Option>, + clients: VecDeque>, +} + +pub struct Server { + txs: Vec>, + rxs: Vec>, + info: Receiver<(usize, M)>, +} + +pub struct Client { + idx: usize, + tx: Sender, + rx: Receiver, + info: Sender<(usize, M)>, +} + +impl Controller { + pub fn new(n: usize) -> Self { + let (info_tx, info_rx) = mpsc::channel::<(usize, M)>(); + let mut c = Controller { + server: Some(Server { + txs: Vec::new(), + rxs: Vec::new(), + info: info_rx, + }), + clients: VecDeque::new(), + }; + + for idx in 0..n { + let (server_tx, client_rx) = mpsc::channel(); + let (client_tx, server_rx) = mpsc::channel(); + match c.server.as_mut() { + Some(s) => { + s.txs.push(server_tx); + s.rxs.push(server_rx); + }, + None => unreachable!(), + } + c.clients.push_back(Client { + idx, + tx: client_tx, + rx: client_rx, + info: info_tx.clone(), + }); + } + + c + } + + pub fn server(&mut self) -> Option> { + self.server.take() + } + + pub fn client(&mut self) -> Option> { + self.clients.pop_front() + } +} + +impl Server { + pub fn send(&self, idx: usize, msg: M) -> Result<(), SendError> { + self.txs[idx].send(msg) + } + pub fn recv(&self, idx: usize) -> Result { + self.rxs[idx].recv() + } + pub fn info(&self) -> Result<(usize, M), RecvError> { + self.info.recv() + } +} + +impl Server +where M: Clone { + pub fn broadcast(&self, msg: M) -> Result<(), SendError> { + for tx in &self.txs { + tx.send(M::clone(&msg))?; + } + + Ok(()) + } +} + +impl Client { + pub fn send(&self, m: M) -> Result<(), SendError> { + self.tx.send(m) + } + pub fn recv(&self) -> Result { + self.rx.recv() + } + pub fn info(&self, msg: M) -> Result<(), SendError<(usize, M)>> { + self.info.send((self.idx, msg)) + } +} diff --git a/src/lib.rs b/src/lib.rs index 1603d5c..8fccf34 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,6 +25,7 @@ //! Finally, we provide an [io] package to facilitate loading and saving these boards, and a related image to //! a compressed file. pub mod io; +pub mod controller; use serde::{ Serialize, Deserialize }; use std::collections::{ HashMap, HashSet };