#![allow(dead_code)]
use ferroui_base::input::ICommand;
use ferroui_base::reactive::{Disposable, IDisposable};
use ferroui_base::BoxedValue;
use std::cell::{Cell, RefCell};
use std::rc::{Rc, Weak};
type Handlers = Vec<(u64, Rc<dyn Fn()>)>;
pub struct TestCommand {
this: Weak<TestCommand>,
can_execute: Box<dyn Fn(Option<&BoxedValue>) -> bool>,
execute: Box<dyn Fn(Option<&BoxedValue>)>,
can_execute_changed: RefCell<Handlers>,
next_token: Cell<u64>,
enabled: Rc<Cell<bool>>,
subscription_count: Cell<i32>,
}
impl TestCommand {
pub fn new(enabled: bool) -> Rc<Self> {
let enabled = Rc::new(Cell::new(enabled));
let flag = enabled.clone();
Self::create(enabled, Box::new(move |_| flag.get()), Box::new(|_| {}))
}
pub fn with_can_execute(can_execute: impl Fn(Option<&BoxedValue>) -> bool + 'static) -> Rc<Self> {
Self::create(Rc::new(Cell::new(true)), Box::new(can_execute), Box::new(|_| {}))
}
pub fn with_can_execute_and_execute(
can_execute: impl Fn(Option<&BoxedValue>) -> bool + 'static,
execute: impl Fn(Option<&BoxedValue>) + 'static,
) -> Rc<Self> {
Self::create(Rc::new(Cell::new(true)), Box::new(can_execute), Box::new(execute))
}
fn create(
enabled: Rc<Cell<bool>>,
can_execute: Box<dyn Fn(Option<&BoxedValue>) -> bool>,
execute: Box<dyn Fn(Option<&BoxedValue>)>,
) -> Rc<Self> {
Rc::new_cyclic(|this| Self {
this: this.clone(),
can_execute,
execute,
can_execute_changed: RefCell::new(Vec::new()),
next_token: Cell::new(0),
enabled,
subscription_count: Cell::new(0),
})
}
pub fn is_enabled(&self) -> bool {
self.enabled.get()
}
pub fn set_is_enabled(&self, value: bool) {
if self.enabled.get() != value {
self.enabled.set(value);
self.raise_can_execute_changed();
}
}
pub fn subscription_count(&self) -> i32 {
self.subscription_count.get()
}
pub fn raise_can_execute_changed(&self) {
let handlers: Vec<Rc<dyn Fn()>> = self.can_execute_changed.borrow().iter().map(|(_, h)| h.clone()).collect();
for handler in handlers {
handler();
}
}
pub fn as_command(self: &Rc<Self>) -> Option<Rc<dyn ICommand>> {
Some(self.clone())
}
}
impl ICommand for TestCommand {
fn can_execute(&self, parameter: Option<&BoxedValue>) -> bool {
(self.can_execute)(parameter)
}
fn execute(&self, parameter: Option<&BoxedValue>) {
(self.execute)(parameter)
}
fn can_execute_changed(&self, handler: Rc<dyn Fn()>) -> Rc<dyn IDisposable> {
let token = self.next_token.get();
self.next_token.set(token + 1);
self.can_execute_changed.borrow_mut().push((token, handler));
self.subscription_count.set(self.subscription_count.get() + 1);
let weak = self.this.clone();
Disposable::create(move || {
if let Some(this) = weak.upgrade() {
this.can_execute_changed.borrow_mut().retain(|(t, _)| *t != token);
this.subscription_count.set(this.subscription_count.get() - 1);
}
})
}
}