slint/api/sixtyfps-node/native/persistent_context.rs
Simon Hausmann c2a0cd7000 Added a node version of the memory puzzle game
This also implements a basic single shot timer support, which has
one caveat: it leaks the closures right now.
2020-12-11 17:17:28 +01:00

55 lines
1.9 KiB
Rust

/* LICENSE BEGIN
This file is part of the SixtyFPS Project -- https://sixtyfps.io
Copyright (c) 2020 Olivier Goffart <olivier.goffart@sixtyfps.io>
Copyright (c) 2020 Simon Hausmann <simon.hausmann@sixtyfps.io>
SPDX-License-Identifier: GPL-3.0-only
This file is also available under commercial licensing terms.
Please contact info@sixtyfps.io for more information.
LICENSE END */
/*!
Since neon do not allow to have Persistant handle, use this hack.
*/
use neon::prelude::*;
pub struct PersistentContext<'a>(Handle<'a, JsArray>);
const KEY: &'static str = "$__persistent_context";
/// Since neon do not allow to have Persistant handle, this allocates property in an array.
/// And this array is gonna be kept as a property somewhere.
impl<'a> PersistentContext<'a> {
pub fn new(cx: &mut impl Context<'a>) -> Self {
PersistentContext(JsArray::new(cx, 0))
}
pub fn allocate(&self, cx: &mut impl Context<'a>, value: Handle<'a, JsValue>) -> u32 {
let idx = self.0.len();
self.0.set(cx, idx, value).unwrap();
idx
}
pub fn get(&self, cx: &mut impl Context<'a>, idx: u32) -> JsResult<'a, JsValue> {
self.0.get(cx, idx)
}
pub fn save_to_object(&self, cx: &mut impl Context<'a>, o: Handle<'a, JsObject>) {
o.set(cx, KEY, self.0).unwrap();
}
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)?))
}
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
}
})
}
}