Working input response!
This commit is contained in:
parent
6e19401200
commit
54f6e09511
1 changed files with 72 additions and 65 deletions
137
src/main.rs
137
src/main.rs
|
|
@ -16,6 +16,7 @@ mod utils;
|
||||||
mod wasm_vm;
|
mod wasm_vm;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
@ -26,10 +27,13 @@ use panes::PaneId;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use termion::input::TermRead;
|
use termion::input::TermRead;
|
||||||
use wasm_vm::PluginInstruction;
|
use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
|
||||||
|
use wasmer_wasi::{Pipe, WasiState};
|
||||||
|
|
||||||
use crate::command_is_executing::CommandIsExecuting;
|
use crate::command_is_executing::CommandIsExecuting;
|
||||||
use crate::errors::{AppContext, ContextType, ErrorContext, PtyContext, ScreenContext};
|
use crate::errors::{
|
||||||
|
AppContext, ContextType, ErrorContext, PluginContext, PtyContext, ScreenContext,
|
||||||
|
};
|
||||||
use crate::input::input_loop;
|
use crate::input::input_loop;
|
||||||
use crate::layout::Layout;
|
use crate::layout::Layout;
|
||||||
use crate::os_input_output::{get_os_input, OsApi};
|
use crate::os_input_output::{get_os_input, OsApi};
|
||||||
|
|
@ -39,6 +43,7 @@ use crate::utils::{
|
||||||
consts::{MOSAIC_IPC_PIPE, MOSAIC_TMP_DIR, MOSAIC_TMP_LOG_DIR},
|
consts::{MOSAIC_IPC_PIPE, MOSAIC_TMP_DIR, MOSAIC_TMP_LOG_DIR},
|
||||||
logging::*,
|
logging::*,
|
||||||
};
|
};
|
||||||
|
use crate::wasm_vm::{mosaic_imports, wasi_stdout, wasi_write_string, PluginInstruction};
|
||||||
|
|
||||||
thread_local!(static OPENCALLS: RefCell<ErrorContext> = RefCell::default());
|
thread_local!(static OPENCALLS: RefCell<ErrorContext> = RefCell::default());
|
||||||
|
|
||||||
|
|
@ -403,81 +408,83 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
||||||
active_threads.push(
|
active_threads.push(
|
||||||
thread::Builder::new()
|
thread::Builder::new()
|
||||||
.name("wasm".to_string())
|
.name("wasm".to_string())
|
||||||
.spawn(move || {
|
.spawn({
|
||||||
use crate::errors::PluginContext;
|
let mut send_screen_instructions = send_screen_instructions.clone();
|
||||||
use crate::wasm_vm::{mosaic_imports, wasi_stdout};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
|
|
||||||
use wasmer_wasi::{Pipe, WasiState};
|
|
||||||
|
|
||||||
let store = Store::default();
|
move || {
|
||||||
|
let store = Store::default();
|
||||||
|
|
||||||
let mut plugin_id = 0;
|
let mut plugin_id = 0;
|
||||||
let mut plugin_map = HashMap::new();
|
let mut plugin_map = HashMap::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let (event, mut err_ctx) = receive_plugin_instructions
|
let (event, mut err_ctx) = receive_plugin_instructions
|
||||||
.recv()
|
.recv()
|
||||||
.expect("failed to receive event on channel");
|
.expect("failed to receive event on channel");
|
||||||
err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event)));
|
err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event)));
|
||||||
match event {
|
send_screen_instructions.update(err_ctx);
|
||||||
PluginInstruction::Load(pid_tx, path) => {
|
match event {
|
||||||
// FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that
|
PluginInstruction::Load(pid_tx, path) => {
|
||||||
let module = Module::from_file(&store, &path).unwrap();
|
// FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that
|
||||||
|
let module = Module::from_file(&store, &path).unwrap();
|
||||||
|
|
||||||
let output = Pipe::new();
|
let output = Pipe::new();
|
||||||
let input = Pipe::new();
|
let input = Pipe::new();
|
||||||
let mut wasi_env = WasiState::new("mosaic")
|
let mut wasi_env = WasiState::new("mosaic")
|
||||||
.env("CLICOLOR_FORCE", "1")
|
.env("CLICOLOR_FORCE", "1")
|
||||||
.preopen(|p| {
|
.preopen(|p| {
|
||||||
p.directory(".") // FIXME: Change this to a more meaningful dir
|
p.directory(".") // FIXME: Change this to a more meaningful dir
|
||||||
.alias(".")
|
.alias(".")
|
||||||
.read(true)
|
.read(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
}).unwrap()
|
}).unwrap()
|
||||||
.stdin(Box::new(input))
|
.stdin(Box::new(input))
|
||||||
.stdout(Box::new(output))
|
.stdout(Box::new(output))
|
||||||
.finalize().unwrap();
|
.finalize().unwrap();
|
||||||
|
|
||||||
let wasi = wasi_env.import_object(&module).unwrap();
|
let wasi = wasi_env.import_object(&module).unwrap();
|
||||||
let mosaic = mosaic_imports(&store, &wasi_env);
|
let mosaic = mosaic_imports(&store, &wasi_env);
|
||||||
let instance = Instance::new(&module, &mosaic.chain_back(wasi)).unwrap();
|
let instance = Instance::new(&module, &mosaic.chain_back(wasi)).unwrap();
|
||||||
|
|
||||||
let start = instance.exports.get_function("_start").unwrap();
|
let start = instance.exports.get_function("_start").unwrap();
|
||||||
|
|
||||||
// This eventually calls the `.init()` method
|
// This eventually calls the `.init()` method
|
||||||
start.call(&[]).unwrap();
|
start.call(&[]).unwrap();
|
||||||
|
|
||||||
debug_log_to_file(format!("Loaded {}({}) from {}", instance.module().name().unwrap(), plugin_id, path.display())).unwrap();
|
debug_log_to_file(format!("Loaded {}({}) from {}", instance.module().name().unwrap(), plugin_id, path.display())).unwrap();
|
||||||
plugin_map.insert(plugin_id, (instance, wasi_env));
|
plugin_map.insert(plugin_id, (instance, wasi_env));
|
||||||
pid_tx.send(plugin_id).unwrap();
|
pid_tx.send(plugin_id).unwrap();
|
||||||
plugin_id += 1;
|
plugin_id += 1;
|
||||||
}
|
|
||||||
PluginInstruction::Draw(buf_tx, pid, rows, cols) => {
|
|
||||||
let (instance, wasi_env) = plugin_map.get(&pid).unwrap();
|
|
||||||
|
|
||||||
let draw = instance.exports.get_function("draw").unwrap();
|
|
||||||
|
|
||||||
draw.call(&[Value::I32(rows as i32), Value::I32(cols as i32)]).unwrap();
|
|
||||||
|
|
||||||
buf_tx.send(wasi_stdout(&wasi_env)).unwrap();
|
|
||||||
}
|
|
||||||
PluginInstruction::Input(pid, input_bytes) => {
|
|
||||||
let (instance, wasi_env) = plugin_map.get(&pid).unwrap();
|
|
||||||
|
|
||||||
let handle_key = instance.exports.get_function("handle_key").unwrap();
|
|
||||||
for key in input_bytes.keys() {
|
|
||||||
if let Ok(key) = key {
|
|
||||||
dbg!(serde_json::to_string(&key));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
PluginInstruction::Draw(buf_tx, pid, rows, cols) => {
|
||||||
|
let (instance, wasi_env) = plugin_map.get(&pid).unwrap();
|
||||||
|
|
||||||
|
let draw = instance.exports.get_function("draw").unwrap();
|
||||||
|
|
||||||
|
draw.call(&[Value::I32(rows as i32), Value::I32(cols as i32)]).unwrap();
|
||||||
|
|
||||||
|
buf_tx.send(wasi_stdout(&wasi_env)).unwrap();
|
||||||
|
}
|
||||||
|
PluginInstruction::Input(pid, input_bytes) => {
|
||||||
|
let (instance, wasi_env) = plugin_map.get(&pid).unwrap();
|
||||||
|
|
||||||
|
let handle_key = instance.exports.get_function("handle_key").unwrap();
|
||||||
|
for key in input_bytes.keys() {
|
||||||
|
if let Ok(key) = key {
|
||||||
|
wasi_write_string(wasi_env, &serde_json::to_string(&key).unwrap());
|
||||||
|
handle_key.call(&[]).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
send_screen_instructions.send(ScreenInstruction::Render).unwrap();
|
||||||
|
}
|
||||||
|
PluginInstruction::Quit => break,
|
||||||
|
i => panic!("Yo, dawg, nice job calling the wasm thread!\n {:?} is defo not implemented yet...", i),
|
||||||
}
|
}
|
||||||
PluginInstruction::Quit => break,
|
|
||||||
i => panic!("Yo, dawg, nice job calling the wasm thread!\n {:?} is defo not implemented yet...", i),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
).unwrap(),
|
).unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue