portal Michała Hanćkowiaka
Begin main content
wm withdraw .; wm geom .output 379x366+231+5; wm geo .konsola 724x689+626+5; catch {source ~/tcl/111/dodatki2_kons.tcl}

## programowanie zdarzeniowe, coroutine
# + rozszerzenie ebp02.tcl...
# + dodałem możliwość wielu msg typu A (z niedokon handlerem)
# + jak zrobic to samo z vwait ?!
#

lassign [chan pipe] wy we
  # ^ łącze nienazwane do wysylania msg

fileevent $wy readable {
  set msg [gets $wy]; if {[eof $wy]} {close $wy; return}
  set typ [lindex $msg 0]
  if {![info exists event($typ)]} {_puts "brak obslugi $typ"; return}
  eval $event($typ)
    # ^ to się wykonuje na poziomie globalnym
}
proc czekaj_na typ {
  dolacz ::coro$typ [info coro]
  set ::event($typ) "\[pobierz ::coro$typ\]"
  yield
  if {[llength [set ::coro$typ]]==0} {unset ::event($typ)}
  return $::msg
}

proc dolacz {li_ w} { # dołącz jeśli nie ma (!)
  upvar $li_ li; if {![info exists li]} {set li {}}
  if {[lsearch -exact $li $w]==-1} {lappend li $w}
}
proc pobierz {li_} {
  upvar $li_ li; set r [lindex $li 0]; set li [lrange $li 1 end]
  return $r
}
set new_coro_licz 0
proc new_coro args { # auto nazwy coroutin
  set nc coro#$::new_coro_licz#
  coroutine $nc {*}$args; incr ::new_coro_licz
}

array unset event
set event(A) {new_coro handlerA $msg}
set event(B) {coroutine coroB handlerB $msg}
  # ^ początkowa obsluga zdarzeń
  # ^ typ A i B inaczej obslugiwany !!

proc handlerA {m} {
  _puts "A/111 [info coro] '$m'"
  set m2 [czekaj_na A1]
  _puts "A/222 [info coro] '$m2'"
}
proc handlerB {m} {
  _puts "B/111 [info coro] '$m'"
  set m2 [czekaj_na B1]
  _puts "B/222 [info coro] '$m2'"
}

# ^^^ wykonaj ^^^

.output.t delete 1.0 end

array get event

puts $we "A 123"; flush $we
puts $we "B 321"; flush $we

array get event

puts $we "A1 1233"; flush $we
puts $we "B1 3211"; flush $we


exit

uwaga: portal używa ciasteczek tylko do obsługi tzw. sesji...