use parking_lot::Mutex;
use super::*;
use crate::widget::ui_node;
use std::{mem, sync::Arc};
pub struct AdoptiveNode<U> {
child: Arc<Mutex<BoxedUiNode>>,
node: U,
is_inited: bool,
}
impl<U: UiNode> AdoptiveNode<U> {
pub fn new(create: impl FnOnce(AdoptiveChildNode) -> U) -> Self {
let ad_child = AdoptiveChildNode::nil();
let child = ad_child.child.clone();
let node = create(ad_child);
Self {
child,
node,
is_inited: false,
}
}
pub fn try_new<E>(create: impl FnOnce(AdoptiveChildNode) -> Result<U, E>) -> Result<Self, E> {
let ad_child = AdoptiveChildNode::nil();
let child = ad_child.child.clone();
let node = create(ad_child)?;
Ok(Self {
child,
node,
is_inited: false,
})
}
pub fn replace_child(&mut self, new_child: impl UiNode) -> BoxedUiNode {
assert!(!self.is_inited);
mem::replace(&mut *self.child.lock(), new_child.boxed())
}
pub fn is_inited(&self) -> bool {
self.is_inited
}
pub fn into_parts(self) -> (Arc<Mutex<BoxedUiNode>>, U) {
assert!(!self.is_inited);
(self.child, self.node)
}
pub fn from_parts(child: Arc<Mutex<BoxedUiNode>>, node: U) -> Self {
Self {
child,
node,
is_inited: false,
}
}
}
#[ui_node(delegate = &mut self.node)]
impl<U: UiNode> UiNode for AdoptiveNode<U> {
fn init(&mut self) {
self.is_inited = true;
self.node.init();
}
fn deinit(&mut self) {
self.is_inited = false;
self.node.deinit();
}
}
pub struct AdoptiveChildNode {
child: Arc<Mutex<BoxedUiNode>>,
}
impl AdoptiveChildNode {
fn nil() -> Self {
Self {
child: Arc::new(Mutex::new(NilUiNode.boxed())),
}
}
}
#[ui_node(delegate = self.child.lock())]
impl UiNode for AdoptiveChildNode {}