Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement TINPUT/ONEINPUT #9

Merged
merged 6 commits into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions HTTP.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,26 @@ struct Ret {
lines: [{parts: [ConsoleLinePart]}]
}

enum InputRequest {
struct InputRequest {
generation: u32,
ty: InputRequestType,
timeout: Option<Timeout>,
is_one: bool,
}

enum InputRequestType {
Anykey,
EnterKey,
Int,
Str,
}

struct Timeout {
timeout: u32,
show_timer: bool,
timeout_msg: String,
}

enum ConsoleLinePart {
Text(String, TextStyle),
Line(String, TextStyle),
Expand Down Expand Up @@ -56,4 +69,10 @@ Int일시엔 꼭 숫자 문자열로 전송 Str이면 그냥 그대로 전송

웹소켓 연결 가능

연결시 UI가 업데이트 될때마다 아무 메세지를 전송함
연결시 이밴트 발생시 메세지로 전송해줌

## 이밴트 목록

* REDRAW(1)

* TIMEOUT(2)
17 changes: 17 additions & 0 deletions erars-ast/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ pub enum Value {
String(String),
}

impl Default for Value {
fn default() -> Self {
Value::Int(0)
}
}

impl Value {
pub const ZERO: Value = Value::Int(0);
pub const ONE: Value = Value::Int(1);
Expand Down Expand Up @@ -69,6 +75,17 @@ impl TryFrom<Value> for usize {
}
}

impl TryFrom<Value> for u32 {
type Error = Error;

fn try_from(value: Value) -> Result<Self, Self::Error> {
match value {
Value::Int(i) => Ok(i.try_into()?),
_ => bail!("Value is not int"),
}
}
}

impl TryFrom<Value> for i64 {
type Error = Error;

Expand Down
101 changes: 92 additions & 9 deletions src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ use regex::Regex;
use serde::{Deserialize, Serialize};
use smol_str::SmolStr;
use std::collections::VecDeque;
use std::sync::atomic::AtomicU32;
use std::sync::atomic::{AtomicBool, Ordering::SeqCst};
use std::sync::Arc;
use std::time::Duration;
use tokio::time::Instant;

#[cfg(feature = "stdio-backend")]
mod stdio_backend;
Expand Down Expand Up @@ -130,9 +132,10 @@ impl ConsoleLine {
}

/// Used by ui backend
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Debug, PartialEq, Eq)]
struct VirtualConsole {
pub current_req: Option<InputRequest>,
timeout: Option<(Instant, u32, Value)>,
lines: Vec<ConsoleLine>,
style: TextStyle,
bg_color: Color,
Expand All @@ -143,6 +146,7 @@ impl VirtualConsole {
fn new() -> Self {
Self {
current_req: None,
timeout: None,
lines: Vec::new(),
style: TextStyle {
color: Color([255, 255, 255]),
Expand All @@ -164,8 +168,12 @@ impl VirtualConsole {
}
match com {
ConsoleMessage::Input(req) => {
if self.current_req.is_some() {
log::warn!("Input overwrited");
if let Some(timeout) = req.timeout.as_ref() {
self.timeout = Some((
Instant::now() + Duration::from_millis(timeout.timeout as _),
req.generation,
timeout.default_value.clone(),
));
}
self.current_req = Some(req);
}
Expand Down Expand Up @@ -250,13 +258,56 @@ bitflags::bitflags! {
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum InputRequest {
Anykey,
pub enum InputRequestType {
AnyKey,
EnterKey,
Int,
Str,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
/// input timeout
pub struct Timeout {
pub timeout: u32,
#[serde(skip)]
pub default_value: Value,
pub timeout_msg: Option<String>,
pub show_timer: bool,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct InputRequest {
/// InputRequest generation
pub generation: u32,
/// type of request
pub ty: InputRequestType,
/// whether is ONEINPUT or not
pub is_one: bool,
#[serde(skip_serializing_if = "Option::is_none")]
/// TINPUT
pub timeout: Option<Timeout>,
}

impl InputRequest {
pub fn normal(gen: u32, ty: InputRequestType) -> Self {
Self {
generation: gen,
ty,
is_one: false,
timeout: None,
}
}

pub fn oneinput(gen: u32, ty: InputRequestType) -> Self {
Self {
generation: gen,
ty,
is_one: true,
timeout: None,
}
}
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ConsoleResult {
Quit,
Expand Down Expand Up @@ -318,7 +369,12 @@ impl ConsoleSender {
Value::Int(i) => break Some(i),
}
} else {
self.chan.send_msg(ConsoleMessage::Input(InputRequest::Int));
self.chan.send_msg(ConsoleMessage::Input(InputRequest {
generation: self.chan.input_gen(),
ty: InputRequestType::Int,
is_one: false,
timeout: None,
}));
let ret = self.chan.recv_ret();

match ret {
Expand All @@ -330,10 +386,18 @@ impl ConsoleSender {
}
}

pub fn input_gen(&self) -> u32 {
self.chan.input_gen()
}

pub fn input(&mut self, req: InputRequest) -> ConsoleResult {
self.request_redraw();

if matches!(req, InputRequest::Anykey | InputRequest::EnterKey) && !self.inputs.is_empty() {
if matches!(
req.ty,
InputRequestType::AnyKey | InputRequestType::EnterKey
) && !self.inputs.is_empty()
{
ConsoleResult::Value(0.into())
} else if let Some(i) = self.inputs.pop_front() {
ConsoleResult::Value(i)
Expand Down Expand Up @@ -476,6 +540,7 @@ pub struct ConsoleChannel {
exit_fn: Mutex<Option<Box<dyn Fn() + Send + Sync>>>,
delay_redraw: AtomicBool,
delay_exit: AtomicBool,
input_generation: AtomicU32,
console: (Sender<ConsoleMessage>, Receiver<ConsoleMessage>),
ret: (Sender<ConsoleResult>, Receiver<ConsoleResult>),
}
Expand All @@ -487,11 +552,16 @@ impl ConsoleChannel {
exit_fn: Mutex::new(None),
delay_redraw: AtomicBool::new(false),
delay_exit: AtomicBool::new(false),
input_generation: AtomicU32::new(0),
console: bounded(256),
ret: bounded(8),
}
}

pub fn input_gen(&self) -> u32 {
self.input_generation.load(SeqCst)
}

pub fn set_redraw_fn(&self, f: impl Fn() + Send + Sync + 'static) {
let mut redraw_fn = self.redraw_fn.lock();

Expand Down Expand Up @@ -542,8 +612,21 @@ impl ConsoleChannel {
self.console.1.recv_timeout(Duration::from_millis(50)).ok()
}

pub fn send_ret(&self, ret: ConsoleResult) {
self.ret.0.send(ret).unwrap()
pub fn send_quit(&self) {
self.ret.0.send(ConsoleResult::Quit).unwrap()
}

pub fn send_input(&self, input: Value, gen: u32) -> bool {
if self
.input_generation
.compare_exchange(gen, gen.wrapping_add(1), SeqCst, SeqCst)
.is_ok()
{
self.ret.0.send(ConsoleResult::Value(input)).unwrap();
true
} else {
false
}
}

pub fn recv_ret(&self) -> ConsoleResult {
Expand Down
Loading