[oden][game] Multiple screens, logging, pre/post, bluescreen

Better blue screens and also logging and whatnot
This commit is contained in:
John Doty 2023-09-11 20:41:11 -07:00
parent 95d626c15f
commit 93d4e3eb91
8 changed files with 1201 additions and 244 deletions

View file

@ -1,7 +1,7 @@
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use oden_js::{
module::loader::{ModuleLoader, ModuleSource},
Context, ContextRef, Result, Runtime, Value,
Context, ContextRef, RejectedPromiseTracker, Result, Runtime, Value,
};
use std::ffi::OsStr;
use std::sync::mpsc::{channel, Receiver, Sender};
@ -53,6 +53,39 @@ impl ModuleLoader for Loader {
}
}
struct RejectedPromiseHandler {
error_lines: Sender<String>,
}
impl RejectedPromiseTracker for RejectedPromiseHandler {
fn on_rejected_promise(
&self,
ctx: &ContextRef,
_promise: &oden_js::ValueRef,
reason: &oden_js::ValueRef,
is_handled: bool,
) {
if !is_handled {
let reason_str = reason.to_string(ctx).expect(
"Unhandled rejected promise: reason unknown: unable to convert reason to string",
);
let reason_str = format!("Unhandled rejected promise:\n{reason_str}");
for line in reason_str.lines().map(|l| l.to_owned()) {
let _ = self.error_lines.send(line);
}
let stack = reason
.get_property(ctx, "stack")
.and_then(|stack| stack.to_string(ctx))
.unwrap_or_else(|_| String::new());
for line in stack.lines().map(|l| l.to_owned()) {
let _ = self.error_lines.send(line);
}
}
}
}
pub struct ScriptContext {
context: Context,
update: Value,
@ -68,12 +101,18 @@ pub struct ScriptContext {
input: input::InputAPI,
error_lines: Vec<String>,
promise_error_reciever: Receiver<String>,
}
impl ScriptContext {
pub fn new(suspend_state: Option<Vec<u8>>, reload_trigger: Sender<()>) -> Result<Self> {
let (promise_error_send, promise_error_recv) = channel();
let mut runtime = Runtime::new();
runtime.set_module_loader(Loader::new(reload_trigger));
runtime.set_rejected_promise_tracker(RejectedPromiseHandler {
error_lines: promise_error_send,
});
let mut context = Context::new(runtime);
context.add_intrinsic_bigfloat();
@ -119,6 +158,7 @@ impl ScriptContext {
input,
error_lines: Vec::new(),
promise_error_reciever: promise_error_recv,
})
}
@ -172,6 +212,11 @@ impl ScriptContext {
{
let _span = span!("process jobs");
self.handle_result(self.context.process_all_jobs());
// Check to make sure we don't have any rejected promises.
while let Ok(line) = self.promise_error_reciever.try_recv() {
self.error_lines.push(line);
}
}
// Now run the update function.
@ -197,9 +242,10 @@ impl ScriptContext {
GraphicsCommand::Clear(ClearCommand {
color: [0.0, 0.0, 1.0, 1.0],
}),
GraphicsCommand::Scale([4.0, 4.0]),
GraphicsCommand::Print(PrintCommand {
text: "FATAL SCRIPT ERROR".to_owned(),
pos: [6.0, 6.0],
pos: [8.0, 8.0],
}),
];