I want to have nodes which behave similar to systems. Each entity can have a graph instance containing the nodes.
It does make sense to run all equivalent nodes on different entities in one wrapper system.
A node looks like
fn node(slot_a: Slot<0, T>, world_query: World<Query<&U>>, mut world_query_mut: World<Query<&mut V>>) -> (Slot0Val, Slot1Val) {
(Slot0Val, Slot1Val)
}
Here World is clashingly/badly named and means it wraps a SystemParam to act like a NodeParam.
The params of a node function impl the trait NodeParam.
A wrapper system for a node looks something like
fn into_system<F>(f: F) where F: NodeFunction {
.
.
.
let system = move |query: Query<QueryForAllEquivalentNodes>, param: <F::NodeParam as NodeParam>::SystemParam| {
for node in &query {
let param = F::NodeParam::get_param(node, param);
let output = f.run(param);
.
.
.
}
}
}
where NodeParam is also implemented for tuples of NodeParam - not important but may be a detail you scratch your head around.
This all already works great with immutable SystemParams, but when mutability is desired all lifetime annotations just explode because of invariation.
I have reduced it to a simpler example.