|
|
@ -21,115 +21,115 @@ use web_sys::Element;
|
|
|
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
|
|
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
|
|
|
|
|
|
|
|
|
|
|
pub enum Directory {
|
|
|
|
pub enum Directory {
|
|
|
|
Home,
|
|
|
|
Home,
|
|
|
|
Projects
|
|
|
|
Projects
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub struct State {
|
|
|
|
pub struct State {
|
|
|
|
fs_root: fs::DirEntry,
|
|
|
|
fs_root: fs::DirEntry,
|
|
|
|
cwd: String,
|
|
|
|
cwd: String,
|
|
|
|
input : String,
|
|
|
|
input : String,
|
|
|
|
output : VecDeque<String>,
|
|
|
|
output : VecDeque<String>,
|
|
|
|
prompt: String,
|
|
|
|
prompt: String,
|
|
|
|
max_rows: usize,
|
|
|
|
max_rows: usize,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl State {
|
|
|
|
impl State {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
State {
|
|
|
|
State {
|
|
|
|
fs_root: fs::setup_fs(),
|
|
|
|
fs_root: fs::setup_fs(),
|
|
|
|
cwd: "/home/ashe".to_string(),
|
|
|
|
cwd: "/home/ashe".to_string(),
|
|
|
|
input : String::new(),
|
|
|
|
input : String::new(),
|
|
|
|
output : VecDeque::new(),
|
|
|
|
output : VecDeque::new(),
|
|
|
|
prompt: String::new(),
|
|
|
|
prompt: String::new(),
|
|
|
|
max_rows: 24,
|
|
|
|
max_rows: 24,
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn print(&mut self, line : String) {
|
|
|
|
pub fn print(&mut self, line : String) {
|
|
|
|
self.output.push_back(line);
|
|
|
|
self.output.push_back(line);
|
|
|
|
|
|
|
|
|
|
|
|
if self.output.len() > self.max_rows {
|
|
|
|
if self.output.len() > self.max_rows {
|
|
|
|
self.output.pop_front();
|
|
|
|
self.output.pop_front();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
fn main() {
|
|
|
|
panic::set_hook(Box::new(console_error_panic_hook::hook));
|
|
|
|
panic::set_hook(Box::new(console_error_panic_hook::hook));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let window = web_sys::window().expect("should have a window in this context");
|
|
|
|
let window = web_sys::window().expect("should have a window in this context");
|
|
|
|
let document = window.document().expect("window should have a document");
|
|
|
|
let document = window.document().expect("window should have a document");
|
|
|
|
|
|
|
|
|
|
|
|
spawn_local(async {
|
|
|
|
spawn_local(async {
|
|
|
|
init(document).await;
|
|
|
|
init(document).await;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async fn init(document : Document) {
|
|
|
|
async fn init(document : Document) {
|
|
|
|
let mut state = State::new();
|
|
|
|
let mut state = State::new();
|
|
|
|
|
|
|
|
|
|
|
|
let mut render_target = document
|
|
|
|
let mut render_target = document
|
|
|
|
.get_element_by_id("target")
|
|
|
|
.get_element_by_id("target")
|
|
|
|
.expect("should have #target on the page");
|
|
|
|
.expect("should have #target on the page");
|
|
|
|
|
|
|
|
|
|
|
|
print_welcome(&mut render_target, &mut state).await;
|
|
|
|
print_welcome(&mut render_target, &mut state).await;
|
|
|
|
|
|
|
|
|
|
|
|
let closure = Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| {
|
|
|
|
let closure = Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| {
|
|
|
|
let key = io::parse_key_event(&event, false);
|
|
|
|
let key = io::parse_key_event(&event, false);
|
|
|
|
|
|
|
|
|
|
|
|
if key.is_none() {
|
|
|
|
if key.is_none() {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let key = key.unwrap();
|
|
|
|
let key = key.unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
let command = io::handle_key_event(&mut state, key);
|
|
|
|
let command = io::handle_key_event(&mut state, key);
|
|
|
|
|
|
|
|
|
|
|
|
if let Some(command) = command {
|
|
|
|
if let Some(command) = command {
|
|
|
|
handle_command(command, &mut state);
|
|
|
|
handle_command(command, &mut state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
state.prompt = io::build_prompt(&state);
|
|
|
|
state.prompt = io::build_prompt(&state);
|
|
|
|
io::print_state(&mut render_target, &state);
|
|
|
|
io::print_state(&mut render_target, &state);
|
|
|
|
}) as Box<dyn FnMut(_)>);
|
|
|
|
}) as Box<dyn FnMut(_)>);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
document.add_event_listener_with_callback("keydown", closure.as_ref().unchecked_ref()).unwrap();
|
|
|
|
document.add_event_listener_with_callback("keydown", closure.as_ref().unchecked_ref()).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
closure.forget();
|
|
|
|
closure.forget();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub async fn print_welcome(render_target : &mut Element, state : &mut State) {
|
|
|
|
pub async fn print_welcome(render_target : &mut Element, state : &mut State) {
|
|
|
|
let intro = include_str!("../res/welcome.txt");
|
|
|
|
let intro = include_str!("../res/welcome.txt");
|
|
|
|
let mut lines = intro.split("\n");
|
|
|
|
let mut lines = intro.split("\n");
|
|
|
|
|
|
|
|
|
|
|
|
let first_line = lines.next().unwrap();
|
|
|
|
let first_line = lines.next().unwrap();
|
|
|
|
state.input = String::from_str(first_line).unwrap();
|
|
|
|
state.input = String::from_str(first_line).unwrap();
|
|
|
|
io::print_state(render_target, state);
|
|
|
|
io::print_state(render_target, state);
|
|
|
|
|
|
|
|
|
|
|
|
js::wait(3000i32).await.unwrap();
|
|
|
|
js::wait(3000i32).await.unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
state.output.push_back(String::from_str(first_line).unwrap());
|
|
|
|
state.output.push_back(String::from_str(first_line).unwrap());
|
|
|
|
state.input = String::new();
|
|
|
|
state.input = String::new();
|
|
|
|
|
|
|
|
|
|
|
|
io::print_state(render_target, state);
|
|
|
|
io::print_state(render_target, state);
|
|
|
|
js::wait(1000i32).await.unwrap();
|
|
|
|
js::wait(1000i32).await.unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
for line in lines {
|
|
|
|
for line in lines {
|
|
|
|
js::wait(30i32).await.unwrap();
|
|
|
|
js::wait(30i32).await.unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
state.output.push_back(String::from_str(line).unwrap());
|
|
|
|
state.output.push_back(String::from_str(line).unwrap());
|
|
|
|
if state.output.len() > state.max_rows {
|
|
|
|
if state.output.len() > state.max_rows {
|
|
|
|
state.output.pop_front();
|
|
|
|
state.output.pop_front();
|
|
|
|
}
|
|
|
|
|
|
|
|
io::print_state(render_target, state);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
io::print_state(render_target, state);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
js::wait(100i32).await.unwrap();
|
|
|
|
js::wait(100i32).await.unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
state.prompt = io::build_prompt(&state);
|
|
|
|
state.prompt = io::build_prompt(&state);
|
|
|
|
io::print_state(render_target, state);
|
|
|
|
io::print_state(render_target, state);
|
|
|
|
}
|
|
|
|
}
|