opportunistic move
should be way faster now
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use std::cell::RefCell;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::foreign::cps_box::{const_cps, init_cps, CPSBox};
|
||||
@@ -23,31 +24,37 @@ struct SetStateCmd(State);
|
||||
#[derive(Debug, Clone)]
|
||||
struct GetStateCmd(State);
|
||||
|
||||
define_fn! { SetState = |x| Ok(init_cps(2, SetStateCmd(x.downcast()?))) }
|
||||
define_fn! { GetState = |x| Ok(init_cps(2, GetStateCmd(x.downcast()?))) }
|
||||
define_fn! {
|
||||
SetState = |x| Ok(init_cps(2, SetStateCmd(x.downcast()?)));
|
||||
GetState = |x| Ok(init_cps(2, GetStateCmd(x.downcast()?)))
|
||||
}
|
||||
|
||||
fn new_state_handler<E>(cmd: &CPSBox<NewStateCmd>) -> Result<ExprInst, E> {
|
||||
fn new_state_handler<E>(cmd: CPSBox<NewStateCmd>) -> Result<ExprInst, E> {
|
||||
let (_, default, handler) = cmd.unpack2();
|
||||
let state = State(Rc::new(RefCell::new(default.clone())));
|
||||
Ok(call(handler.clone(), [state.atom_exi()]).wrap())
|
||||
let state = State(Rc::new(RefCell::new(default)));
|
||||
Ok(call(handler, [state.atom_exi()]).wrap())
|
||||
}
|
||||
|
||||
fn set_state_handler<E>(cmd: &CPSBox<SetStateCmd>) -> Result<ExprInst, E> {
|
||||
fn set_state_handler<E>(cmd: CPSBox<SetStateCmd>) -> Result<ExprInst, E> {
|
||||
let (SetStateCmd(state), value, handler) = cmd.unpack2();
|
||||
*state.0.as_ref().borrow_mut() = value.clone();
|
||||
Ok(handler.clone())
|
||||
*state.0.as_ref().borrow_mut() = value;
|
||||
Ok(handler)
|
||||
}
|
||||
|
||||
fn get_state_handler<E>(cmd: &CPSBox<GetStateCmd>) -> Result<ExprInst, E> {
|
||||
fn get_state_handler<E>(cmd: CPSBox<GetStateCmd>) -> Result<ExprInst, E> {
|
||||
let (GetStateCmd(state), handler) = cmd.unpack1();
|
||||
Ok(call(handler.clone(), [state.0.as_ref().borrow().clone()]).wrap())
|
||||
let val = match Rc::try_unwrap(state.0) {
|
||||
Ok(cell) => cell.into_inner(),
|
||||
Err(rc) => rc.as_ref().borrow().deref().clone(),
|
||||
};
|
||||
Ok(call(handler, [val]).wrap())
|
||||
}
|
||||
|
||||
pub fn state_handlers() -> HandlerTable<'static> {
|
||||
let mut handlers = HandlerTable::new();
|
||||
handlers.register(new_state_handler);
|
||||
handlers.register(get_state_handler);
|
||||
handlers.register(set_state_handler);
|
||||
handlers.register(|b| new_state_handler(*b));
|
||||
handlers.register(|b| get_state_handler(*b));
|
||||
handlers.register(|b| set_state_handler(*b));
|
||||
handlers
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user