ValueHolderWithWeakDependents.st
author Claus Gittinger <cg@exept.de>
Thu, 12 Sep 2013 15:17:56 +0200
changeset 3246 d167d433053c
parent 2950 4527bf8b1d19
child 3488 287a7db6b8f4
permissions -rw-r--r--
class: ActiveHelpView changed: #shapeStyle: block shapes on windows

"
 COPYRIGHT (c) 1999 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:libview2' }"

ValueHolder subclass:#ValueHolderWithWeakDependents
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Support-Models'
!

!ValueHolderWithWeakDependents class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1999 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
! !

!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
            ]
        ]
    ] ensure:[
        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.
                    ]
                ]
            ]
        ]
    ] ensure:[
        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.4 2011-09-29 11:19:53 cg Exp $'
! !