author | Claus Gittinger <cg@exept.de> |
Thu, 25 Apr 1996 18:32:07 +0200 | |
changeset 221 | ea942fe5dc04 |
parent 158 | 16f2237474fe |
child 223 | b65dc250db8d |
permissions | -rw-r--r-- |
145 | 1 |
" |
2 |
COPYRIGHT (c) 1995 by Claus Gittinger |
|
158 | 3 |
All Rights Reserved |
145 | 4 |
|
5 |
This software is furnished under a license and may be used |
|
6 |
only in accordance with the terms of that license and with the |
|
7 |
inclusion of the above copyright notice. This software may not |
|
8 |
be provided or otherwise made available to, or used by, any |
|
9 |
other person. No title to or ownership of the software is |
|
10 |
hereby transferred. |
|
11 |
" |
|
12 |
||
13 |
||
14 |
ValueModel subclass:#BlockValue |
|
15 |
instanceVariableNames:'cachedValue arguments block' |
|
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
16 |
classVariableNames:'NeverComputed' |
145 | 17 |
poolDictionaries:'' |
18 |
category:'Interface-Support-Models' |
|
19 |
! |
|
20 |
||
21 |
!BlockValue class methodsFor:'documentation'! |
|
22 |
||
23 |
copyright |
|
24 |
" |
|
25 |
COPYRIGHT (c) 1995 by Claus Gittinger |
|
158 | 26 |
All Rights Reserved |
145 | 27 |
|
28 |
This software is furnished under a license and may be used |
|
29 |
only in accordance with the terms of that license and with the |
|
30 |
inclusion of the above copyright notice. This software may not |
|
31 |
be provided or otherwise made available to, or used by, any |
|
32 |
other person. No title to or ownership of the software is |
|
33 |
hereby transferred. |
|
34 |
" |
|
35 |
||
36 |
! |
|
37 |
||
38 |
documentation |
|
39 |
" |
|
40 |
BlockValues depend on multiple other objects (typically valueHolders) |
|
41 |
and recompute a value whenever one of them changes. |
|
42 |
If the new value is different, it triggers itself a change to its dependents. |
|
43 |
||
44 |
Example use is to base an enableChannels value on multiple other boolean values. |
|
45 |
(See example for how this is done) |
|
46 |
" |
|
47 |
||
48 |
! |
|
49 |
||
50 |
examples |
|
51 |
" |
|
155 | 52 |
checkToggle 3 shows the value of toggle1 AND toggle2 |
53 |
||
158 | 54 |
|val1 val2 both box| |
155 | 55 |
|
158 | 56 |
val1 := false asValue. |
57 |
val2 := false asValue. |
|
58 |
both := BlockValue |
|
59 |
with:[:v1 :v2 | |
|
60 |
Transcript showCr:'evaluating ...'. |
|
61 |
v1 value and:[v2 value] |
|
62 |
] |
|
63 |
arguments:(Array with:val1 with:val2). |
|
155 | 64 |
|
158 | 65 |
box := Dialog new. |
66 |
box addCheckBox:'one' on:val1. |
|
67 |
box addCheckBox:'two' on:val2. |
|
68 |
box addHorizontalLine. |
|
69 |
box addCheckBox:'both' on:both. |
|
70 |
box open |
|
155 | 71 |
|
72 |
the same, using a convenient instance creation message: |
|
73 |
||
158 | 74 |
|val1 val2 both box| |
155 | 75 |
|
158 | 76 |
val1 := false asValue. |
77 |
val2 := false asValue. |
|
78 |
both := BlockValue forLogical:val1 and:val2. |
|
145 | 79 |
|
158 | 80 |
box := Dialog new. |
81 |
box addCheckBox:'one' on:val1. |
|
82 |
box addCheckBox:'two' on:val2. |
|
83 |
box addHorizontalLine. |
|
84 |
box addCheckBox:'both' on:both. |
|
85 |
box open |
|
155 | 86 |
|
87 |
logical or: |
|
88 |
||
158 | 89 |
|val1 val2 both box| |
155 | 90 |
|
158 | 91 |
val1 := false asValue. |
92 |
val2 := false asValue. |
|
93 |
both := BlockValue forLogical:val1 or:val2. |
|
145 | 94 |
|
158 | 95 |
box := Dialog new. |
96 |
box addCheckBox:'one' on:val1. |
|
97 |
box addCheckBox:'two' on:val2. |
|
98 |
box addHorizontalLine. |
|
99 |
box addCheckBox:'both' on:both. |
|
100 |
box open |
|
155 | 101 |
|
102 |
example use: enabling an element depending on two others: |
|
103 |
||
158 | 104 |
|val1 val2 enabler val3 box| |
155 | 105 |
|
158 | 106 |
val1 := false asValue. |
107 |
val2 := false asValue. |
|
108 |
val3 := false asValue. |
|
109 |
enabler := BlockValue forLogical:val1 and:val2. |
|
155 | 110 |
|
158 | 111 |
box := Dialog new. |
112 |
box addCheckBox:'one' on:val1. |
|
113 |
box addCheckBox:'two' on:val2. |
|
114 |
box addHorizontalLine. |
|
115 |
(box addCheckBox:'three' on:val3) enableChannel:enabler. |
|
116 |
box open |
|
145 | 117 |
" |
118 |
! ! |
|
119 |
||
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
120 |
!BlockValue class methodsFor:'initialization'! |
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
121 |
|
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
122 |
initialize |
158 | 123 |
NeverComputed isNil ifTrue:[ |
124 |
NeverComputed := Object new. |
|
125 |
] |
|
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
126 |
! ! |
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
127 |
|
145 | 128 |
!BlockValue class methodsFor:'instance creation'! |
129 |
||
155 | 130 |
forLogical:arg1 and:arg2 |
131 |
"return a new BlockValue computing the logical AND of its args" |
|
132 |
||
133 |
^ (super new) |
|
158 | 134 |
setBlock:[:a :b | a value and:[b value]] |
135 |
arguments:(Array with:arg1 with:arg2) |
|
155 | 136 |
|
137 |
"Created: 16.12.1995 / 19:20:14 / cg" |
|
138 |
! |
|
139 |
||
140 |
forLogical:arg1 or:arg2 |
|
141 |
"return a new BlockValue computing the logical OR of its args" |
|
142 |
||
143 |
^ (super new) |
|
158 | 144 |
setBlock:[:a :b | a value or:[b value]] |
145 |
arguments:(Array with:arg1 with:arg2) |
|
155 | 146 |
|
147 |
"Created: 16.12.1995 / 19:20:14 / cg" |
|
148 |
! |
|
149 |
||
145 | 150 |
with:aBlock |
151 |
"return a new BlockValue computing aBlock" |
|
152 |
||
153 |
^ (super new) setBlock:aBlock |
|
154 |
||
155 |
"Created: 16.12.1995 / 19:16:33 / cg" |
|
156 |
! |
|
157 |
||
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
158 |
with:aBlock argument:anArgument |
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
159 |
"return a new BlockValue computing aBlock" |
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
160 |
|
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
161 |
^ (super new) setBlock:aBlock arguments:(Array with:anArgument) |
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
162 |
|
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
163 |
"Created: 16.12.1995 / 19:20:14 / cg" |
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
164 |
! |
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
165 |
|
145 | 166 |
with:aBlock arguments:aCollectionOfArguments |
167 |
"return a new BlockValue computing aBlock" |
|
168 |
||
169 |
^ (super new) setBlock:aBlock arguments:aCollectionOfArguments |
|
170 |
||
171 |
"Created: 16.12.1995 / 19:20:14 / cg" |
|
172 |
! ! |
|
173 |
||
174 |
!BlockValue methodsFor:'accessing'! |
|
175 |
||
176 |
dependOn:someObject |
|
177 |
arguments isNil ifTrue:[ |
|
158 | 178 |
arguments := Array with:someObject |
145 | 179 |
] ifFalse:[ |
158 | 180 |
arguments := arguments copyWith:someObject |
145 | 181 |
]. |
182 |
someObject addDependent:self |
|
183 |
||
184 |
"Modified: 16.12.1995 / 19:18:31 / cg" |
|
185 |
! |
|
186 |
||
187 |
evaluate |
|
188 |
arguments isNil ifTrue:[ |
|
158 | 189 |
^ block value |
145 | 190 |
]. |
191 |
^ block valueWithArguments:(arguments asArray) |
|
192 |
||
193 |
"Created: 16.12.1995 / 19:27:40 / cg" |
|
194 |
! |
|
195 |
||
196 |
setBlock:aBlock |
|
197 |
block := aBlock. |
|
198 |
arguments notNil ifTrue:[ |
|
158 | 199 |
self release |
145 | 200 |
]. |
201 |
arguments := nil. |
|
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
202 |
cachedValue := NeverComputed. |
145 | 203 |
|
204 |
"Created: 16.12.1995 / 19:16:59 / cg" |
|
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
205 |
"Modified: 16.12.1995 / 19:51:23 / cg" |
145 | 206 |
! |
207 |
||
208 |
setBlock:aBlock arguments:aCollectionOfArguments |
|
209 |
block := aBlock. |
|
210 |
arguments notNil ifTrue:[ |
|
158 | 211 |
self release |
145 | 212 |
]. |
213 |
arguments := aCollectionOfArguments. |
|
214 |
arguments do:[:arg | |
|
158 | 215 |
arg addDependent:self |
145 | 216 |
]. |
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
217 |
cachedValue := NeverComputed. |
145 | 218 |
|
219 |
"Created: 16.12.1995 / 19:21:41 / cg" |
|
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
220 |
"Modified: 16.12.1995 / 19:51:28 / cg" |
145 | 221 |
! |
222 |
||
155 | 223 |
setValue:newValue |
224 |
"physically set my value, without change notifications. |
|
225 |
This is a noop here, since my value is computed." |
|
226 |
||
227 |
^ self |
|
228 |
||
229 |
||
230 |
! |
|
231 |
||
145 | 232 |
value |
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
233 |
cachedValue == NeverComputed ifTrue:[ |
158 | 234 |
cachedValue := self evaluate |
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
235 |
]. |
145 | 236 |
^ cachedValue |
237 |
||
238 |
"Created: 16.12.1995 / 19:23:26 / cg" |
|
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
239 |
"Modified: 17.12.1995 / 15:59:16 / cg" |
145 | 240 |
! ! |
241 |
||
242 |
!BlockValue methodsFor:'change and update'! |
|
243 |
||
244 |
update:something with:aParameter from:someone |
|
245 |
|oldValue| |
|
246 |
||
247 |
oldValue := cachedValue. |
|
248 |
cachedValue := self evaluate. |
|
249 |
oldValue ~~ cachedValue ifTrue:[ |
|
158 | 250 |
self changed:#value |
145 | 251 |
]. |
252 |
||
253 |
"Created: 16.12.1995 / 19:22:54 / cg" |
|
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
254 |
"Modified: 17.12.1995 / 15:58:56 / cg" |
145 | 255 |
! ! |
256 |
||
257 |
!BlockValue methodsFor:'release'! |
|
258 |
||
259 |
release |
|
260 |
arguments notNil ifTrue:[ |
|
158 | 261 |
arguments do:[:arg | arg removeDependent:self]. |
145 | 262 |
]. |
263 |
||
264 |
"Modified: 16.12.1995 / 19:21:11 / cg" |
|
265 |
! ! |
|
266 |
||
267 |
!BlockValue class methodsFor:'documentation'! |
|
268 |
||
269 |
version |
|
158 | 270 |
^ '$Header: /cvs/stx/stx/libview2/BlockValue.st,v 1.4 1996-01-27 18:36:36 cg Exp $' |
145 | 271 |
! ! |
146
9603cec98ac2
oops change notification was wrong
Claus Gittinger <cg@exept.de>
parents:
145
diff
changeset
|
272 |
BlockValue initialize! |