mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-24 18:18:17 -06:00
In the browser editor a .jsx script couldn't open any file, even one the
page holds next to the project: File.open("r") returned false with "File
not found" and File.exists was false. The footage check after File > Open
also marked imported media as missing.
Both asked whether a file exists on the local disk (std::fs), which has no
files on wasm32:
- scripts read files through Session.services but checked existence with
std::fs (File.open's access check, File.exists, Folder.exists); they now
ask services.exists / services.is_dir, after the folder check;
- WebServices kept the default exists (std::fs); it now looks in the file
table.
Desktop and CLI are unchanged (FsServices keeps the std::fs defaults).
Tests: script tests_services (a host with in-memory files), web smoke
step hostFiles (a script reads a stored file, footage check finds stored
media).
48 lines
1.7 KiB
Rust
48 lines
1.7 KiB
Rust
//! Scripts see the host's files: existence checks go through `Services`, like reads, so a host
|
|
//! that keeps files in memory (the web editor's browser storage) answers for its own files.
|
|
|
|
use std::collections::HashMap;
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
use effectcraft_engine::{Services, Session};
|
|
|
|
use crate::run_code;
|
|
|
|
#[derive(Default)]
|
|
struct Mem(Mutex<HashMap<String, Vec<u8>>>);
|
|
|
|
impl Services for Mem {
|
|
fn read_file(&self, path: &str) -> std::io::Result<Vec<u8>> {
|
|
self.0.lock().unwrap().get(path).cloned().ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, path.to_string()))
|
|
}
|
|
fn write_file(&self, path: &str, data: &[u8]) -> std::io::Result<()> {
|
|
self.0.lock().unwrap().insert(path.into(), data.into());
|
|
Ok(())
|
|
}
|
|
fn exists(&self, path: &str) -> bool {
|
|
self.0.lock().unwrap().contains_key(path)
|
|
}
|
|
fn is_dir(&self, path: &str) -> bool {
|
|
path == "/browser/footage"
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn a_script_opens_a_file_only_the_host_holds() {
|
|
let mem = Arc::new(Mem::default());
|
|
mem.write_file("/browser/data.txt", b"hello").unwrap();
|
|
let mut s = Session { services: mem, ..Default::default() };
|
|
crate::install(&mut s);
|
|
// A project in a folder that isn't on disk: scripts may read files next to it.
|
|
s.path = Some("/browser/project.ecproj".into());
|
|
let out = run_code(
|
|
&mut s,
|
|
r#"var f = new File("/browser/data.txt"); var ok = f.open("r");
|
|
writeLn(ok + " " + (ok ? f.read() : f.error));
|
|
writeLn(new File("/browser/missing.txt").exists + " " + new Folder("/browser/footage").exists);"#,
|
|
"t.jsx",
|
|
);
|
|
assert!(out.error.is_none(), "{:?}", out.error);
|
|
assert_eq!(out.output, vec!["true hello".to_string(), "false true".to_string()]);
|
|
}
|