From 46f314f096833dde19ca6c94b05647435d775942 Mon Sep 17 00:00:00 2001 From: Ettore Ricci Date: Fri, 9 Aug 2024 14:08:18 +0200 Subject: [PATCH 1/2] Added a way to get a time reference in a plugin --- docs/PLUGIN_API.md | 8 ++++++++ src/app/plugins/app_context.rs | 11 +++++++++-- src/app/plugins/mod.rs | 1 + src/app/plugins/plugin.rs | 22 ++++++++++++++++++++++ src/app/plugins/plugin_instant.rs | 22 ++++++++++++++++++++++ test/debug_plugins/debug.lua | 21 +++++++++++++-------- 6 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 src/app/plugins/plugin_instant.rs diff --git a/docs/PLUGIN_API.md b/docs/PLUGIN_API.md index 656c5c3..61adb85 100644 --- a/docs/PLUGIN_API.md +++ b/docs/PLUGIN_API.md @@ -203,6 +203,7 @@ And the following functions: |`open_popup`|`(popup_handler: String)`|Opens a popup, each time the popup is drawn the handler function is called| |`get_popup`|`() -> Option`|Returns the name of the `popup_handler` of the currently open popup if there is one opened by this plugin. `nil` otherwise.| |`close_popup`|`(popup_handler: Option)`|Closes a popup opened by this plugin. If `popup_handler` is not `nil` it will also check if that is the currently open popup. If no popup is open, this plugin does not own the currently open popup, or the provided handler does not match the function will raise an error.| +|`get_instant_now`|`() -> Instant`|Gets an instant relative to the time this function was called. The Instant type is explained at [Instant](#instant).| For more information on the types, see the following sections. @@ -534,3 +535,10 @@ A custom setting can be one of the following types: - `KeyEvent` In the case of a `Style` or `KeyEvent`, the value is effectively a table with the same fields as the type. + +### Instant + +This type represents a point in time. + +This type has the following functions: +|`elapsed`|`() -> f64`|Gets the time elapsed in seconds since the instant was created. This is a float so the precision should go up to nanoseconds.| diff --git a/src/app/plugins/app_context.rs b/src/app/plugins/app_context.rs index e0b08b3..0395f72 100644 --- a/src/app/plugins/app_context.rs +++ b/src/app/plugins/app_context.rs @@ -14,7 +14,7 @@ use crate::{ use super::{ exported_commands::ExportedCommands, exported_header_parsers::ExportedHeaderParsers, - instruction_info::InstructionInfo, + instruction_info::InstructionInfo, plugin_instant::PluginInstant, }; #[macro_export] @@ -313,7 +313,14 @@ impl<'app> AppContext<'app> { scope.create_any_userdata_ref_mut(self.settings).unwrap(), ) .unwrap(); - + context + .set( + "get_instant_now", + scope.create_function(|_, ()| { + Ok(PluginInstant::now()) + }).unwrap() + ) + .unwrap(); context } } diff --git a/src/app/plugins/mod.rs b/src/app/plugins/mod.rs index 1c90753..e2acf63 100644 --- a/src/app/plugins/mod.rs +++ b/src/app/plugins/mod.rs @@ -9,3 +9,4 @@ pub mod plugin; pub mod plugin_manager; pub mod popup_context; pub mod register_userdata; +pub mod plugin_instant; diff --git a/src/app/plugins/plugin.rs b/src/app/plugins/plugin.rs index 96b1d19..9f6d681 100644 --- a/src/app/plugins/plugin.rs +++ b/src/app/plugins/plugin.rs @@ -729,4 +729,26 @@ mod test { assert_eq!(popup_text.lines[2].alignment, Some(Alignment::Left)); assert_eq!(popup_text.lines[2].spans[0].content, "span4"); } + + #[test] + fn test_plugin_instant() { + let source = " + function init(context) + start = context.get_instant_now() + + counter = 0 + while counter < 100 do + counter = counter + 1 + end + + if start:elapsed() <= 0 then + error(\"Timer is not increasing\") + end + end + "; + + let mut app = App::mockup(vec![0; 0x100]); + let mut app_context = get_app_context!(app); + Plugin::new_from_source(source, &mut app_context).unwrap(); + } } diff --git a/src/app/plugins/plugin_instant.rs b/src/app/plugins/plugin_instant.rs new file mode 100644 index 0000000..d27c194 --- /dev/null +++ b/src/app/plugins/plugin_instant.rs @@ -0,0 +1,22 @@ +use std::time::Instant; + +use mlua::UserData; + +#[derive(Clone, Copy, Debug)] +pub struct PluginInstant { + pub inner: Instant +} + +impl PluginInstant { + pub fn now() -> Self { + Self { inner: Instant::now() } + } +} + +impl UserData for PluginInstant { + fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_method("elapsed", |_, this, ()| { + Ok(this.inner.elapsed().as_secs_f64()) + }); + } +} diff --git a/test/debug_plugins/debug.lua b/test/debug_plugins/debug.lua index dd7d339..a338469 100644 --- a/test/debug_plugins/debug.lua +++ b/test/debug_plugins/debug.lua @@ -14,7 +14,6 @@ function on_edit(new_bytes, context) context.log(1, "Data edited: @" .. context.offset) end -popup_additional_text = "Press Enter!" function on_key(key_event, context) modifiers = "" if key_event.modifiers.shift then @@ -41,7 +40,7 @@ function on_key(key_event, context) end if context.get_popup() == "fill_popup" and key_event.code == "Enter" then - popup_additional_text = "Enter pressed!" + last_time_enter_pressed = context.get_instant_now() end end @@ -69,16 +68,20 @@ function debug(context) context.open_popup("fill_popup") end -fill_popup_calls = 0 +last_time_enter_pressed = nil function fill_popup(popup_context, context) popup_context.title:set("Debug") popup_context.height:set(7) popup_context.text:push_line("Debugging information") popup_context.text:set_style({fg="green"}) popup_context.text:set_alignment("left") - popup_context.text:push_line("Calls: ") + popup_context.text:push_line("Time from last enter: ") popup_context.text:reset_style() - popup_context.text:push_span(fill_popup_calls) + if last_time_enter_pressed == nil then + popup_context.text:push_span("Never") + else + popup_context.text:push_span(last_time_enter_pressed:elapsed()) + end popup_context.text:set_style({fg="green"}) popup_context.text:push_line("Popup size: ") popup_context.text:reset_style() @@ -88,7 +91,9 @@ function fill_popup(popup_context, context) popup_context.text:reset_style() popup_context.text:push_span(context.screen_width .. "x" .. context.screen_height) popup_context.text:reset_alignment() - popup_context.text:push_line(popup_additional_text) - fill_popup_calls = fill_popup_calls + 1 - popup_additional_text = "Press Enter!" + if last_time_enter_pressed == nil or last_time_enter_pressed:elapsed() > 1 then + popup_context.text:push_line("Press Enter!") + else + popup_context.text:push_line("Enter Pressed!") + end end From ef264e7a8912485ad437ded3fe9c294a5987a693 Mon Sep 17 00:00:00 2001 From: Ettore Ricci Date: Fri, 9 Aug 2024 14:10:21 +0200 Subject: [PATCH 2/2] Fixed format warnings --- src/app/plugins/app_context.rs | 6 +++--- src/app/plugins/mod.rs | 2 +- src/app/plugins/plugin_instant.rs | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/app/plugins/app_context.rs b/src/app/plugins/app_context.rs index 0395f72..611892b 100644 --- a/src/app/plugins/app_context.rs +++ b/src/app/plugins/app_context.rs @@ -316,9 +316,9 @@ impl<'app> AppContext<'app> { context .set( "get_instant_now", - scope.create_function(|_, ()| { - Ok(PluginInstant::now()) - }).unwrap() + scope + .create_function(|_, ()| Ok(PluginInstant::now())) + .unwrap(), ) .unwrap(); context diff --git a/src/app/plugins/mod.rs b/src/app/plugins/mod.rs index e2acf63..57f164b 100644 --- a/src/app/plugins/mod.rs +++ b/src/app/plugins/mod.rs @@ -6,7 +6,7 @@ pub mod header_context; pub mod header_parser_info; pub mod instruction_info; pub mod plugin; +pub mod plugin_instant; pub mod plugin_manager; pub mod popup_context; pub mod register_userdata; -pub mod plugin_instant; diff --git a/src/app/plugins/plugin_instant.rs b/src/app/plugins/plugin_instant.rs index d27c194..99ef1ef 100644 --- a/src/app/plugins/plugin_instant.rs +++ b/src/app/plugins/plugin_instant.rs @@ -4,12 +4,14 @@ use mlua::UserData; #[derive(Clone, Copy, Debug)] pub struct PluginInstant { - pub inner: Instant + pub inner: Instant, } impl PluginInstant { pub fn now() -> Self { - Self { inner: Instant::now() } + Self { + inner: Instant::now(), + } } }