diff --git a/doc/FUNCTIONS.md b/doc/FUNCTIONS.md index 363c71a..8501b50 100644 --- a/doc/FUNCTIONS.md +++ b/doc/FUNCTIONS.md @@ -2,6 +2,7 @@ All game functions are in a `game` namespace, they can be called like this: ```rhai game::GiveXP(1) +log(game::GetRamAttackRange()) game::OnQuestSuccess_Player_TraitorToHumanity() game::Kill() ``` diff --git a/src/host.rs b/src/host.rs index b1bd978..b0101c7 100644 --- a/src/host.rs +++ b/src/host.rs @@ -1,7 +1,7 @@ -use std::borrow::Cow; use std::fmt::Debug; +use std::sync::mpsc; -use rhai::{Engine, Module, Scope}; +use rhai::{Dynamic, Engine, Module, Scope}; use crate::elex::FunctionPtr; @@ -9,6 +9,7 @@ use crate::elex::FunctionPtr; pub struct ScriptHost { pub(crate) cmd: String, pub(crate) history: String, + log_receiver: mpsc::Receiver, is_active: bool, engine: Engine, scope: Scope<'static>, @@ -17,10 +18,17 @@ pub struct ScriptHost { impl Default for ScriptHost { fn default() -> Self { let mut engine = Engine::new(); + let (tx, tr) = mpsc::channel(); + engine.register_static_module("game", ScriptHost::create_game_module().into()); + engine.register_fn("log", move |val: Dynamic| { + tx.send(val.to_string()).ok(); + }); + Self { cmd: String::new(), history: String::new(), + log_receiver: tr, is_active: false, engine, scope: Scope::new(), @@ -33,19 +41,28 @@ impl ScriptHost { self.history.push_str(&self.cmd); self.history.push('\n'); - let out = self.handle_command(); - self.history.push_str(&out); + if let Err(err) = self.engine.run_with_scope(&mut self.scope, &self.cmd) { + self.history.push_str(&err.to_string()); + self.history.push('\n'); + } self.cmd.clear(); } - fn handle_command(&mut self) -> Cow<'static, str> { - let res = self.engine.run_with_scope(&mut self.scope, &self.cmd); - match res { - Ok(()) => Cow::Borrowed(""), - Err(err) => Cow::Owned(err.to_string() + "\n"), + pub fn process_events(&mut self) { + while let Ok(str) = self.log_receiver.try_recv() { + self.history.push_str(&str); + self.history.push('\n'); } } + pub fn toggle(&mut self) { + self.is_active = !self.is_active; + } + + pub fn is_active(&self) -> bool { + self.is_active + } + fn create_game_module() -> Module { let mut module = Module::new(); @@ -58,14 +75,6 @@ impl ScriptHost { } module } - - pub fn toggle(&mut self) { - self.is_active = !self.is_active; - } - - pub fn is_active(&self) -> bool { - self.is_active - } } pub type CustomHandler = fn(&str, &mut Module, FunctionPtr) -> u64; diff --git a/src/lib.rs b/src/lib.rs index bf8078a..e9a7e2a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,7 @@ egui_hook!(ScriptHost, ui); fn ui(ctx: &Context, app: &mut ScriptHost) { const DEFAULT_SIZE: Vec2 = Vec2::new(600., 320.); + let was_active = app.is_active(); if ctx.input().key_pressed(Key::Home) { app.toggle(); } @@ -38,9 +39,14 @@ fn ui(ctx: &Context, app: &mut ScriptHost) { .desired_width(600.) .show(ui); + if app.is_active() != was_active { + input.response.request_focus(); + } + if ui.input().key_pressed(Key::Enter) { input.response.request_focus(); app.process_command(); }; + app.process_events(); }); }