feat: add mutations property to localsignal

This commit is contained in:
Byson94
2025-12-28 19:40:49 +05:30
parent 4cb6ac05d3
commit ff9db50831
3 changed files with 64 additions and 4 deletions

View File

@@ -541,7 +541,10 @@ impl<B: DisplayBackend> App<B> {
let b_interval = self.rt_engine_config.batching_interval;
// kick start the localsignal
rhai_impl::updates::handle_localsignal_changes();
rhai_impl::updates::handle_localsignal_changes(
stored_parser_clone.clone(),
compiled_ast.clone(),
);
glib::MainContext::default().spawn_local(async move {
let mut pending_updates = HashSet::new();

View File

@@ -101,7 +101,11 @@ pub fn register_all_widgets(
"localsignal",
move |props: Map| -> Result<LocalSignal, Box<EvalAltResult>> {
let id = hash_props(&props);
let signal = Rc::new(LocalSignal { id, props, data: Arc::new(LocalDataBinder::new()) });
let signal = Rc::new(LocalSignal {
id,
props,
data: Arc::new(LocalDataBinder::new()),
});
let signal_rc = register_signal(id, signal);

View File

@@ -1,4 +1,5 @@
use super::{get_prefered_shell, handle_listen, handle_poll};
use crate::parser::ParseConfig;
use gtk4::glib;
use gtk4::prelude::*;
use gtk4::subclass::prelude::*;
@@ -117,7 +118,10 @@ pub fn notify_all_localsignals() {
});
}
pub fn handle_localsignal_changes() {
pub fn handle_localsignal_changes(
parser: Rc<RefCell<ParseConfig>>,
ast: Option<Rc<RefCell<rhai::AST>>>,
) {
let shell = get_prefered_shell();
let get_string_fn = shared_utils::extract_props::get_string_prop;
let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel::<String>();
@@ -174,7 +178,56 @@ pub fn handle_localsignal_changes() {
let mut registry_ref = registry.borrow_mut();
if let Some(signal) = registry_ref.get_mut(&id) {
signal.data.set_value(&value);
let original = value.to_string();
let mut current = original.clone();
let parser_rc = parser.borrow_mut();
let compiled_ast = match ast.as_ref() {
Some(rc) => rc.borrow(),
None => {
log::warn!("No compiled AST available");
return;
}
};
let mutations: Vec<rhai::FnPtr> = match signal.props.get("mutations") {
Some(v) => {
if let Ok(arr) = v.as_array_ref() {
arr.iter()
.filter_map(|item| {
item.clone().try_cast::<rhai::FnPtr>().or_else(|| {
log::warn!("Non-function found in signal.props.mutations");
None
})
})
.collect()
} else {
log::warn!("Localsignal mutations property is not an array");
Vec::new()
}
}
None => Vec::new(),
};
for mutation in mutations {
match mutation.call::<String>(&parser_rc.engine, &compiled_ast, (current.clone(),)) {
Ok(v) => {
current = v;
}
Err(e) => {
log::warn!(
"Signal {} mutation failed ({}), reverting to original value",
id,
e
);
current = original.clone();
break;
}
}
}
signal.data.set_value(&current);
} else {
log::warn!("No LocalSignal found for id {}", id);
}