aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrooks J Rady <b.j.rady@gmail.com>2021-01-07 15:23:54 +0000
committerBrooks J Rady <b.j.rady@gmail.com>2021-01-07 15:23:54 +0000
commit58a2fc1656f73c41c98d9bf1319357c7b57d8b63 (patch)
treef6503507de1a580d8921d14e51269dfca5acb4b8 /src
parentFix the plugin splitting bugs (diff)
downloadsl0ppij-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.rs21
-rw-r--r--src/wasm_vm.rs37
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 {