initial checkin
authorClaus Gittinger <cg@exept.de>
Mon, 25 Oct 1999 16:52:53 +0200
changeset 1257 6c1eab277273
parent 1256 338de8fddab9
child 1258 a6d935055c0b
initial checkin
ValueHolderWithWeakDependents.st
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ValueHolderWithWeakDependents.st	Mon Oct 25 16:52:53 1999 +0200
@@ -0,0 +1,127 @@
+ValueHolder subclass:#ValueHolderWithWeakDependents
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Support-Models'
+!
+
+
+!ValueHolderWithWeakDependents methodsFor:'dependents access'!
+
+addDependent:anObject
+    "make the argument, anObject be a weak dependent of the receiver"
+
+    |wasBlocked|
+
+    wasBlocked := OperatingSystem blockInterrupts.
+    [
+        |deps dep|
+
+        deps := dependents.
+        "/
+        "/ store the very first dependent directly in
+        "/ the dependents instVar
+        "/
+        (deps isNil and:[anObject isCollection not]) ifTrue:[
+            dependents := WeakArray with:anObject
+        ] ifFalse:[
+            deps class == WeakArray ifTrue:[
+                dep := deps at:1.
+                dep ~~ anObject ifTrue:[
+                    (dep isNil or:[dep == 0]) ifTrue:[
+                        deps at:1 put:anObject
+                    ] ifFalse:[
+                        self dependents:(WeakIdentitySet with:dep with:anObject)
+                    ]
+                ]
+            ] ifFalse:[
+                deps add:anObject
+            ]
+        ]
+    ] valueNowOrOnUnwindDo:[
+        wasBlocked ifFalse:[
+            OperatingSystem unblockInterrupts
+        ]
+    ]
+
+    "Modified: 8.1.1997 / 23:40:30 / cg"
+
+
+!
+
+dependentsDo:aBlock
+    "evaluate aBlock for all of my dependents"
+
+    |deps|
+
+    deps := dependents.
+    deps size ~~ 0 ifTrue:[
+        deps do:[:d | 
+                    (d notNil and:[d ~~ 0]) ifTrue:[
+                        aBlock value:d
+                    ]
+                ]
+    ].
+
+!
+
+removeDependent:anObject
+    "make the argument, anObject be independent of the receiver"
+
+    |wasBlocked|
+
+    "/ must do this save from interrupts, since the dependents collection
+    "/ is possibly accessed from multiple threads.
+    "/ Used to use #valueUninterruptably here; inlined that code for slightly
+    "/ faster execution.
+
+    wasBlocked := OperatingSystem blockInterrupts.
+    [
+        |deps n d|
+
+        deps := dependents.
+        deps size ~~ 0 ifTrue:[
+
+            "/ to save a fair amount of memory in case of
+            "/ many dependencies, we store a single dependent in
+            "/ a WeakArray, and switch to a WeakSet if more dependents are
+            "/ added. Here we have to do the inverse ...
+
+            deps class == WeakArray ifTrue:[
+                ((d := deps at:1) == anObject 
+                or:[d isNil
+                or:[d == 0]]) ifTrue:[
+                    dependents := nil
+                ]
+            ] ifFalse:[
+                deps remove:anObject ifAbsent:[].
+                (n := deps size) == 0 ifTrue:[
+                    dependents := nil
+                ] ifFalse:[
+                    n == 1 ifTrue:[
+                        d := deps firstIfEmpty:nil.
+                        d notNil ifTrue:[
+                            deps := WeakArray with:d
+                        ] ifFalse:[
+                            deps := nil
+                        ].
+                        dependents := deps.
+                    ]
+                ]
+            ]
+        ]
+    ] valueNowOrOnUnwindDo:[
+        wasBlocked ifFalse:[
+            OperatingSystem unblockInterrupts
+        ]
+    ]
+
+    "Modified: / 26.1.1998 / 19:51:50 / cg"
+
+! !
+
+!ValueHolderWithWeakDependents class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/libview2/ValueHolderWithWeakDependents.st,v 1.1 1999-10-25 14:52:53 cg Exp $'
+! !