Registry.st
changeset 159 514c749165c3
parent 117 270ddeff4a48
child 217 a0400fdbc933
equal deleted inserted replaced
158:be947d4e7fb2 159:514c749165c3
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 Object subclass:#Registry
    13 Object subclass:#Registry
    14        instanceVariableNames:'registeredObjects phantoms cleanState'
    14        instanceVariableNames:'registeredObjects phantomArray cleanState'
    15        classVariableNames:''
    15        classVariableNames:''
    16        poolDictionaries:''
    16        poolDictionaries:''
    17        category:'System-Support'
    17        category:'System-Support'
    18 !
    18 !
    19 
    19 
    20 Registry comment:'
    20 Registry comment:'
    21 COPYRIGHT (c) 1993 by Claus Gittinger
    21 COPYRIGHT (c) 1993 by Claus Gittinger
    22               All Rights Reserved
    22               All Rights Reserved
    23 
    23 
    24 $Header: /cvs/stx/stx/libbasic/Registry.st,v 1.9 1994-08-22 12:12:55 claus Exp $
    24 $Header: /cvs/stx/stx/libbasic/Registry.st,v 1.10 1994-10-10 00:27:59 claus Exp $
    25 '!
    25 '!
    26 
    26 
    27 !Registry class methodsFor:'documentation'!
    27 !Registry class methodsFor:'documentation'!
    28 
    28 
    29 copyright
    29 copyright
    40 "
    40 "
    41 !
    41 !
    42 
    42 
    43 version
    43 version
    44 "
    44 "
    45 $Header: /cvs/stx/stx/libbasic/Registry.st,v 1.9 1994-08-22 12:12:55 claus Exp $
    45 $Header: /cvs/stx/stx/libbasic/Registry.st,v 1.10 1994-10-10 00:27:59 claus Exp $
    46 "
    46 "
    47 !
    47 !
    48 
    48 
    49 documentation
    49 documentation
    50 "
    50 "
    51     Registries provide an easy interface to using WeakArrays. 
    51     Registries provide an easy interface to using WeakArrays. 
    52     A class, which wants to be informed of instance-death, can put a created object
    52     A class, which wants to be informed of instance-death, can put a created object
    53     into a registry. The registry will create a copy of the object, and
    53     into a registry. The registry will create a (shallow-)copy of the object, and
    54     watch out for death of the registered object. When it dies, the copy will
    54     watch out for death of the original object. When it dies, the copy will
    55     be sent the message >>disposed.
    55     be sent the #disposed-message.
    56     The trick with the shallow copy is especially nice, you can think of it as
    56     The trick with the shallow copy is especially nice, you can think of it as
    57     being the original object which died.
    57     being the original object which died.
    58 
    58 
    59     All objects, which keep external resources (such as fileDescriptors, fonts, 
    59     All objects, which keep external resources (such as fileDescriptors, fonts, 
    60     colormap-entries etc.) should be registered, so that the underlying resource
    60     colormap-entries etc.) should be registered, so that the underlying resource
    61     can be freed when the object goes away.
    61     can be freed when the object goes away.
    62 
    62 
    63     Of course, you too can use it to do whatever you need to do in case of the
    63     Of course, you too can use it to do whatever you need to do in case of the
    64     death of an object.
    64     death of an object.
       
    65 
       
    66     Registries use #shallowCopyForFinalization to aquire the copy of the original,
       
    67     this can be redefined in registered classes for faster copying 
       
    68     (typically, not all internal state but only some device handles are needed for 
       
    69     finalization).
       
    70 
       
    71     See axample uses in Form, Color, ExternalStream and Font
    65 "
    72 "
    66 ! !
    73 ! !
    67 
    74 
    68 !Registry methodsFor:'dispose handling'!
    75 !Registry methodsFor:'dispose handling'!
    69 
    76 
    70 informDispose
    77 informDispose
    71     "an instance has been destroyed - look which one it was"
    78     "an instance has been destroyed - look which one it was"
    72 
    79 
    73     |phantom|
    80     |phantom
       
    81      sz "{ Class: SmallInteger }"|
    74 
    82 
    75     cleanState ifTrue:[
    83     cleanState ifTrue:[
    76         1 to:phantoms size do:[:index |
    84 	sz := phantomArray size.
       
    85         1 to:sz do:[:index |
    77             (registeredObjects at:index) isNil ifTrue:[
    86             (registeredObjects at:index) isNil ifTrue:[
    78                 phantom := phantoms at:index.
    87                 phantom := phantomArray at:index.
    79                 phantom notNil ifTrue:[
    88                 phantom notNil ifTrue:[
    80                     phantoms at:index put:nil.
    89                     phantomArray at:index put:nil.
    81                     phantom disposed
    90                     phantom disposed
    82                 ]
    91                 ]
    83             ]
    92             ]
    84         ]
    93         ]
    85     ]
    94     ]
    89 
    98 
    90 contentsDo:aBlock
    99 contentsDo:aBlock
    91     "evaluate aBlock for each registered object"
   100     "evaluate aBlock for each registered object"
    92 
   101 
    93     registeredObjects notNil ifTrue:[
   102     registeredObjects notNil ifTrue:[
    94         registeredObjects do:[:o |
   103         registeredObjects nonNilElementsDo:[:o |
    95             o notNil ifTrue:[
   104             aBlock value:o
    96                 aBlock value:o
       
    97             ]
       
    98         ]
   105         ]
    99     ]
   106     ]
   100 ! !
   107 ! !
   101 
   108 
   102 !Registry methodsFor:'accessing'!
   109 !Registry methodsFor:'accessing'!
   112 
   119 
   113     |index|
   120     |index|
   114 
   121 
   115     index := registeredObjects identityIndexOf:anObject ifAbsent:[0].
   122     index := registeredObjects identityIndexOf:anObject ifAbsent:[0].
   116     index ~~ 0 ifTrue:[
   123     index ~~ 0 ifTrue:[
   117         phantoms at:index put:anObject shallowCopy.
   124         phantomArray at:index put:anObject shallowCopyForFinalization.
   118     ]
   125     ]
   119 !
   126 !
   120 
   127 
   121 register:anObject
   128 register:anObject
   122     "register anObject, so that a copy of it gets the disposed message
   129     "register anObject, so that a copy of it gets the disposed message
   123      when anObject dies (some time in the future)"
   130      when anObject dies (some time in the future)"
   124 
   131 
   125     |phantom newColl newPhantoms
   132     |phantom newColl newPhantoms
   126      count "{ Class: SmallInteger }"
   133      size  "{ Class: SmallInteger }"
   127      p index|
   134      index "{ Class: SmallInteger }"
   128 
   135      p|
   129     phantom := anObject shallowCopy.
   136 
       
   137     phantom := anObject shallowCopyForFinalization.
   130 
   138 
   131     registeredObjects isNil ifTrue:[
   139     registeredObjects isNil ifTrue:[
   132         registeredObjects := WeakArray new:10.
   140         registeredObjects := WeakArray new:10.
   133         registeredObjects watcher:self.
   141         registeredObjects watcher:self.
   134         registeredObjects at:1 put:anObject.
   142         registeredObjects at:1 put:anObject.
   135         phantoms := Array new:10.
   143         phantomArray := Array new:10.
   136         phantoms at:1 put:phantom.
   144         phantomArray at:1 put:phantom.
   137         cleanState := true.
   145         cleanState := true.
   138         ObjectMemory addDependent:self.
   146         ObjectMemory addDependent:self.
   139         ^ self
   147         ^ self
   140     ].
   148     ].
   141 
   149 
   142     index := registeredObjects identityIndexOf:anObject ifAbsent:[0].
   150     index := registeredObjects identityIndexOf:anObject ifAbsent:[0].
   143     index ~~ 0 ifTrue:[
   151     index ~~ 0 ifTrue:[
   144         "already registered"
   152         "already registered"
   145         phantoms at:index put:phantom.
   153         phantomArray at:index put:phantom.
   146         self error:'object is already registered'.
   154         self error:'object is already registered'.
   147         ^ self
   155         ^ self
   148     ].
   156     ].
   149 
   157 
   150     "search for a free slot, on the fly look for leftovers"
   158     "search for a free slot, on the fly look for leftovers"
   151     count := phantoms size.
   159     index := registeredObjects identityIndexOf:nil startingAt:1.
   152     1 to:count do:[:i |
   160     index ~~ 0 ifTrue:[
   153         (registeredObjects at:i) isNil ifTrue:[
   161 	"is there a leftover ?"
   154             "is there a leftover ?"
   162 	p := phantomArray at:index.
   155             p := phantoms at:i.
   163         p notNil ifTrue:[
   156             p notNil ifTrue:[
   164 	    "tell the phantom"
   157 		"tell the phantom"
   165             phantomArray at:index put:nil.
   158                 phantoms at:i put:nil.
   166             p disposed.
   159                 p disposed.
   167             p := nil.
   160                 p := nil.
   168         ].
   161             ].
   169         registeredObjects at:index put:anObject.
   162             registeredObjects at:i put:anObject.
   170         phantomArray at:index put:phantom.
   163             phantoms at:i put:phantom.
   171         ^ self
   164             ^ self
       
   165         ]
       
   166     ].
   172     ].
   167 
   173 
   168     "no free slot, add at the end"
   174     "no free slot, add at the end"
   169 
   175 
   170     newColl := WeakArray new:(count * 2).
   176     size := registeredObjects size.
   171     newColl replaceFrom:1 to:count with:registeredObjects.
   177     index := size + 1.
       
   178     newColl := WeakArray new:(size * 2).
       
   179     newColl replaceFrom:1 to:size with:registeredObjects.
   172     registeredObjects := newColl.
   180     registeredObjects := newColl.
   173     registeredObjects watcher:self.
   181     registeredObjects watcher:self.
   174     registeredObjects at:(count + 1) put:anObject.
   182     registeredObjects at:index put:anObject.
   175 
   183 
   176     newPhantoms := Array new:(count * 2).
   184     newPhantoms := Array new:(size * 2).
   177     newPhantoms replaceFrom:1 to:count with:phantoms.
   185     newPhantoms replaceFrom:1 to:size with:phantomArray.
   178     phantoms := newPhantoms.
   186     phantomArray := newPhantoms.
   179     phantoms at:(count + 1) put:phantom.
   187     phantomArray at:index put:phantom.
   180 !
   188 !
   181 
   189 
   182 unregister:anObject
   190 unregister:anObject
   183     "remove registration of anObject, without telling the phantom;
   191     "remove registration of anObject, without telling the phantom;
   184      should be sent, if we are no more interrested in destruction of
   192      should be sent, if we are no more interrested in destruction of
   186 
   194 
   187     |index|
   195     |index|
   188 
   196 
   189     index := registeredObjects identityIndexOf:anObject ifAbsent:[0].
   197     index := registeredObjects identityIndexOf:anObject ifAbsent:[0].
   190     index ~~ 0 ifTrue:[
   198     index ~~ 0 ifTrue:[
   191         phantoms at:index put:nil.
   199         phantomArray at:index put:nil.
   192         registeredObjects at:index put:nil
   200         registeredObjects at:index put:nil
   193     ]
   201     ]
   194 ! !
   202 ! !
   195 
   203 
   196 !Registry methodsFor:'restart handling'!
   204 !Registry methodsFor:'restart handling'!
   197 
   205 
   198 update:aParameter
   206 update:aParameter
   199     aParameter == #earlyRestart ifTrue:[
   207     aParameter == #earlyRestart ifTrue:[
   200         phantoms notNil ifTrue:[
   208         phantomArray notNil ifTrue:[
   201             phantoms atAllPut:nil
   209             phantomArray atAllPut:nil
   202         ]
   210         ]
   203     ].
   211     ].
   204     aParameter == #returnFromSnapshot ifTrue:[
   212     aParameter == #returnFromSnapshot ifTrue:[
   205         cleanState := true
   213         cleanState := true
   206     ]
   214     ]