Create backend module for more separation

This commit is contained in:
Joscha 2022-03-05 17:07:04 +01:00
parent c36f35747f
commit 80a6582ce5
8 changed files with 63 additions and 30 deletions

6
cove-tui/src/backend.rs Normal file
View file

@ -0,0 +1,6 @@
pub mod cove;
#[derive(Debug)]
pub enum Event {
Cove(String, cove::conn::Event),
}

View file

@ -33,9 +33,10 @@ pub enum Error {
IncorrectReplyType, IncorrectReplyType,
} }
#[derive(Debug)]
pub enum Event { pub enum Event {
StateChanged, StateChanged,
// TODO Add IdentificationRequired event IdentificationRequired,
// TODO Add events for joining, parting, sending, ... // TODO Add events for joining, parting, sending, ...
} }
@ -278,7 +279,7 @@ impl CoveConnMt {
match &rpl { match &rpl {
Rpl::Room(RoomRpl::Success) => { Rpl::Room(RoomRpl::Success) => {
connected.status = Status::IdRequired(None); connected.status = Status::IdRequired(None);
conn.ev_tx.send(Event::StateChanged); conn.ev_tx.send(Event::IdentificationRequired);
} }
Rpl::Room(RoomRpl::InvalidRoom { reason }) => { Rpl::Room(RoomRpl::InvalidRoom { reason }) => {
return Err(Error::InvalidRoom(reason.clone())) return Err(Error::InvalidRoom(reason.clone()))
@ -289,7 +290,7 @@ impl CoveConnMt {
} }
Rpl::Identify(IdentifyRpl::InvalidNick { reason }) => { Rpl::Identify(IdentifyRpl::InvalidNick { reason }) => {
connected.status = Status::IdRequired(Some(reason.clone())); connected.status = Status::IdRequired(Some(reason.clone()));
conn.ev_tx.send(Event::StateChanged); conn.ev_tx.send(Event::IdentificationRequired);
} }
Rpl::Identify(IdentifyRpl::InvalidIdentity { reason }) => { Rpl::Identify(IdentifyRpl::InvalidIdentity { reason }) => {
return Err(Error::InvalidIdentity(reason.clone())) return Err(Error::InvalidIdentity(reason.clone()))

View file

@ -8,13 +8,14 @@ use tokio::sync::Mutex;
use crate::config::Config; use crate::config::Config;
use crate::never::Never; use crate::never::Never;
use super::conn::{self, CoveConn, CoveConnMt, Event}; use super::super::Event;
use super::conn::{self, CoveConn, CoveConnMt};
struct ConnConfig { struct ConnConfig {
url: String, url: String,
room: String, room: String,
timeout: Duration, timeout: Duration,
ev_tx: UnboundedSender<Event>, ev_tx: UnboundedSender<conn::Event>,
} }
impl ConnConfig { impl ConnConfig {
@ -59,7 +60,7 @@ impl CoveRoom {
let (conn, mt) = conf.new_conn().await; let (conn, mt) = conf.new_conn().await;
let room = Self { let room = Self {
name, name: name.clone(),
conn: Arc::new(Mutex::new(conn)), conn: Arc::new(Mutex::new(conn)),
dead_mans_switch: tx, dead_mans_switch: tx,
}; };
@ -68,7 +69,7 @@ impl CoveRoom {
tokio::spawn(async move { tokio::spawn(async move {
tokio::select! { tokio::select! {
_ = rx => {} // Watch dead man's switch _ = rx => {} // Watch dead man's switch
_ = Self::shovel_events(ev_rx, outer_ev_tx) => {} _ = Self::shovel_events(ev_rx, outer_ev_tx, name) => {}
_ = Self::run(conn_clone, mt, conf) => {} _ = Self::run(conn_clone, mt, conf) => {}
} }
}); });
@ -76,11 +77,15 @@ impl CoveRoom {
room room
} }
async fn shovel_events<E>(mut ev_rx: UnboundedReceiver<Event>, ev_tx: UnboundedSender<E>) async fn shovel_events<E>(
where mut ev_rx: UnboundedReceiver<conn::Event>,
ev_tx: UnboundedSender<E>,
name: String,
) where
Event: Into<E>, Event: Into<E>,
{ {
while let Some(event) = ev_rx.recv().await { while let Some(event) = ev_rx.recv().await {
let event = Event::Cove(name.clone(), event);
if ev_tx.send(event.into()).is_err() { if ev_tx.send(event.into()).is_err() {
break; break;
} }

View file

@ -1,7 +1,7 @@
#![warn(clippy::use_self)] #![warn(clippy::use_self)]
pub mod backend;
mod config; mod config;
mod cove;
mod never; mod never;
mod ui; mod ui;

View file

@ -11,7 +11,9 @@ use std::collections::hash_map::Entry;
use std::collections::HashMap; use std::collections::HashMap;
use std::io::Stdout; use std::io::Stdout;
use crossterm::event::{Event, EventStream, KeyCode, KeyEvent, MouseEvent, MouseEventKind}; use crossterm::event::{
Event as CEvent, EventStream, KeyCode, KeyEvent, MouseEvent, MouseEventKind,
};
use futures::StreamExt; use futures::StreamExt;
use tokio::sync::mpsc::error::TryRecvError; use tokio::sync::mpsc::error::TryRecvError;
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
@ -19,8 +21,10 @@ use tui::backend::CrosstermBackend;
use tui::layout::{Constraint, Direction, Layout, Rect}; use tui::layout::{Constraint, Direction, Layout, Rect};
use tui::{Frame, Terminal}; use tui::{Frame, Terminal};
use crate::backend::cove::conn::Event as CoveEvent;
use crate::backend::cove::room::CoveRoom;
use crate::backend::Event as BEvent;
use crate::config::Config; use crate::config::Config;
use crate::cove::room::CoveRoom;
use crate::ui::overlays::OverlayReaction; use crate::ui::overlays::OverlayReaction;
use self::cove::CoveUi; use self::cove::CoveUi;
@ -31,24 +35,24 @@ use self::rooms::Rooms;
pub type Backend = CrosstermBackend<Stdout>; pub type Backend = CrosstermBackend<Stdout>;
#[derive(Debug)]
pub enum UiEvent {
Term(Event),
Redraw,
// TODO Add room events
}
impl From<crate::cove::conn::Event> for UiEvent {
fn from(_: crate::cove::conn::Event) -> Self {
Self::Redraw
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum RoomId { pub enum RoomId {
Cove(String), Cove(String),
} }
#[derive(Debug)]
pub enum UiEvent {
Term(CEvent),
Room(BEvent),
Redraw,
}
impl From<BEvent> for UiEvent {
fn from(event: BEvent) -> Self {
Self::Room(event)
}
}
enum EventHandleResult { enum EventHandleResult {
Continue, Continue,
Stop, Stop,
@ -138,9 +142,12 @@ impl Ui {
}; };
loop { loop {
let result = match event { let result = match event {
UiEvent::Term(Event::Key(event)) => self.handle_key_event(event).await?, UiEvent::Term(CEvent::Key(event)) => self.handle_key_event(event).await?,
UiEvent::Term(Event::Mouse(event)) => self.handle_mouse_event(event).await?, UiEvent::Term(CEvent::Mouse(event)) => self.handle_mouse_event(event).await?,
UiEvent::Term(Event::Resize(_, _)) => EventHandleResult::Continue, UiEvent::Term(CEvent::Resize(_, _)) => EventHandleResult::Continue,
UiEvent::Room(BEvent::Cove(name, event)) => {
self.handle_cove_event(name, event).await?
}
UiEvent::Redraw => EventHandleResult::Continue, UiEvent::Redraw => EventHandleResult::Continue,
}; };
match result { match result {
@ -237,6 +244,20 @@ impl Ui {
Ok(EventHandleResult::Continue) Ok(EventHandleResult::Continue)
} }
async fn handle_cove_event(
&mut self,
name: String,
event: CoveEvent,
) -> anyhow::Result<EventHandleResult> {
match event {
CoveEvent::StateChanged => {}
CoveEvent::IdentificationRequired => {
// TODO Send identification if default nick is set in config
}
}
Ok(EventHandleResult::Continue)
}
async fn render(&mut self, frame: &mut Frame<'_, Backend>) -> anyhow::Result<()> { async fn render(&mut self, frame: &mut Frame<'_, Backend>) -> anyhow::Result<()> {
let entire_area = frame.size(); let entire_area = frame.size();
let areas = Layout::default() let areas = Layout::default()

View file

@ -4,7 +4,7 @@ use tui::backend::Backend;
use tui::layout::Rect; use tui::layout::Rect;
use tui::Frame; use tui::Frame;
use crate::cove::room::CoveRoom; use crate::backend::cove::room::CoveRoom;
pub struct CoveUi { pub struct CoveUi {
room: CoveRoom, room: CoveRoom,

View file

@ -7,7 +7,7 @@ use tui::layout::Rect;
use tui::text::{Span, Spans}; use tui::text::{Span, Spans};
use tui::widgets::{Paragraph, Widget}; use tui::widgets::{Paragraph, Widget};
use crate::cove::conn::Present; use crate::backend::cove::conn::Present;
use crate::ui::styles; use crate::ui::styles;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]