Skip to content

Commit

Permalink
Emglken: Get/set directories
Browse files Browse the repository at this point in the history
  • Loading branch information
curiousdannii committed Mar 17, 2024
1 parent 19de196 commit f77708b
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 39 deletions.
16 changes: 8 additions & 8 deletions remglk/src/glkapi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ where S: Default + GlkSystem {
current_stream: Option<GlkStreamWeak>,
exited: bool,
pub filerefs: GlkObjectStore<FileRef>,
pub folders: Folders,
pub dirs: Directories,
gen: u32,
metrics: NormalisedMetrics,
partial_inputs: PartialInputs,
Expand All @@ -74,7 +74,7 @@ impl<S> GlkApi<S>
where S: Default + GlkSystem {
pub fn new(system: S) -> Self {
GlkApi {
folders: S::get_folders(),
dirs: S::get_directories(),
system,
..Default::default()
}
Expand Down Expand Up @@ -197,7 +197,7 @@ where S: Default + GlkSystem {

pub fn glk_fileref_create_by_name(&mut self, usage: u32, filename: String, rock: u32) -> GlkFileRef {
let filetype = file_type(usage & fileusage_TypeMask);
let path = self.folders.working.join(clean_filename(filename, filetype)).to_str().unwrap().to_owned();
let path = self.dirs.working.join(clean_filename(filename, filetype)).to_str().unwrap().to_owned();
self.create_fileref(path, rock, usage)
}

Expand All @@ -220,7 +220,7 @@ where S: Default + GlkSystem {
FileRefResponse::Fref(fref) => fref.filename,
FileRefResponse::Path(path) => path,
};
let path = self.folders.working.join(clean_filename(filename, filetype)).to_str().unwrap().to_owned();
let path = self.dirs.working.join(clean_filename(filename, filetype)).to_str().unwrap().to_owned();
return Ok(Some(self.create_fileref(path, rock, usage)));
}
}
Expand Down Expand Up @@ -1034,12 +1034,12 @@ where S: Default + GlkSystem {
// Extensions

pub fn glkunix_fileref_create_by_name_uncleaned(&mut self, usage: u32, filename: String, rock: u32) -> GlkFileRef {
let path = self.folders.storyfile.join(filename).to_str().unwrap().to_owned();
let path = self.dirs.storyfile.join(filename).to_str().unwrap().to_owned();
self.create_fileref(path, rock, usage)
}

pub fn glkunix_set_base_file(&mut self, path: String) {
S::set_base_file(&mut self.folders, path);
S::set_base_file(&mut self.dirs, path);
}

// The GlkOte protocol functions
Expand Down Expand Up @@ -1593,7 +1593,7 @@ where S: Default + GlkSystem {

fn temp_file_path(&self, file_num: u32) -> String {
let filename = format!("remglktempfile-{}", file_num);
self.folders.temp.join(filename).to_str().unwrap().to_owned()
self.dirs.temp.join(filename).to_str().unwrap().to_owned()
}

/** Unretain an array, or leak if no callbacks setup */
Expand All @@ -1617,7 +1617,7 @@ where S: Default + GlkSystem {
}

#[derive(Default)]
pub struct Folders {
pub struct Directories {
pub storyfile: PathBuf,
pub temp: PathBuf,
pub working: PathBuf,
Expand Down
6 changes: 3 additions & 3 deletions remglk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub mod glkapi;

use std::path::PathBuf;

use glkapi::Folders;
use glkapi::Directories;
use glkapi::protocol::{Event, Update};

/** Glk's access to the operating system */
Expand All @@ -31,6 +31,6 @@ pub trait GlkSystem {
/** Get an event from GlkOte */
fn get_glkote_event(&mut self) -> Option<Event>;

fn get_folders() -> Folders;
fn set_base_file(folders: &mut Folders, path: String);
fn get_directories() -> Directories;
fn set_base_file(folders: &mut Directories, path: String);
}
45 changes: 30 additions & 15 deletions remglk_capi/src/systems/emglken.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::mem::MaybeUninit;
use std::path::PathBuf;
use std::slice;

use serde::Deserialize;
use serde::de::DeserializeOwned;

use super::*;
Expand All @@ -25,14 +26,10 @@ extern "C" {
fn emglken_file_exists(path_ptr: *const u8, path_len: usize) -> bool;
fn emglken_file_read(path_ptr: *const u8, path_len: usize, buffer: *mut EmglkenBuffer) -> bool;
fn emglken_file_write_buffer(path_ptr: *const u8, path_len: usize, buf_ptr: *const u8, buf_len: usize);
fn emglken_get_dirs(buffer: *mut EmglkenBuffer);
fn emglken_get_glkote_event(buffer: *mut EmglkenBuffer);
fn emglken_send_glkote_update(update_ptr: *const u8, update_len: usize);
}

#[repr(C)]
pub struct EmglkenBuffer {
pub ptr: *mut u8,
pub len: usize,
fn emglken_set_storyfile_dir(path_ptr: *const u8, path_len: usize, buffer: *mut EmglkenBuffer);
}

pub type GlkApi = glkapi::GlkApi<EmglkenSystem>;
Expand Down Expand Up @@ -99,23 +96,41 @@ impl GlkSystem for EmglkenSystem {
unsafe {emglken_send_glkote_update(json.as_ptr(), json.len())};
}

fn get_folders() -> Folders {
// TODO: do something better here when we can do it reliably in both Node and browser
Folders {
storyfile: PathBuf::new(),
temp: PathBuf::new(),
working: PathBuf::new(),
fn get_directories() -> Directories {
let mut buf: MaybeUninit<EmglkenBuffer> = MaybeUninit::uninit();
unsafe {emglken_get_dirs(buf.as_mut_ptr())};
let dirs: EmglkenDirectories = buffer_to_protocol_struct(buf);
Directories {
storyfile: PathBuf::from(dirs.storyfile),
temp: PathBuf::from(dirs.temp),
working: PathBuf::from(dirs.working),
}
}

fn set_base_file(folders: &mut Folders, path: String) {
// This really needs to move to the JS layer, as it depends on the Dialog backend
fn set_base_file(dirs: &mut Directories, path: String) {
let mut path = PathBuf::from(path);
path.pop();
folders.storyfile = path;
let path = path.to_str().unwrap();
let mut buf: MaybeUninit<EmglkenBuffer> = MaybeUninit::uninit();
unsafe {emglken_set_storyfile_dir(path.as_ptr(), path.len(), buf.as_mut_ptr())};
let emglken_dirs: EmglkenDirectories = buffer_to_protocol_struct(buf);
dirs.storyfile = PathBuf::from(emglken_dirs.storyfile);
}
}

#[repr(C)]
pub struct EmglkenBuffer {
pub ptr: *mut u8,
pub len: usize,
}

#[derive(Deserialize)]
struct EmglkenDirectories {
pub storyfile: String,
pub temp: String,
pub working: String,
}

fn buffer_to_boxed_slice(buffer: MaybeUninit<EmglkenBuffer>) -> Box<[u8]> {
let buffer = unsafe {buffer.assume_init()};
unsafe {Box::from_raw(slice::from_raw_parts_mut(buffer.ptr, buffer.len))}
Expand Down
23 changes: 13 additions & 10 deletions remglk_capi/src/systems/library_emglken.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ const EMGLKEN_JS = {
emglken_file_exists(path_ptr, path_len) {
return Asyncify.handleAsync(async () => {
const path = UTF8ToString(path_ptr, path_len)
if (path === storyfile_name) {
return true
}
return Dialog.exists(path)
})
},
Expand All @@ -36,13 +33,7 @@ const EMGLKEN_JS = {
emglken_file_read(path_ptr, path_len, buffer) {
return Asyncify.handleAsync(async () => {
const path = UTF8ToString(path_ptr, path_len)
let data
if (path === storyfile_name) {
data = storyfile_data
}
else {
data = await Dialog.read(path)
}
const data = await Dialog.read(path)
if (data) {
writeBuffer(buffer, data)
return true
Expand All @@ -57,6 +48,11 @@ const EMGLKEN_JS = {
Dialog.write(path, data)
},

emglken_get_dirs(buffer) {
const dirs = Dialog.get_dirs()
writeBufferJSON(buffer, dirs)
},

emglken_get_glkote_event__async: true,
emglken_get_glkote_event(buffer) {
return Asyncify.handleAsync(async () => {
Expand All @@ -73,6 +69,13 @@ const EMGLKEN_JS = {
GlkOte.update(obj)
},

emglken_set_storyfile_dir(path_ptr, path_len, buffer) {
const path = UTF8ToString(path_ptr, path_len)
Dialog.set_storyfile_dir(path)
const dirs = Dialog.get_dirs()
writeBufferJSON(buffer, dirs)
},

$writeBuffer(buffer, data) {
const ptr = _malloc(data.length)
HEAP8.set(data, ptr)
Expand Down
6 changes: 3 additions & 3 deletions remglk_capi/src/systems/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,15 @@ impl GlkSystem for StandardSystem {
println!("{}", output);
}

fn get_folders() -> Folders {
Folders {
fn get_directories() -> Directories {
Directories {
storyfile: env::current_dir().unwrap(),
temp: env::temp_dir(),
working: env::current_dir().unwrap(),
}
}

fn set_base_file(folders: &mut Folders, path: String) {
fn set_base_file(folders: &mut Directories, path: String) {
let mut path = PathBuf::from(path);
path.pop();
folders.storyfile = path.clone();
Expand Down

0 comments on commit f77708b

Please sign in to comment.