I want to have a Node
type that stores a reference to the parent node, a transform property, rotation degrees, opacity, signals, among other things. I want to have cheap access to these properties, and want to implement them in Node
, not in the Node
subtypes themselves.
Approach 1
Well, the approach to implement a inheritance of nodes with these Node
common properties like position and opacity is using a Node
struct containing a "subtype" property. Kind of like:
struct Node {
m_parent: Option<Weak<Node>>,
m_subtype: Arc<dyn NodeSubtype>,
}
trait NodeSubtype {
}
Here's what I sketched about subtypes a few days ago (slightly edited):
Subtype Trait
In regards to node subtypes, the Node trait implements:
node.to::<T>()
: allows to access subtype properties and methods. It returnsArc<T>
.node.is::<T>()
Use this to retrieve TypeId from a type parameter.
use core::any::TypeId; TypeId::of::<T>();
The trait
NodeSubtype
implements:
fn draw(&self, node: &Arc<Node>) {}
fn process(&self, node: &Arc<Node>) {}
fn ready(&self, node: &Arc<Node>) {}
As you can see, this allows NodeSubtype
to access the respective Node
properties in certain events like in draw()
. But with still that, NodeSubtype
doesn't always have access to its respective Node
. So, for example, if a NodeSubtype
has a method f()
, that method f()
can only access properties and methods defined by NodeSubtype
.
Is that a good approach to inheritance?
Approach 2
I could define Node
as a trait and provide a single struct
that covers all the common properties of nodes. I can then provide aliases for properties in this common struct
, such as fn x(self: &Arc<Self>) -> f64 { self.common().x }
use std::sync::{Arc, Weak};
struct NodeCommon {
}
trait Node {
fn common(self: &Arc<Self>) -> Arc<NodeCommon>;
}
struct TabBar {
m_common: Arc<NodeCommon>,
}
impl Node for TabBar {
fn common(self: &Arc<Self>) -> Arc<NodeCommon> {
self.m_common.clone()
}
}
What is better?