--- /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 $'
+! !