在循环过程运行时将命令添加到循环过程中



我的目标是将命令添加到已经运行的循环中,我知道如何使用这样的全局变量:

proc myLoop {} {
global cmd1 cmd2 cmd3
if {$cmd1} {
# do something...
}
if {$cmd2} {
# do something...
}
# ...

after 1000 myLoop
}
set cmd1 0 ; set cmd2 1
myLoop

我想在飞行中做到这一点:CCD_ 1。我曾想过每次都重命名我的myLoop并替换它,但我不知道这是否可行或有效。

您可以将命令放在一个列表中,并每次处理该列表。要添加命令,只需将其附加到列表中即可。

proc myLoop {} {
global cmdlist
foreach cmd $cmdlist {
# Execute the command in the global scope
uplevel #0 $cmd
}
after 1000 myLoop
}
set cmdlist [list $cmd1 $cmd2]
# Start the loop
myLoop
# Add a command
lappend cmdlist [list myCmd $arg1 $arg2]

你也可以通过协同程序来避免使用全局变量:

proc myLoop {cmdlist} {
foreach cmd $cmdlist {
# Execute the command in the global scope
uplevel #0 $cmd
}
after 1000 [list [info coroutine] continue]
while {[set arg [yield]] ne "continue"} {
lappend cmdlist $arg
}
}
coroutine addCmdInLoop myLoop $cmd1 $cmd2

然后,您提出的addCmdInLoop [list myCmd $arg1 $arg2]命令将用于将myCmd添加到循环的任何未来运行中。

如果myLoop已经在运行,那么我不知道如何中断循环来更改变量。如果不更改变量,那么循环将以相同的方式运行。

你当然可以改变一些Tcl的外部。如果您的循环检查是否存在文件名而不是变量的值,该怎么办?

您可能想做的是向这些变量添加跟踪。https://www.tcl-lang.org/man/tcl/TclCmd/trace.htm

proc do_cmd1 args {
global cmd1
if {$cmd1 == 1} {
puts "cmd1 is 1"
}
}
trace add variable cmd1 write do_cmd1

一旦将跟踪分配给变量,则每当向cmd1写入值时,就会执行do_cmd1过程。

tcl8.6.8> set cmd1 0
0
tcl8.6.8> set cmd1 1
cmd1 is 1    <------ Look at that!!
1

但是,这只会在设置cmd1变量时运行proc。这并不是真正的循环行为。

最新更新