Looks like I need multiple inheritance...

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Looks like I need multiple inheritance...

Fernando Rodríguez
Hi,

I have a Dialog that lets the user modify an OrderedCollection (inside
a ListModel).

It doesn't work as expected, since Dialog uses an AspectBuffer which
in turn does a #copy of it's subject. So, any changes made to the list
with the dialog are visible on the model, even if the user clicks on
the Cancel button.

I decided to create a subclass of Dialog called DeepCopyDialog that
uses a subclass of AspectBuffer, called DeepCopyAspectBuffer.

Everything OK, so far. However, all the dialogs in this project (the
Formula One thing from The Dolphin Smalltalk Companion) descend from a
F1Dialog that has some common methods.

If I make F1Dialog a subclass of DeepCopyDialog, all of my dialogs
will become DeepCopy ones, and I don't wat that. Only one should be a
DeepCopyDialog and a F1Dialog. All others should be only F1Dialogs.

What's the best way to solve this sort situation without resorting to
multiple inheritance?

Thanks


Reply | Threaded
Open this post in threaded view
|

Re: Looks like I need multiple inheritance...

Martin Rubi
> What's the best way to solve this sort situation without resorting to
> multiple inheritance?

I don't know if I understood your problem correctly, but I think you wont
need multiple inheritance, or even to create the class DeepCopyDialog at
all.
I think all it takes is to redefine the method #bufferedModelFor: in the
dialog which manipulates the collection to use a different wrapper on your
model (in your case, one that makes a deep copy of it, and sets its contents
properly when applied). The comment for #bufferedModelFor: says that:

"[...] May be overriden by subclasses that wish to use a different buffering
scheme."

Regards
Martin


Reply | Threaded
Open this post in threaded view
|

Re: Looks like I need multiple inheritance...

Fernando Rodríguez
On Mon, 28 Mar 2005 11:26:35 -0300, "Martin" <[hidden email]>
wrote:


>I think all it takes is to redefine the method #bufferedModelFor: in the
>dialog which manipulates the collection to use a different wrapper on your
>model (in your case, one that makes a deep copy of it, and sets its contents
>properly when applied). The comment for #bufferedModelFor: says that:
>
>"[...] May be overriden by subclasses that wish to use a different buffering
>scheme."

Thanks, you are right.  However, it still doesn't work. :-(

Let's recapitulate:

I created a subclass of AspectBuffer called DeepCopyAspectBuffer and
it overrides one method: #subject

subject: aSubjectModel
        "Does a deepCopy instead"
        subject := aSubjectModel.
        subjectCopy := aSubjectModel deepCopy. "the only difference"
        aspects := IdentityDictionary new.

I also have a model subclass called Season that has a ListModel aspect
that is shared with the presenter (called SeasonPresenter). This
ListModel is accessed via the #scoreDefinition method.

I'm setting the model of the ListPresenter in SeasonPresenter like
this:

SeasonPresenter>>model:  aSeason
        super model: aSeason.
        "The shared ListModel:"
        scoreListPresenter model: (self model scoreDefinition).
       
I also override the #bufferedModelFor: method as you suggested:

bufferedModelFor: aSubjectModel
        "Private - Answers a deepCopied buffer, since self presents a
            list (shallow copy isn't enough)"
        ^DeepCopyAspectBuffer subject: aSubjectModel.

If I show a Season on a DialogSeason and add a few entries to the list
and then click on the OK button, the list in Season remains unchanged.
=:-O

The culprit seems to be AspectBuffer>>apply which does nothing in this
particular case.

I think I should override it in DeepCopyAspectBuffer, but I'm not sure
what I should do in that method. Or perhaps the problem is my
SeasonPresenter>>model:

Besides, I'm not sure if I really understand what's going on...

Any suggestions? O:-)  Is the whole idea of creating
DeepCopyAspectBuffer a good idea?

Thanks


Reply | Threaded
Open this post in threaded view
|

Re: Looks like I need multiple inheritance...

hboon@motionobj.com
Fernando wrote:
> The culprit seems to be AspectBuffer>>apply which does nothing in
this
> particular case.
>
> I think I should override it in DeepCopyAspectBuffer, but I'm not
sure
> what I should do in that method. Or perhaps the problem is my
> SeasonPresenter>>model:
>
> Besides, I'm not sure if I really understand what's going on...
>
> Any suggestions? O:-)  Is the whole idea of creating
> DeepCopyAspectBuffer a good idea?

You are probably missing a #aspectValue: send for your list. A simpler
way to do this without subclassing is to override #copy to make a copy
of your list. eg.

copy
    | answer |
    answer := super copy.
    answer someList: someList copy. "And I think you don't want a deep
copy here."
    ^answer

model: aModel
    super model: aModel.
    ...
    self model aspectValue: #someList.
    ...


This doesn't always work of course, depending on your own usage pattern
of #copy and how you want the list to be synchronised etc.


Reply | Threaded
Open this post in threaded view
|

Re: Looks like I need multiple inheritance...

Fernando Rodríguez
On 28 Mar 2005 19:56:45 -0800, "[hidden email]"
<[hidden email]> wrote:


>
>You are probably missing a #aspectValue: send for your list. A simpler

You mean it's necessary to create an AspectValue even when sharing a
ListModel between the Model and the Presenter?


Reply | Threaded
Open this post in threaded view
|

Re: Looks like I need multiple inheritance...

hboon@motionobj.com
Browse the AspectBuffer class which is the buffer being used by Dialog.
If you look in #apply, you will notice that the buffer copies the
aspects/properties specified in the ivar aspects. Sending #aspectValue:
for the list is just a way (I know some other people does it this way
too. I'm not sure if this is the right way since it is just using the
side-effect but it works :)) for us to update the aspects ivar to
include the list.