Registry.st
changeset 1 a27a279701f8
child 2 6526dde5f3ac
equal deleted inserted replaced
0:aa2498ef6470 1:a27a279701f8
       
     1 "
       
     2  COPYRIGHT (c) 1993 by Claus Gittinger
       
     3               All Rights Reserved
       
     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 Object subclass:#Registry
       
    14        instanceVariableNames:'registeredObjects phantoms'
       
    15        classVariableNames:''
       
    16        poolDictionaries:''
       
    17        category:'System-Support'
       
    18 !
       
    19 
       
    20 Registry comment:'
       
    21 
       
    22 COPYRIGHT (c) 1993 by Claus Gittinger
       
    23               All Rights Reserved
       
    24 
       
    25 %W% %E%
       
    26 written jun 93 by claus
       
    27 '!
       
    28 
       
    29 !Registry class methodsFor:'documentation'!
       
    30 
       
    31 documentation
       
    32 "
       
    33 Registries provide an easy interface to using ShadowArrays. 
       
    34 A class, which wants to be informed of instance-death, can put a created object
       
    35 into a registry. The registry will create a copy of the object, and
       
    36 watch out for death of the registered object. When it dies, the copy will
       
    37 be sent the message >>disposed.
       
    38 The trick with the shallow copy is especially nice, you can think of it as
       
    39 beeing the original object which died.
       
    40 
       
    41 All objects, which keep external resources (such as fileDescriptors, fonts, 
       
    42 colormap-entries etc.) should be registered, so that the underlying resource
       
    43 can be freed when the object goes away.
       
    44 
       
    45 Of course, you too can use it to do whatever you need to do in case of the
       
    46 death of an object.
       
    47 "
       
    48 ! !
       
    49 
       
    50 !Registry methodsFor:'dispose handling'!
       
    51 
       
    52 informDispose
       
    53     "an instance has been destroyed - look which one it was"
       
    54 
       
    55     |phantom|
       
    56 
       
    57     1 to:phantoms size do:[:index |
       
    58         (registeredObjects at:index) isNil ifTrue:[
       
    59             (phantoms at:index) notNil ifTrue:[
       
    60                 phantom := phantoms at:index.
       
    61                 phantoms at:index put:nil.
       
    62                 phantom disposed
       
    63             ]
       
    64         ]
       
    65     ]
       
    66 ! !
       
    67 
       
    68 !Registry methodsFor:'enumeration'!
       
    69 
       
    70 contentsDo:aBlock
       
    71     "evaluate aBlock for each registered object"
       
    72 
       
    73     registeredObjects notNil ifTrue:[
       
    74         registeredObjects do:[:o |
       
    75             o notNil ifTrue:[
       
    76                 aBlock value:o
       
    77             ]
       
    78         ]
       
    79     ]
       
    80 ! !
       
    81 
       
    82 !Registry methodsFor:'accessing'!
       
    83 
       
    84 contents
       
    85     "return the collection of registered objects"
       
    86 
       
    87     ^ registeredObjects
       
    88 !
       
    89 
       
    90 changed:anObject
       
    91     "a registered object has changed, create a new phantom"
       
    92 
       
    93     |index|
       
    94 
       
    95     index := registeredObjects identityIndexOf:anObject ifAbsent:[0].
       
    96     index ~~ 0 ifTrue:[
       
    97         phantoms at:index put:anObject shallowCopy.
       
    98     ]
       
    99 !
       
   100 
       
   101 register:anObject
       
   102     "register anObject, so that a copy of it gets the disposed message
       
   103      when anObject dies (somewhere in the future)"
       
   104 
       
   105     |phantom newColl count p index|
       
   106 
       
   107     phantom := anObject shallowCopy.
       
   108 
       
   109     registeredObjects isNil ifTrue:[
       
   110         registeredObjects := ShadowArray new:10.
       
   111         registeredObjects watcher:self.
       
   112         registeredObjects at:1 put:anObject.
       
   113         phantoms := VariableArray with:phantom.
       
   114         ^ self
       
   115     ].
       
   116 
       
   117     index := registeredObjects identityIndexOf:anObject ifAbsent:[0].
       
   118     index ~~ 0 ifTrue:[
       
   119 	self error:'bad register'.
       
   120 	phantoms at:index put:phantom.
       
   121 	^ self
       
   122     ].
       
   123 
       
   124     "search for a free slot, on the fly look for leftovers"
       
   125     count := phantoms size.
       
   126     1 to:count do:[:index |
       
   127         (registeredObjects at:index) isNil ifTrue:[
       
   128             "is there a leftover ?"
       
   129             (phantoms at:index) notNil ifTrue:[
       
   130                 p := phantoms at:index.
       
   131                 phantoms at:index put:nil.
       
   132                 p disposed
       
   133             ].
       
   134             (phantoms at:index) isNil ifTrue:[
       
   135                 registeredObjects at:index put:anObject.
       
   136                 phantoms at:index put:phantom.
       
   137                 ^ self
       
   138             ]
       
   139         ]
       
   140     ].
       
   141 
       
   142     "no free slot, add at the end"
       
   143 
       
   144     newColl := ShadowArray new:(count * 2).
       
   145     newColl replaceFrom:1 to:count with:registeredObjects.
       
   146     registeredObjects := newColl.
       
   147     registeredObjects watcher:self.
       
   148 
       
   149     registeredObjects at:(count + 1) put:anObject.
       
   150     phantoms add:phantom
       
   151 !
       
   152 
       
   153 unregister:anObject
       
   154     "remove registration of anObject, without telling the phantom;
       
   155      should be sent, if we are no more interrested in destruction of
       
   156      anObject (i.e. it no longer holds external resources)."
       
   157 
       
   158     |index|
       
   159 
       
   160     index := registeredObjects identityIndexOf:anObject ifAbsent:[0].
       
   161     index ~~ 0 ifTrue:[
       
   162         phantoms at:index put:nil.
       
   163         registeredObjects at:index put:nil
       
   164     ]
       
   165 ! !