mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 14:21:16 +00:00
Fix single shot timer leaks in the nodejs api
As discussed, don't use the persistent context approach for single shot timers but store the callback directly in the global object and "delete" it afterwards.
This commit is contained in:
parent
b42c16851a
commit
0e04149868
3 changed files with 25 additions and 20 deletions
|
@ -27,6 +27,7 @@ css-color-parser2 = "1.0.1"
|
||||||
spin_on = "0.1" #FIXME: remove and delegate to async JS instead
|
spin_on = "0.1" #FIXME: remove and delegate to async JS instead
|
||||||
vtable = { version = "0.1.1", path="../../../helper_crates/vtable" }
|
vtable = { version = "0.1.1", path="../../../helper_crates/vtable" }
|
||||||
generativity = "1"
|
generativity = "1"
|
||||||
|
rand = "0.7.3"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
neon-build = "0.6.0"
|
neon-build = "0.6.0"
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
LICENSE END */
|
LICENSE END */
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
use neon::prelude::*;
|
use neon::prelude::*;
|
||||||
|
use rand::RngCore;
|
||||||
use sixtyfps_compilerlib::langtype::Type;
|
use sixtyfps_compilerlib::langtype::Type;
|
||||||
use sixtyfps_corelib::Resource;
|
use sixtyfps_corelib::Resource;
|
||||||
|
|
||||||
|
@ -491,26 +492,41 @@ declare_types! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn singleshot_timer_property(id: u32) -> String {
|
||||||
|
format!("$__sixtyfps_singleshot_timer_{}", id)
|
||||||
|
}
|
||||||
|
|
||||||
fn singleshot_timer(mut cx: FunctionContext) -> JsResult<JsValue> {
|
fn singleshot_timer(mut cx: FunctionContext) -> JsResult<JsValue> {
|
||||||
let duration_in_msecs = cx.argument::<JsNumber>(0)?.value() as u64;
|
let duration_in_msecs = cx.argument::<JsNumber>(0)?.value() as u64;
|
||||||
let handler = cx.argument::<JsFunction>(1)?;
|
let handler = cx.argument::<JsFunction>(1)?;
|
||||||
|
|
||||||
let global_persistent_context = persistent_context::PersistentContext::global(&mut cx)?;
|
let global_object: Handle<JsObject> = cx.global().downcast().unwrap();
|
||||||
|
let unique_timer_property = {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
loop {
|
||||||
|
let id = rng.next_u32();
|
||||||
|
let key = singleshot_timer_property(id);
|
||||||
|
if global_object.get(&mut cx, &*key)?.is_a::<JsUndefined>() {
|
||||||
|
break key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let handler_value = handler.as_value(&mut cx);
|
let handler_value = handler.as_value(&mut cx);
|
||||||
let handler_idx = global_persistent_context.allocate(&mut cx, handler_value);
|
global_object.set(&mut cx, &*unique_timer_property, handler_value).unwrap();
|
||||||
let callback = move || {
|
let callback = move || {
|
||||||
run_with_global_contect(&move |cx, _| {
|
run_with_global_contect(&move |cx, _| {
|
||||||
let global_persistent_context =
|
let global_object: Handle<JsObject> = cx.global().downcast().unwrap();
|
||||||
persistent_context::PersistentContext::global(cx).unwrap();
|
|
||||||
|
|
||||||
global_persistent_context
|
let callback = global_object
|
||||||
.get(cx, handler_idx)
|
.get(cx, &*unique_timer_property)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.downcast::<JsFunction>()
|
.downcast::<JsFunction>()
|
||||||
.unwrap()
|
|
||||||
.call::<_, _, JsValue, _>(cx, JsUndefined::new(), vec![])
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
global_object.set(cx, &*unique_timer_property, JsUndefined::new()).unwrap();
|
||||||
|
|
||||||
|
callback.call::<_, _, JsValue, _>(cx, JsUndefined::new(), vec![]).unwrap();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,16 +40,4 @@ impl<'a> PersistentContext<'a> {
|
||||||
pub fn from_object(cx: &mut impl Context<'a>, o: Handle<'a, JsObject>) -> NeonResult<Self> {
|
pub fn from_object(cx: &mut impl Context<'a>, o: Handle<'a, JsObject>) -> NeonResult<Self> {
|
||||||
Ok(PersistentContext(o.get(cx, KEY)?.downcast_or_throw(cx)?))
|
Ok(PersistentContext(o.get(cx, KEY)?.downcast_or_throw(cx)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn global(cx: &mut impl Context<'a>) -> NeonResult<Self> {
|
|
||||||
let global_object: Handle<JsObject> = cx.global().downcast().unwrap();
|
|
||||||
Ok(match global_object.get(cx, KEY)?.downcast() {
|
|
||||||
Ok(array) => PersistentContext(array),
|
|
||||||
Err(_) => {
|
|
||||||
let ctx = PersistentContext::new(cx);
|
|
||||||
ctx.save_to_object(cx, global_object);
|
|
||||||
ctx
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue