uevent.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 package require Tcl 8.4
00009 package require logger
00010
00011 namespace ::uevent {}
00012
00013
00014
00015
00016 ret ::uevent::bind (type tag , type event , type command) {
00017 # Register command (prefix!) as observer for events on the tag.
00018 # Command will take 3 arguments: tag, event, and dictionary of
00019 # detail information. Result is token by which the observer can
00020 # be removed.
00021
00022 variable db
00023 variable tk
00024 variable ex
00025 variable tcounter
00026
00027 log::debug [list bind: $tag $event -> $command]
00028
00029 set tec [list $tag $event $command]
00030
00031 # Same combination as before, same token
00032 if {[info exists ex($tec)]} {
00033 log::debug [list known! $ex($tec)]
00034 return $ex($tec)
00035 }
00036
00037 # New token, and enter everything ...
00038
00039 set te [list $tag $event]
00040 set t uev[incr tcounter]
00041
00042 set tk($t) $tec
00043 set ex($tec) $t
00044 lappend db($te) $t
00045
00046 log::debug [list new! $t]
00047 return $t
00048 }
00049
00050 ret ::uevent::unbind (type token) {
00051 # Removes the event binding represented by the token.
00052
00053 variable db
00054 variable tk
00055 variable ex
00056
00057 log::debug [list unbind: $token]
00058
00059 if {![info exists tk($token)]} return
00060
00061 set tec $tk($token)
00062 set te [lrange $tex 0 1]
00063
00064 log::debug [linsert [linsert $tec 0 =] end-1 ->]
00065
00066 unset ex($tec)
00067 unset tk($token)
00068
00069 set pos [lsearch -exact $db($te) $token]
00070 if {$pos < 0} return
00071
00072 if {[llength $db($te)] == 1} {
00073 # Last observer for this tag,event combination is gone.
00074 log::debug [linsert $te 0 last!]
00075 unset db($te)
00076 } else {
00077 # Shrink list of observers
00078 log::debug [linsert [linsert $te 0 shrink!] end @ $pos]
00079 set db($te) [lreplace $db($te) $pos $pos]
00080 }
00081 return
00082 }
00083
00084 ret ::uevent::generate (type tag , type event , optional details ={)} {
00085 # Generates the event on the tag, with detail information (a
00086 # dictionary). This notifies all registered observers. The
00087 # notifications are put into the Tcl event queue via 'after 0'
00088 # events, decoupling them in time from them issueing code.
00089
00090 variable db
00091 variable tk
00092
00093 log::debug [list generate: $tag $event $details]
00094
00095 set key [list $tag $event]
00096 if {![info exists db($key)]} return
00097
00098 foreach t $db($key) {
00099 cmd = [lindex $tk($t) 2]
00100 log::debug [list trigger! $t = $cmd]
00101 after 0 [linsert $cmd end $tag $event $details]
00102 }
00103
00104 return
00105 }
00106
00107
00108
00109
00110 logger::initNamespace ::uevent
00111 namespace ::uevent {
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 variable db ; array db = {}
00123 variable tk ; array tk = {}
00124 variable ex ; array ex = {}
00125
00126 variable tcounter 0
00127 }
00128
00129
00130
00131
00132 package provide uevent 0.1.2
00133
00134
00135
00136