added network Manager

tl;dr, as the title says
This commit is contained in:
michael-bailey 2022-02-19 00:53:18 +00:00
parent 8e519c5fa0
commit bed642a31d
6 changed files with 246 additions and 11 deletions

View File

@ -0,0 +1,21 @@
use crate::managers::NetworkManagerMessage;
pub enum WorkerMessage {
Info {
server_name: String,
server_owner: String,
},
Error(&'static str),
}
impl From<NetworkManagerMessage> for WorkerMessage {
fn from(other: NetworkManagerMessage) -> Self {
use WorkerMessage::{Info as NewInfo, Error as NewError};
use NetworkManagerMessage::{Info as OldInfo, Error};
match other {
OldInfo {server_name, server_owner}
=> NewInfo {server_owner,server_name},
_ => todo!()
}
}
}

View File

@ -1,19 +1,34 @@
mod worker;
mod managers;
mod WorkerMessage;
use worker::Worker;
use cursive::{Cursive, CursiveExt};
use cursive::menu::{Item, Tree};
use cursive::traits::Nameable;
use cursive::views::{Dialog, TextView};
fn main() {
let mut app = Cursive::default();
let workerStream = Worker::new(app.cb_sink().clone()).start();
let workerStream =
Worker::new(app.cb_sink().clone()).start();
app.set_user_data(workerStream);
app.add_layer(Dialog::new()
.content(TextView::new("Hello world").with_name("TextView"))
.button("close", |s| s.quit()));
app.menubar().autohide = false;
app.menubar().add_subtree(
"Application",
Tree::new()
.item(
Item::leaf("About", |s| s.quit())
).delimiter().item(
Item::leaf("Quit",|s| s.quit())
)
);
app.set_fps(30);
app.run();
}

View File

@ -0,0 +1,149 @@
use std::io::{Error, ErrorKind};
use std::sync::Arc;
use std::time::Duration;
use cursive::views::{Dialog, TextView};
use tokio::sync::Mutex;
use tokio::time::sleep;
use async_trait::async_trait;
use tokio::net::ToSocketAddrs;
use tokio::sync::mpsc::Sender;
use serverlib::Server;
use foundation::ClientDetails;
use foundation::connection::Connection;
use foundation::messages::client::{ClientStreamIn, ClientStreamOut};
use foundation::messages::network::{NetworkSockIn, NetworkSockOut};
use foundation::prelude::IManager;
use crate::managers::NetworkManagerMessage;
pub struct NetworkManager<M>
where M: From<NetworkManagerMessage> {
server_connection: Mutex<Option<Connection>>,
cursive: Sender<M>,
}
impl<M> NetworkManager<M>
where M: From<NetworkManagerMessage> {
pub fn new(sender: Sender<M>) -> Arc<Self> {
Arc::new(NetworkManager {
server_connection: Mutex::new(None),
cursive: sender,
})
}
pub async fn info<T: ToSocketAddrs>(self: &Arc<Self>, host: T) -> Result<NetworkManagerMessage, Error> {
let connection= Connection::new();
println!("Created connection");
connection.connect(host).await?;
let req = connection.read().await?;
println!("request: {:?}", req);
if let NetworkSockOut::Request = req {
connection.write::<NetworkSockIn>(NetworkSockIn::Info)
.await?;
return Ok(connection.read::<NetworkSockOut>()
.await?.into());
} else {
Err(Error::new(ErrorKind::ConnectionAborted, "Request not received"))
}
}
pub async fn login(self: &Arc<Self>, host: String, id: String, username: String) {
let connection= Connection::new();
let _ = connection.connect(host);
// connection.write(NetworkSockIn::Connect {}).await;
let mut lock = self.server_connection.lock().await;
*lock = Some(connection);
}
pub async fn logout() {
}
pub async fn update() {
}
async fn start(self: Arc<Self>) {
let network_manager = self.clone();
tokio::spawn(async {
});
}
}
#[async_trait]
impl<M: 'static> IManager for NetworkManager<M>
where M: From<NetworkManagerMessage> + Send {
async fn run(self: Arc<Self>) {
let networkManager = self.clone();
loop {
sleep(Duration::new(1,0)).await;
println!("networkManager tick")
}
}
async fn start(self: &Arc<Self>) {
let network_manager = self.clone();
tokio::spawn(
network_manager.run()
);
}
}
#[cfg(test)]
mod test {
use std::future::Future;
use std::panic;
use tokio::sync::mpsc::channel;
use serverlib::Server;
use crate::managers::Network::NetworkManagerMessage;
use crate::managers::Network::NetworkManagerMessage::Info;
use crate::managers::NetworkManager;
async fn wrap_setup<T,F>(test: T)
where T: FnOnce(u16) -> F,
F: Future
{
let server = Server::new().unwrap();
let port = server.port();
tokio::spawn(
async move {
server.start().await;
}
);
test(port).await;
}
#[tokio::test]
async fn create_network_manager() {
use NetworkManagerMessage::Info;
let (tx,rx) =
channel::<NetworkManagerMessage>(16);
wrap_setup(|port| {
async move {
let network = NetworkManager::new(tx);
let info = network.info(format!("localhost:{}", port)).await.expect("Failed to fetch info");
assert_eq!(info, Info {
server_name: "oof".to_string(),
server_owner: "michael".to_string()
});
}
}).await;
}
// #[tokio::test]
// async fn fetch_server_info() {
// wrap_setup(|port| {
// async move {
//
// }
// })
// }
}

View File

@ -0,0 +1,38 @@
use foundation::ClientDetails;
use foundation::messages::network::NetworkSockOut;
#[derive(Debug)]
pub enum NetworkManagerMessage {
Users(Vec<ClientDetails>),
Info {
server_name: String,
server_owner: String,
},
Error(&'static str)
}
impl From<NetworkSockOut> for NetworkManagerMessage {
fn from(other: NetworkSockOut) -> Self {
use NetworkSockOut::{GotInfo as OldInfo};
use NetworkManagerMessage::{Info as NewInfo, Error};
match other {
OldInfo {server_name,server_owner} => NewInfo {server_name,server_owner},
_ => Error("Error occurred with conversion")
}
}
}
impl PartialEq for NetworkManagerMessage {
fn eq(&self, other: &Self) -> bool {
use NetworkManagerMessage::Info;
match self {
Info {server_owner, server_name} => {
if let Info {server_owner: other_owner,server_name: other_name} = other {
return server_owner == other_owner && server_name == other_name;
}
false
}
_ => {false}
}
}
}

View File

@ -0,0 +1,7 @@
mod Network;
#[path = "NetworkManagerMessage.rs"]
mod Message;
pub use Network::NetworkManager;
pub use Message::NetworkManagerMessage;

View File

@ -1,3 +1,4 @@
use std::marker::PhantomData;
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::thread::spawn;
@ -6,25 +7,24 @@ use std::time::Duration;
use crossbeam_channel::Sender as CrossSender;
use cursive::backends::curses::n::ncurses::LcCategory::numeric;
use tokio::runtime::Runtime;
use tokio::select;
use tokio::sync::mpsc::{channel, Sender as TokioSender};
use tokio::sync::Mutex;
use tokio::time::sleep;
use foundation::ClientDetails;
use crate::{Cursive, TextView};
use crate::managers::NetworkManager;
pub enum WorkerMessage {
Disconnect,
Connect {username: String},
}
use crate::managers::{NetworkManager, NetworkManagerMessage};
use crate::WorkerMessage::WorkerMessage;
pub type CursiveSender = CrossSender<Box<dyn FnOnce(&mut Cursive) + Send>>;
pub struct Worker {
pub struct Worker
{
cursive_sender: CursiveSender,
network_manager: NetworkManager,
network_manager: Arc<NetworkManager<WorkerMessage>>,
number: Arc<Mutex<usize>>,
@ -33,10 +33,14 @@ pub struct Worker {
impl Worker {
pub fn new(sender: CursiveSender) -> Worker {
let (tx,rx) = channel::<WorkerMessage>(16);
Worker {
cursive_sender: sender,
network_manager: NetworkManager::new(tx.clone()),
number: Arc::new(Mutex::new(0)),
user_details: Mutex::new(None)
user_details: Mutex::new(None),
cursive_sender: sender
}
}
@ -47,6 +51,7 @@ impl Worker {
let sender = self.cursive_sender.clone();
let rt = Runtime::new().unwrap();
let tmp_num = self.number.clone();
let network_manager = self.network_manager.clone();
rt.block_on(async move {
let a = &tmp_num;
loop {