diff options
| author | Brooks J Rady <b.j.rady@gmail.com> | 2021-01-07 15:23:54 +0000 |
|---|---|---|
| committer | Brooks J Rady <b.j.rady@gmail.com> | 2021-01-07 15:23:54 +0000 |
| commit | 58a2fc1656f73c41c98d9bf1319357c7b57d8b63 (patch) | |
| tree | f6503507de1a580d8921d14e51269dfca5acb4b8 /src | |
| parent | Fix the plugin splitting bugs (diff) | |
| download | sl0ppij-58a2fc1656f73c41c98d9bf1319357c7b57d8b63.tar.gz sl0ppij-58a2fc1656f73c41c98d9bf1319357c7b57d8b63.tar.xz sl0ppij-58a2fc1656f73c41c98d9bf1319357c7b57d8b63.zip | |
Finished plugin system! (Added file opening)
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 21 | ||||
| -rw-r--r-- | src/wasm_vm.rs | 37 |
2 files changed, 34 insertions, 24 deletions
diff --git a/src/main.rs b/src/main.rs index 3d358399..96809688 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ use panes::PaneId; use serde::{Deserialize, Serialize}; use structopt::StructOpt; use termion::input::TermRead; +use wasm_vm::PluginEnv; use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value}; use wasmer_wasi::{Pipe, WasiState}; @@ -408,6 +409,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) { thread::Builder::new() .name("wasm".to_string()) .spawn({ + let mut send_pty_instructions = send_pty_instructions.clone(); let mut send_screen_instructions = send_screen_instructions.clone(); move || { @@ -422,6 +424,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) { .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event))); send_screen_instructions.update(err_ctx); + send_pty_instructions.update(err_ctx); match event { PluginInstruction::Load(pid_tx, path) => { // FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that @@ -445,7 +448,13 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) { .unwrap(); let wasi = wasi_env.import_object(&module).unwrap(); - let mosaic = mosaic_imports(&store, &wasi_env); + + let plugin_env = PluginEnv { + send_pty_instructions: send_pty_instructions.clone(), + wasi_env, + }; + + let mosaic = mosaic_imports(&store, &plugin_env); let instance = Instance::new(&module, &mosaic.chain_back(wasi)).unwrap(); @@ -454,29 +463,29 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) { // This eventually calls the `.init()` method start.call(&[]).unwrap(); - plugin_map.insert(plugin_id, (instance, wasi_env)); + plugin_map.insert(plugin_id, (instance, plugin_env)); pid_tx.send(plugin_id).unwrap(); plugin_id += 1; } PluginInstruction::Draw(buf_tx, pid, rows, cols) => { - let (instance, wasi_env) = plugin_map.get(&pid).unwrap(); + let (instance, plugin_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(); + buf_tx.send(wasi_stdout(&plugin_env.wasi_env)).unwrap(); } PluginInstruction::Input(pid, input_bytes) => { - let (instance, wasi_env) = plugin_map.get(&pid).unwrap(); + let (instance, plugin_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, + &plugin_env.wasi_env, &serde_json::to_string(&key).unwrap(), ); handle_key.call(&[]).unwrap(); diff --git a/src/wasm_vm.rs b/src/wasm_vm.rs index 6d2d4a19..51bd9375 100644 --- a/src/wasm_vm.rs +++ b/src/wasm_vm.rs @@ -1,11 +1,9 @@ -use std::{ - path::PathBuf, - process::{Command, Stdio}, - sync::mpsc::Sender, -}; -use wasmer::{imports, Function, ImportObject, Store}; +use std::{path::PathBuf, sync::mpsc::Sender}; +use wasmer::{imports, Function, ImportObject, Store, WasmerEnv}; use wasmer_wasi::WasiEnv; +use crate::{pty_bus::PtyInstruction, SenderWithContext}; + #[derive(Clone, Debug)] pub enum PluginInstruction { Load(Sender<u32>, PathBuf), @@ -15,29 +13,32 @@ pub enum PluginInstruction { Quit, } -// Plugin API ----------------------------------------------------------------- +#[derive(WasmerEnv, Clone)] +pub struct PluginEnv { + pub send_pty_instructions: SenderWithContext<PtyInstruction>, // FIXME: This should be a big bundle of all of the channels + pub wasi_env: WasiEnv, +} + +// Plugin API --------------------------------------------------------------------------------------------------------- -pub fn mosaic_imports(store: &Store, wasi_env: &WasiEnv) -> ImportObject { +pub fn mosaic_imports(store: &Store, plugin_env: &PluginEnv) -> ImportObject { imports! { "mosaic" => { - "host_open_file" => Function::new_native_with_env(store, wasi_env.clone(), host_open_file) + "host_open_file" => Function::new_native_with_env(store, plugin_env.clone(), host_open_file) } } } // FIXME: Bundle up all of the channels! Pair that with WasiEnv? -fn host_open_file(wasi_env: &WasiEnv) { - Command::new("xdg-open") - .arg(format!( - "./{}", - wasi_stdout(wasi_env).lines().next().unwrap() - )) - .stderr(Stdio::null()) - .spawn() +fn host_open_file(plugin_env: &PluginEnv) { + let path = PathBuf::from(wasi_stdout(&plugin_env.wasi_env).lines().next().unwrap()); + plugin_env + .send_pty_instructions + .send(PtyInstruction::SpawnTerminal(Some(path))) .unwrap(); } -// Helper Functions ----------------------------------------------------------- +// Helper Functions --------------------------------------------------------------------------------------------------- // FIXME: Unwrap city pub fn wasi_stdout(wasi_env: &WasiEnv) -> String { |
