Hello all.
I have next model of objects Every object of class A own collection of objects of class B. Every object of class B own collection ob objects of class C. When object class A append object of class B to collection (objects of class B), that objectB get next event objectB when:#change send: #changeObjectsB to: self where self is object of class A. Class B do same event for object of class C (when object B append to collection object of class C) I want save my model to file and later restore it. But, if use standart STBINFiler STBOutFiler, that events for objects not save/restore. I proposes, that heed use STBProxy, but not understand work with it. May anybody tell me with this? |
Musulainen,
> I want save my model to file and later restore it. > But, if use standart STBINFiler STBOutFiler, that events for objects > not save/restore. > > I proposes, that heed use STBProxy, but not understand work with it. Wouldn't it be easier to just keep it as simple as possible and restore the events yourself? ClassA>>restoreFrom: aStream collectionA := Object binaryReadFrom: aStream. "or whatever" collectionA do: [:eachB | eachB restoreEvents. eachB when: #change send: #changeObjectsB to: self] ClassB>>restoreEvents collectionB do: [:eachC | eachC when: #change send: #changeObjectsC to: self] -- Ian Use the Reply-To address to contact me. Mail sent to the From address is ignored. |
> Wouldn't it be easier to just keep it as simple as possible and restore the
> events yourself? > > ClassA>>restoreFrom: aStream > collectionA := Object binaryReadFrom: aStream. "or whatever" > collectionA do: [:eachB | > eachB restoreEvents. > eachB when: #change send: #changeObjectsB to: self] > > ClassB>>restoreEvents > collectionB do: [:eachC | > eachC when: #change send: #changeObjectsC to: self] Am I right understand, that I must save collectionB and CollectionC to other file(s) (for example). I restore object of class A (entry point to my model) standart STBOutFiler, after that, I restore myself objects from collectionB and collectionC. It's correct? |
Musulainen Vladimir wrote:
> I restore object of class A (entry point to my model) standart > STBOutFiler, after that, I restore myself objects from collectionB > and collectionC. > > It's correct? No. When you store your class A instance then anything referenced by it's instance variables (and, recursively, anything referenced by their instance variables) are also stored in the binary stream. When you restore the saved bytes then _all_ the objects are restored. A demonstration. Copy the code below into a workspace, select it all and then "File It In" from the Workspace menu. You will have 3 new classes in the image, ClassA, ClassB and ClassC. Save the image. Evaluate the following in an workspace. a := ClassA new. 10 timesRepeat: [ b := ClassB new. 11 timesRepeat: [ c := ClassC new. 12 timesRepeat: [ c add: Time microsecondClockValue -> Time now]. b add: c]. a add: b]. fs := FileStream write: 'test.bin' text: false. [a binaryStoreOn: fs] ensure: [fs close]. That will create a nested collection of instances of the new classes and save them into a file. Shut down and restart Dolphin. The 3 classes added above will still be in the image so you can open up a new workspace and evaluate. fs := FileStream read: 'test.bin' text: false. [a1 := Object binaryReadFrom: fs] ensure: [fs close]. a1 inspect You should see that the entire structure that you created in the first workspace has been reconstructed. Note that although the objects are recreated their original values are restored - the Times stored in the ClassC instances are the ones from when the instance was first created. Note that the classes for the objects stored in the file must be present in the image. If you had started again with a clean image in which ClassA, ClassB and ClassC did not exist, then restoring the file will fail. =~=~=~=~=~= Object subclass: #ClassA instanceVariableNames: 'collectionA' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! ClassA guid: (GUID fromString: '{8358D41E-838B-4835-8B57-13338C55DC42}')! ClassA comment: ''! !ClassA categoriesForClass!Kernel-Objects! ! !ClassA methodsFor! add: anObject collectionA ifNil: [collectionA := OrderedCollection new]. collectionA add: anObject! ! !ClassA categoriesFor: #add:!public! ! Object subclass: #ClassB instanceVariableNames: 'collectionB' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! ClassB guid: (GUID fromString: '{9861C63B-DD02-4870-B94E-D0E5477421E7}')! ClassB comment: ''! !ClassB categoriesForClass!Kernel-Objects! ! !ClassB methodsFor! add: anObject collectionB ifNil: [collectionB := Set new]. collectionB add: anObject! ! !ClassB categoriesFor: #add:!public! ! Object subclass: #ClassC instanceVariableNames: 'collectionC' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! ClassC guid: (GUID fromString: '{5871B861-2105-4949-A2A6-9A720C8C87ED}')! ClassC comment: ''! !ClassC categoriesForClass!Kernel-Objects! ! !ClassC methodsFor! add: anObject collectionC ifNil: [collectionC := Bag new]. collectionC add: anObject! ! !ClassC categoriesFor: #add:!public! ! =~=~=~=~=~= I hope that helps. If not please ask again. -- Ian Use the Reply-To address to contact me. Mail sent to the From address is ignored. |
In reply to this post by Vladimir Musulainen
Musulainen Vladimir wrote:
> I want save my model to file and later restore it. > But, if use standart STBINFiler STBOutFiler, that events for objects > not save/restore. The problem is that the events attached to an object are logically part of the Observer, not of the Observee. Hence (quite correctly) the default Dolphin STB mechanism does not save them as part of the object's saved state*. In fact, by default, the event set *isn't* part of the Observee's state even at the implementation level. Some classes (notably Model) that "expect" to make heavy use of events have an optimisation where the event set is implemented by keeping it in one the object's instance variables, but in those cases the class has a special version of #stbSaveOn: that explicitly prevents the event set being saved with the rest of the object. But you have a case where the events are part of a (compound) object's internal state. So what you have to do is re-establish the connections when the object is de-STBed. I use code like ======================== stbFixup: anSTBInFiler at: newObjectIndex "overriden to rebuild the internal dependencies" self rebuildDependencies. ^ super stbFixup: anSTBInFiler at: newObjectIndex. ======================== Where #rebuildDependencies is the method that actually re-establishes the Observer/Observee relationships (as in Ian's post). BTW, if your (compound) objects can also be #copy-ed then you probably want to do something similar in your #postCopy method too. One warning: the above method won't work for Views -- that's because Views are saved via an STBViewProxy. When I needed to do this with a View (only once so far), I just put the reconnection code into an override of #onCreated:. There may be better ways to do it. -- chris [*] Arguably if both the Observer and Observee are part of the same STB file, then the events linking them should be saved too. I suspect that would be a great deal of work to implement, and probably not really worth the effort. |
Free forum by Nabble | Edit this page |