From: Paul on
Is it possible to check if the command created by coroutine exists?
i.e.

coroutine cr aProc
cr
cr

At some point cr will disappear, that's what I would like to check
for.

I've tried info procs cr to test if cr exists but that doesn't work.

Thanks
From: Donal K. Fellows on
On 13/02/2010 08:34, Paul wrote:
> Is it possible to check if the command created by coroutine exists?
[...]
> At some point cr will disappear, that's what I would like to check
> for.
>
> I've tried info procs cr to test if cr exists but that doesn't work.

Plain old [llength [info commands cr]] should work; coroutines are
commands, and are implemented in C so aren't listed in [info procs]. You
can also set a command delete trace on the coro if you want notification
of when it goes away.

Donal.
From: Paul on
On Feb 13, 10:45 am, "Donal K. Fellows"
<donal.k.fell...(a)manchester.ac.uk> wrote:
> On 13/02/2010 08:34, Paul wrote:
>
> > Is it possible to check if the command created by coroutine exists?
> [...]
> > At some point cr will disappear, that's what I would like to check
> > for.
>
> > I've tried info procs cr to test if cr exists but that doesn't work.
>
> Plain old [llength [info commands cr]] should work; coroutines are
> commands, and are implemented in C so aren't listed in [info procs]. You
> can also set a command delete trace on the coro if you want notification
> of when it goes away.
>
> Donal.

Thanks. I've been experimenting with Tcl coroutines, scheduling and
then executing procs, fwiw with the code below. Now seems to work.

# list for storing scheduled commands
set scheduledCmds [list]

# for generating unique coroutine names
set count 0

# schedules command for execution
proc schedule {cmd args} {
global scheduledCmds
lappend scheduledCmds [dict create cmdName $cmd coro "" cmdArgs
$args]
}

# executes each scheduled command until yield (or return)
proc execute {} {
global scheduledCmds count
set i 0
while {$i < [llength $scheduledCmds]} {
set cmdInstance [lindex $scheduledCmds $i]
if {[dict get $cmdInstance coro] == ""} {
incr count
dict set cmdInstance coro "cr_id_$count"
lset scheduledCmds $i $cmdInstance
coroutine "cr_id_$count" [dict get $cmdInstance cmdName] \
{*}[dict get $cmdInstance cmdArgs]
} else {
[dict get $cmdInstance coro]
}
if {[llength [info commands [dict get $cmdInstance coro]]] ==
0} {
set scheduledCmds [lreplace $scheduledCmds $i $i]
} else {
incr i
}
}
}

proc aProc {a b} {
set i 1
puts "([info coroutine]: $a) i: $i"
yield
incr i
puts "([info coroutine]: $b) i: $i"
}

proc bProc {a b} {
set j 5
puts "([info coroutine]: $a) j: $j"
yield
incr j
puts "([info coroutine]: $b) j: $j"
}

schedule aProc "a" "more a"
schedule bProc "b" "more b"
schedule aProc "a again" "more a again"
schedule bProc "b again" "more b again"

while {[llength $scheduledCmds] != 0} {
execute
}



Outputs the following:

(::cr_id_1: a) i: 1
(::cr_id_2: b) j: 5
(::cr_id_3: a again) i: 1
(::cr_id_4: b again) j: 5
(::cr_id_1: more a) i: 2
(::cr_id_2: more b) j: 6
(::cr_id_3: more a again) i: 2
(::cr_id_4: more b again) j: 6