Rust - 使用子节点的输出更新树节点
Rust - update tree node with output from children
我正在尝试实现一个 树 结构,其中每个节点都是 更新的 使用其 子节点的一些输出.
无法在最终应用程序中克隆或移动输出。当我给它的子节点的节点引用来更新它时,我 运行 陷入了多次借用错误。
我正在使用 indextree 箱子。
我无法理解它...无法通过这种更新行为找到类似的东西。
我的例子code :
树包含这样的动态节点
type NodeOutput = i64; //(Can't be copied) wgpu::TextureView in final version
trait CalcNode {
fn update(&mut self, input: Vec<&dyn CalcNode>);
fn output(&self) -> NodeOutput;
}
struct NodeModel {
output: NodeOutput, // generated output ()
internal: i64, // some internal state
}
impl CalcNode for NodeModel {
//input can't be cloned/copied in final version
fn update(&mut self, input: Vec<&dyn CalcNode>) {
//example for a possible update function
let child_input: i64 = input.iter().map(|&f| f.output()).sum();
self.output = self.internal * child_input;
self.internal += 1
// this is only an simplified example
//the final version is rendering to a Texture
}
fn output(&self) -> NodeOutput {
// output is not copy-able in final version
self.output
}
}
impl NodeModel {
fn new(internal: i64) -> Self {
Self {
output: internal,
internal,
}
}
}
然后我尝试像这样更新树:
use indextree::{Arena, NodeId};
fn main() {
let (mut arena_, root) = build_tree(); //generate some Tree
let arena = &mut arena_;
let node_stack: Vec<NodeId> = root.descendants(arena).collect(); //collect all nodes depth first
//update in reverse order deepest node first, ROOT LAST.
for &n in node_stack.iter().rev() {
// collect updated children when available
let children: Vec<&dyn CalcNode> = {
n.children(arena)
.map(|f| arena.get(f).unwrap().get().as_ref())
.collect()
};
//get the node to update
//--- can't borrow arena here to get the node ---
let node = { arena.get_mut(n).unwrap().get_mut().as_mut() };
// update the node
node.update(children);
}
}
CalcNode::update
函数实际上不需要访问它的子函数——实际上它只需要从它们计算的值,所以您可以将计算移出 update
函数以防止别名引用:
fn update(&mut self, child_input: i64) {
self.output = self.internal * child_input;
self.internal += 1
}
// <-- Main loop
for &n in node_stack.iter().rev() {
// collect updated children when available
let children: Vec<&dyn CalcNode> = {
n.children(arena)
.map(|f| arena.get(f).unwrap().get().as_ref())
.collect()
};
//example for n possible update funciton
let child_input: i64 = children.iter().map(|&f| f.output()).sum();
//get the node to update
let node = { arena.get_mut(n).unwrap().get_mut().as_mut() };
node.update(child_input);
}
我正在尝试实现一个 树 结构,其中每个节点都是 更新的 使用其 子节点的一些输出.
无法在最终应用程序中克隆或移动输出。当我给它的子节点的节点引用来更新它时,我 运行 陷入了多次借用错误。
我正在使用 indextree 箱子。
我无法理解它...无法通过这种更新行为找到类似的东西。
我的例子code :
树包含这样的动态节点
type NodeOutput = i64; //(Can't be copied) wgpu::TextureView in final version
trait CalcNode {
fn update(&mut self, input: Vec<&dyn CalcNode>);
fn output(&self) -> NodeOutput;
}
struct NodeModel {
output: NodeOutput, // generated output ()
internal: i64, // some internal state
}
impl CalcNode for NodeModel {
//input can't be cloned/copied in final version
fn update(&mut self, input: Vec<&dyn CalcNode>) {
//example for a possible update function
let child_input: i64 = input.iter().map(|&f| f.output()).sum();
self.output = self.internal * child_input;
self.internal += 1
// this is only an simplified example
//the final version is rendering to a Texture
}
fn output(&self) -> NodeOutput {
// output is not copy-able in final version
self.output
}
}
impl NodeModel {
fn new(internal: i64) -> Self {
Self {
output: internal,
internal,
}
}
}
然后我尝试像这样更新树:
use indextree::{Arena, NodeId};
fn main() {
let (mut arena_, root) = build_tree(); //generate some Tree
let arena = &mut arena_;
let node_stack: Vec<NodeId> = root.descendants(arena).collect(); //collect all nodes depth first
//update in reverse order deepest node first, ROOT LAST.
for &n in node_stack.iter().rev() {
// collect updated children when available
let children: Vec<&dyn CalcNode> = {
n.children(arena)
.map(|f| arena.get(f).unwrap().get().as_ref())
.collect()
};
//get the node to update
//--- can't borrow arena here to get the node ---
let node = { arena.get_mut(n).unwrap().get_mut().as_mut() };
// update the node
node.update(children);
}
}
CalcNode::update
函数实际上不需要访问它的子函数——实际上它只需要从它们计算的值,所以您可以将计算移出 update
函数以防止别名引用:
fn update(&mut self, child_input: i64) {
self.output = self.internal * child_input;
self.internal += 1
}
// <-- Main loop
for &n in node_stack.iter().rev() {
// collect updated children when available
let children: Vec<&dyn CalcNode> = {
n.children(arena)
.map(|f| arena.get(f).unwrap().get().as_ref())
.collect()
};
//example for n possible update funciton
let child_input: i64 = children.iter().map(|&f| f.output()).sum();
//get the node to update
let node = { arena.get_mut(n).unwrap().get_mut().as_mut() };
node.update(child_input);
}