我可以边走边修改 Tcl struct::graph 吗?
Can I modify a Tcl struct::graph while walking it?
Tcl struct::graph
有一个 walk
命令,我想用它来删除节点并清理节点属性可访问的数据,例如小部件名称。该文档没有说明在遍历图形时可以做什么和不能做什么,所以我想知道如果我开始删除与行走节点相邻的弧,它是如何工作的。
这是我想要的步行命令(即将完成,可能有错误):
proc csp_scene_walk_remove {mode g n} {
set canvas [$g get canvas]
foreach arc [$g arcs -adj $n] {
$canvas delete [$g arc get $arc widget]
}
$canvas delete [$g node get $n widget] [$g node get $n widgetanno] [$g node get $n widgetanno].bg
$g node delete $n
}
我想如果 walk
适用于实际的图形对象而不是副本,我想它可能会起作用,数据在适当的时候在内部复制等。
问:stuct::graph walk
如果边走边修改图,会有什么行为?
编辑: 该命令似乎可以像这样使用它来执行我想要的操作:
# destroy all nodes downstream with associated widgets
mygraph walk $node -order post -type dfs -dir forward -command csp_scene_walk_remove;
但我无法判断这是否是 Tcllib 所见的实现定义行为。
虽然您正在做的事情会奏效,但您的怀疑是正确的,因为并发修改错误很难解决。因此,最简单的方法是在遍历树时累积要删除的节点列表,然后使用 $graph node delete {*}$theNodes
将它们全部删除。除了我们可以保留我们在图形本身中积累的节点列表,这会稍微简化一些事情。
proc csp_scene_walk_remove {mode g n} {
upvar #0 $nodeAccumulator nodes
set canvas [$g get canvas]
foreach arc [$g arcs -adj $n] {
$canvas delete [$g arc get $arc widget]
}
$canvas delete [$g node get $n widget] [$g node get $n widgetanno] \
[$g node get $n widgetanno].bg
$g lappend deadNodes $n
}
mygraph set deadNodes {}
# Order of traversal is unimportant; nodes remain until afterwards
mygraph walk $node -command csp_scene_walk_remove
# NB: Expanding substitution is very useful here!
mygraph node delete {*}[mygraph get deadNodes]
mygraph unset deadNodes
我更想给每个节点的 canvas 项目一个公共标签(例如,节点 ID!),然后用它来删除它们,这样我就不需要跟踪 canvas 很多东西的ID,但这取决于你...
Tcl struct::graph
有一个 walk
命令,我想用它来删除节点并清理节点属性可访问的数据,例如小部件名称。该文档没有说明在遍历图形时可以做什么和不能做什么,所以我想知道如果我开始删除与行走节点相邻的弧,它是如何工作的。
这是我想要的步行命令(即将完成,可能有错误):
proc csp_scene_walk_remove {mode g n} {
set canvas [$g get canvas]
foreach arc [$g arcs -adj $n] {
$canvas delete [$g arc get $arc widget]
}
$canvas delete [$g node get $n widget] [$g node get $n widgetanno] [$g node get $n widgetanno].bg
$g node delete $n
}
我想如果 walk
适用于实际的图形对象而不是副本,我想它可能会起作用,数据在适当的时候在内部复制等。
问:stuct::graph walk
如果边走边修改图,会有什么行为?
编辑: 该命令似乎可以像这样使用它来执行我想要的操作:
# destroy all nodes downstream with associated widgets
mygraph walk $node -order post -type dfs -dir forward -command csp_scene_walk_remove;
但我无法判断这是否是 Tcllib 所见的实现定义行为。
虽然您正在做的事情会奏效,但您的怀疑是正确的,因为并发修改错误很难解决。因此,最简单的方法是在遍历树时累积要删除的节点列表,然后使用 $graph node delete {*}$theNodes
将它们全部删除。除了我们可以保留我们在图形本身中积累的节点列表,这会稍微简化一些事情。
proc csp_scene_walk_remove {mode g n} {
upvar #0 $nodeAccumulator nodes
set canvas [$g get canvas]
foreach arc [$g arcs -adj $n] {
$canvas delete [$g arc get $arc widget]
}
$canvas delete [$g node get $n widget] [$g node get $n widgetanno] \
[$g node get $n widgetanno].bg
$g lappend deadNodes $n
}
mygraph set deadNodes {}
# Order of traversal is unimportant; nodes remain until afterwards
mygraph walk $node -command csp_scene_walk_remove
# NB: Expanding substitution is very useful here!
mygraph node delete {*}[mygraph get deadNodes]
mygraph unset deadNodes
我更想给每个节点的 canvas 项目一个公共标签(例如,节点 ID!),然后用它来删除它们,这样我就不需要跟踪 canvas 很多东西的ID,但这取决于你...