use parking_lot::Mutex;
use super::*;
use std::{mem, sync::Arc};
pub struct AdoptiveNode {
child: Arc<Mutex<UiNode>>,
node: UiNode,
is_inited: bool,
}
impl AdoptiveNode {
pub fn new(create: impl FnOnce(AdoptiveChildNode) -> UiNode) -> 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<UiNode, 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: UiNode) -> UiNode {
assert!(!self.is_inited);
mem::replace(&mut *self.child.lock(), new_child)
}
pub fn is_inited(&self) -> bool {
self.is_inited
}
pub fn into_parts(self) -> (Arc<Mutex<UiNode>>, UiNode) {
assert!(!self.is_inited);
(self.child, self.node)
}
pub fn from_parts(child: Arc<Mutex<UiNode>>, node: UiNode) -> Self {
Self {
child,
node,
is_inited: false,
}
}
}
impl UiNodeImpl for AdoptiveNode {
fn init(&mut self) {
self.is_inited = true;
self.node.init();
}
fn deinit(&mut self) {
self.is_inited = false;
self.node.deinit();
}
fn children_len(&self) -> usize {
1
}
fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
if index == 0 {
visitor(&mut self.node);
}
}
}
pub struct AdoptiveChildNode {
child: Arc<Mutex<UiNode>>,
}
impl AdoptiveChildNode {
fn nil() -> Self {
Self {
child: Arc::new(Mutex::new(UiNode::nil())),
}
}
}
impl UiNodeImpl for AdoptiveChildNode {
fn children_len(&self) -> usize {
1
}
fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
if index == 0 {
visitor(&mut self.child.lock())
}
}
}