'From etoys3.0 of 18 March 2008 [latest update: #1985] on 14 June 2008 at 5:08:28 pm'! "Change Set: ImageSeg-fix-tk Date: 13 June 2008 Author: Ted Kaehler Symptom: Reading in a project gets an error: key not found in SystemDictionary. If you happen to have a Browser open on a Player or a DBJr background uniclass, the ImageSegment will put the uniclass's metaclass organization in its outPointers. The ClassOrganization has a field 'subject' that holds onto the metaclass directly. A DiskProxy is made for this metaclass reference. When the project is read in, the DiskProxy cannot resolve a class, since the main part of the imageSegment containing the uniclass has not been unpacked yet. The solution is to put the classOrganization into the roots of the imageSegment. I made a method that scans the objects that will be in the imageSegment. For each uniclass, it makes sure it's metaclass's organization is in the roots."! !ImageSegment methodsFor: 'read/write segment' stamp: 'tk 6/13/2008 15:59'! classOrganizersBeRoots: dummy "The ClassOrganizers of some UniClasses may slip into OutPointers. They point directly at the class of the UniClass (in subject). They need to be in arrayOfRoots. Find them and insert them into dummy's references." dummy references fasterKeys do: [:anObject | anObject isBehavior & (anObject isKindOf: ClassDescription) ifTrue: [ anObject theNonMetaClass isSystemDefined ifFalse: ["uniClass will be in image seg" (dummy references includesKey: anObject organization) ifFalse: [ dummy references at: anObject organization put: 47]]]]. "will get into roots"! ! !ImageSegment methodsFor: 'read/write segment' stamp: 'tk 6/13/2008 14:57'! smartFillRoots: dummy | refs known ours ww blockers | "Put all traced objects into my arrayOfRoots. Remove some that want to be in outPointers. Return blockers, an IdentityDictionary of objects to replace in outPointers." blockers _ dummy blockers. known _ (refs _ dummy references) size. refs fasterKeys do: [:obj | "copy keys to be OK with removing items" (obj isSymbol) ifTrue: [refs removeKey: obj. known _ known-1]. (obj class == PasteUpMorph) ifTrue: [ obj isWorldMorph & (obj owner == nil) ifTrue: [ (dummy project ~~ nil and: [obj == dummy project world]) ifFalse: [ refs removeKey: obj. known _ known-1. blockers at: obj put: (StringMorph contents: 'The worldMorph of a different world')]]]. "Make a ProjectViewMorph here" "obj class == Project ifTrue: [Transcript show: obj; cr]." (blockers includesKey: obj) ifTrue: [ refs removeKey: obj ifAbsent: [known _ known+1]. known _ known-1]. ]. ours _ dummy project ifNotNil: [dummy project world] ifNil: [ActiveWorld]. refs keysDo: [:obj | obj isMorph ifTrue: [ ww _ obj world. (ww == ours) | (ww == nil) ifFalse: [ refs removeKey: obj. known _ known-1. blockers at: obj put: (StringMorph contents: obj printString, ' from another world')]]]. "keep original roots on the front of the list" (dummy rootObject) do: [:rr | refs removeKey: rr ifAbsent: []]. self classOrganizersBeRoots: dummy. ^ dummy rootObject, refs fasterKeys asArray.! !