Not necessary, but I'm thinking of a Node
which consists of one-level internal variants like Modal
, Button
and more. I thought it'd be cool if someone could type button: Arc<Button>
instead of button: Node
and access Button
as Node
when needed:
// `Node` holds an internal Arc<NonRefNode>,
// so it is a "reference" type.
// what I'd like
let button: Arc<Button> = Button::new();
let button = button.base(); // button: Node
// I think I'll end up with
let button: Node = Button::new();
Playground:, where C1
is the abstract type and C2
is the actual kind:
use std::sync::{Arc, Weak};
struct C1(Arc<C2>);
struct C2(Weak<C1>);
impl C2 {
fn new() -> Arc<Self> {
let mut c2 = Arc::new(C2(Weak::new()));
let c1 = Arc::new(C1(Arc::clone(&c2)));
Arc::get_mut(&mut c2).unwrap().0 = Arc::downgrade(&c1);
c2
}
fn base(&self) -> Arc<C1> {
self.0.upgrade().unwrap()
}
}
fn main() {
let c2 = C2::new();
c2.base(); // got panic; expected no panic
}
I think this isn't entirely necessary because within my framework I'm planning to support user reactive UI components which wrap your graphical nodes using internal composition, even though nodes might not be used just for UI, but also for gaming (for graphical representation of things, together with ECS).
I'll also have these methods regardless:
node.to::<K>()
(returns aArc<K>
by asserting the kind)node.is::<K>()