Implements a simple command structure

This commit is contained in:
Gregor Reitzenstein 2020-11-03 12:39:51 +01:00
parent d074a551ad
commit 97bc38e74a
2 changed files with 30 additions and 23 deletions

View File

@ -5,8 +5,6 @@ use std::sync::{Arc, Mutex, MutexGuard};
use futures::prelude::*;
use futures_signals::signal::{Mutable, Signal, MutableSignalCloned, MutableLockMut};
use linefeed::memory::MemoryTerminal;
use crate::input::Inputs;
use crate::schema::API;
@ -33,8 +31,9 @@ pub struct Sute<'a, S> {
// TODO: BE SMART. Inputs change the state, resize signals change the state, futures completing
// change the state.
pub state: Mutable<SuteState<'a>>,
statesig: MutableSignalCloned<SuteState<'a>>,
state: SuteState<'a>,
modified: bool,
signal: S,
inputs: Inputs,
api: Option<API>,
@ -42,13 +41,14 @@ pub struct Sute<'a, S> {
}
impl<'a, S: Unpin> Sute<'a, S> {
pub fn new(term: MemoryTerminal, s: S, log: Logger, drain: Arc<LogDrain<'a>>, api: API) -> Self {
let inputs = Inputs::new(term);
let state = Mutable::new(SuteState::new(drain));
pub fn new(s: S, log: Logger, drain: Arc<LogDrain<'a>>, api: API) -> Self {
let inputs = Inputs::new();
let state = SuteState::new(drain);
Self {
statesig: state.signal_cloned(),
state: state,
modified: false,
signal: s,
inputs: inputs,
api: Some(api),
@ -57,15 +57,20 @@ impl<'a, S: Unpin> Sute<'a, S> {
}
fn run_cmd(&mut self, cmd: String) {
if cmd == "quit" {
self.state.running = false;
} else {
info!(self.log, "Issues unknown cmd: {}", cmd);
}
}
fn handle_resize(&mut self, new_size: (u16,u16)) {
(self.state.lock_mut()).size = new_size;
self.state.size = new_size;
self.modified = true
}
pub fn get_state(&self) -> SuteState<'a> {
self.state.get_cloned()
self.state.clone()
}
}
@ -76,7 +81,7 @@ impl<'a, S: Signal<Item=(u16,u16)> + Unpin> Signal for Sute<'a, S> {
Poll::Ready(Some(line)) => self.run_cmd(line),
// If the input closes stop the program
Poll::Ready(None) => {
self.state.lock_mut().running = false;
self.state.running = false;
return Poll::Ready(None);
},
Poll::Pending => { },
@ -85,15 +90,18 @@ impl<'a, S: Signal<Item=(u16,u16)> + Unpin> Signal for Sute<'a, S> {
self.handle_resize(size);
}
// TODO chunk this?
Pin::new(&mut self.statesig).poll_change(cx)
if self.modified {
Poll::Ready(Some(self.get_state()))
} else {
Poll::Pending
}
}
}
impl <'a, S> Future for Sute<'a, S> {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
if self.state.lock_ref().running {
if self.state.running {
Poll::Pending
} else {
Poll::Ready(())

View File

@ -69,15 +69,15 @@ fn main() -> Result<(), io::Error> {
let (rpc_future, mut api) = schema::bootstrap(log.clone(), stream);
let app = app::Sute::new(term.clone(), resize, log.clone(), drain, api);
let app = app::Sute::new(resize, log.clone(), drain, api);
let mut stream = app.to_stream();
let ui_future = async move {
let stdout = io::stdout().into_raw_mode()?;
let backend = TermionBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
terminal.hide_cursor()?;
let ui_future = async move {
// Refresh the screen once by resizing the terminal
if let Ok((x,y)) = termion::terminal_size() {
@ -102,10 +102,9 @@ fn main() -> Result<(), io::Error> {
Ok(())
};
lex.spawn(rpc_future).detach();
let r: Task<Result<(), io::Error>> = lex.spawn(ui_future);
//lex.spawn(rpc_future).detach();
let r: Result<(), io::Error> = smol::block_on(lex.run(ui_future));
//smol::block_on(lex.run(Box::pin(app)));
smol::block_on(r);
Ok(())
}