1 # vim: foldmarker=<<<,>>>
6 constructor
{accessvar args
} {
7 upvar $accessvar scopevar
8 eval tlc
::Signal::constructor scopevar
16 method attach_input
{gate_obj
{a_sense normal
}}
17 method detach_input
{gate_obj
}
18 method detach_all_inputs
{}
20 method attach_var_input
{varname
{a_sense normal
}}
21 method detach_var_input
{varname
}
23 method explain_state
{}
24 method explain_txt
{{depth
0}}
30 variable var_inputs
{}
33 method calc_o_state
{}
34 method input_update
{gate_obj state
}
35 method var_input_update
{varname n1 n2 op
}
36 method cleanup
{gate_obj
}
41 configbody tlc
::Gate::default { #<<<1
46 configbody tlc
::Gate::mode { #<<<1
47 switch [string tolower
$mode] {
56 error "Invalid mode specified. Must be one of and, or"
62 body tlc
::Gate::constructor {accessvar args
} { #<<<1
71 body tlc
::Gate::destructor {} { #<<<1
72 foreach var_input
$var_inputs {
73 detach_var_input
$var_input
75 foreach input
[array names inputs
] {
77 if {[$input isa tlc
::Signal]} {
78 $input detach_output
[code
$this input_update
$input]
85 body tlc
::Gate::attach_input {gate_obj
{a_sense normal
}} { #<<<1
86 if {![$gate_obj isa tlc
::Signal]} {
87 error "$gate_obj isn't a tlc::Gate"
90 #$gate_obj register_handler debug [code $this debug]
91 set sense
($gate_obj) [expr {$a_sense != "normal"}]
93 return [$gate_obj attach_output
[code
$this input_update
$gate_obj] \
94 [code
$this cleanup
$gate_obj]]
98 body tlc
::Gate::detach_input {gate_obj
} { #<<<1
99 if {![$gate_obj isa tlc
::Signal]} {
100 error "$gate_obj isn't a tlc::Gate"
103 debug debug
"tlc::Gate::detach_input ($this): ($gate_obj)"
105 set ok
[catch {unset inputs
($gate_obj)} msg
]
106 catch {unset sense
($gate_obj)}
108 $gate_obj detach_output
[code
$this input_update
$gate_obj]
114 body tlc
::Gate::detach_all_inputs {} { #<<<1
115 foreach vinput
$var_inputs {
116 detach_var_input
$vinput
118 foreach gate_obj
[array names inputs
] {
119 detach_input
$gate_obj
124 body tlc
::Gate::attach_var_input {varname
{a_sense normal
}} { #<<<1
125 set idx
[lsearch $var_inputs $varname]
127 lappend var_inputs
$varname
129 set isvar
(${this
}::$varname) $varname
130 set sense
(${this
}::$varname) [expr {$a_sense == "inverted"}]
131 trace variable $varname wu
[code
$this var_input_update
$varname]
133 var_input_update
$varname $varname "" w
134 # tlc::Watchvar $this::$varname -varname $varname \
135 # -state_cb [code $this input_update $this::$varname]
139 body tlc
::Gate::detach_var_input {varname
} { #<<<1
140 set idx
[lsearch $var_inputs $varname]
141 set var_inputs
[lreplace $var_inputs $idx $idx]
142 trace vdelete
$varname wu
[code
$this var_input_update
$varname]
144 catch {unset inputs
(${this
}::$varname)}
145 catch {unset sense
(${this
}::$varname)}
146 catch {unset isvar
(${this
}::$varname)}
152 body tlc
::Gate::input_update {gate_obj state
} { #<<<1
153 if {$sense($gate_obj)} {
154 set state
[expr {!$state}]
156 debug debug
"tlc::Gate::input_update ($this) ($name): ($gate_obj) ($state)"
157 set inputs
($gate_obj) $state
163 body tlc
::Gate::var_input_update {varname n1 n2 op
} { #<<<1
167 if {![info exists value
]} {
168 error "var doesn't exist! ($varname)"
171 [string is boolean
$value] && $value
173 if {$sense(${this
}::$varname)} {
174 set state
[expr {!$state}]
176 set inputs
(${this
}::$varname) $state
182 detach_var_input
$varname
188 body tlc
::Gate::calc_o_state {} { #<<<1
189 set inputlist
[array names inputs
]
191 if {[llength $inputlist] == 0} {
192 set new_o_state
$default
194 switch [string tolower
$mode] {
195 "and" - "nor" {set assume
1}
196 "nand" - "or" {set assume
0}
199 foreach input
$inputlist {
200 switch [string tolower
$mode] {
202 if {!$inputs($input)} {
203 set assume
[expr {!($assume)}]
209 if {$inputs($input)} {
210 set assume
[expr {!($assume)}]
217 set new_o_state
$assume
220 set_state
$new_o_state
224 body tlc
::Gate::cleanup {gate_obj
} { #<<<1
225 detach_input
$gate_obj
229 body tlc
::Gate::explain_state {} { #<<<1
230 return [array get inputs
]
234 body tlc
::Gate::explain_txt {{depth
0}} { #<<<1
236 set firstdepth
[expr {($depth > 0) ?
$depth-1 : 0}]
237 append txt
"$this \"[$this name]\": [$this state]\[$default\] [string toupper [$this cget -mode]] (\n"
238 foreach key
[array names inputs
] {
239 # append txt "[string repeat { } $firstdepth]"
240 append txt
"[string repeat { } $depth]"
241 append txt
$inputs($key)
242 append txt
[expr {$sense($key) ?
"i" : " "}]
243 if {[info exists isvar
($key)]} {
244 append txt
"$this var_input: $isvar($key) ($inputs($key))\n"
246 append txt
[$key explain_txt
[expr {$depth + 1}]]
249 append txt
"[string repeat { } $depth])\n"