Handling object references when implementing buffering similarly to Dialog, but for Shells

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

Handling object references when implementing buffering similarly to Dialog, but for Shells

Yar Hwee Boon-3
Hi all,

I have implemented buffering similar to that in Dialog, but as a Shell  
subclass (PageShell). I suppose what I'm facing should be similar if one  
used a Dialog instead. Basically, I have a Page that can use one and only  
one Template and each template stores the list of pages using it. So I have

Page>>template: aTemplate
     template removePage: self.
     template := aTemplate.
     template addPage: self

Within PageShell there is a ListPresenter that allows the user to  
select/change the template used from among a list. But upon changing the  
selection and calling #template: on the buffer rather than the actual  
subject will of course lead to an attempt to remove the wrong page from  
the old template and add the wrong page to the new template. In fact, as I  
am writing this, it also occurred to that I am already writing changes to  
the old/new templates without buffering which is clearly wrong. How does  
one usually go about doing this? Or, is storing a copy of the Page's state  
and undoing any change when necessary preferred to buffering? Thanks.

--
Regards
Hwee Boon
MotionObj


Reply | Threaded
Open this post in threaded view
|

Re: Handling object references when implementing buffering similarly to Dialog, but for Shells

Chris Uppal-3
Yar Hwee Boon wrote:

> How does
> one usually go about doing this? Or, is storing a copy of the Page's state
> and undoing any change when necessary preferred to buffering? Thanks.

I think I'd normally prefer an interface where the action I (the user) asked
for was implemented directly; i.e. without the buffering.

Still, if for whatever reason, I did design a UI where the displayed state and
the actual state were different, then I think I'd want to implement it the same
way.  That is, I'd make that part of the UI operate on a copy of the real data,
and then either discard the copy, or replace the original with the modified
copy if the user pressed OK (or whatever).

That would have the advantage that the UI code would (mostly) not need to know
that it wasn't manipulating the "real" data.

HTH; it's a bit vague, I know.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Handling object references when implementing buffering similarly to Dialog, but for Shells

Yar Hwee Boon-3
On Tue, 27 Jul 2004 10:39:32 +0100, Chris Uppal  
<[hidden email]> wrote:

> I think I'd normally prefer an interface where the action I (the user)  
> asked
> for was implemented directly; i.e. without the buffering.

Do you mean committing immediately without requiring an OK button or a  
save? In this case, the user is doing something similar to editing a  
document, so I had assumed that user expecting a save/buffer is fairly  
inevitable.

> Still, if for whatever reason, I did design a UI where the displayed  
> state and
> the actual state were different, then I think I'd want to implement it  
> the same
> way.  That is, I'd make that part of the UI operate on a copy of the  
> real data,
> and then either discard the copy, or replace the original with the  
> modified
> copy if the user pressed OK (or whatever).
>
> That would have the advantage that the UI code would (mostly) not need  
> to know
> that it wasn't manipulating the "real" data.

That's what I did, but unfortunately even such a simple "bi-association"  
relationship seems to be causing complications when implementing buffering.

> HTH; it's a bit vague, I know.

Thanks. That's ok, my question was vague anyway, but I think I understood  
your point. Anyway, I didn't solve the problem, I merely avoided it by  
removing the references that Template is tracking, and did a runtime  
search when necessary :)

--
Regards
Hwee Boon
MotionObj


Reply | Threaded
Open this post in threaded view
|

Re: Handling object references when implementing buffering similarly to Dialog, but for Shells

Chris Uppal-3
Yar Hwee Boon wrote:

> > I think I'd normally prefer an interface where the action I (the user)
> > asked
> > for was implemented directly; i.e. without the buffering.
>
> Do you mean committing immediately without requiring an OK button or a
> save? In this case, the user is doing something similar to editing a
> document, so I had assumed that user expecting a save/buffer is fairly
> inevitable.

We're probably talking at cross purposes here...

Anyway, the model I had in mind is where the program has a bunch of objects in
some state, and that state can be "actioned" (e.g. sent to a server,
written-out to disk, whatever).  The UI allows the user to manipulate the state
to get it how s/he likes it before "actioning".  For instance moving objects
around in a diagram before printing it, moving words around a document before
saving it, setting price/quantities in a bid before sending it off to a broker.
In such cases I'd (automatically) build the UI so that the objects appearing in
the UI always reflected the current state of the objects (with maybe a small
caveat about field validation), so there wouldn't be a "commit" operation as
such (distinct from the "action" operation).

I'm not a fan of interfaces where you have nested operations, each of which
have to be saved explicitly into its parent context.  E.g. a (hypothetical)
diagram editior where:

    you have to press OK to accept the edit you are making to
    one element's label in the diagram.

    then you have to press OK (or Save) to save the modified diagram
    back to the document it's part of.

    then you have to press OK (or Save) to write the whole document
    out to disk.

It's not as clear-cut a distinction as I'm making it sound here.  For instance
some classes of users will have difficulty with the distinction between the
state they see on the screen (objects in the program) vs. the state of the
objects stored in a file -- and that distinction /is/ artificial, so maybe they
are right.

So, to me, a more natural UI would have no "commit" (except save-to-disk), but
would be able to revert the state of the program objects.  Reverting to the
last-saved state is easy, just discard the current state and reload the data
from disk.  Reverting to the state before the last chage (or further back) is
also easy /if/ you don't try to optimise it.  Just make a copy of the /entire/
state of the objects manipulated by the UI before each change and add them to a
list somewhere.  So, in simple cases anyway, your "undo" list is just an
OrderedCollection of deep copies of the Model.


> > Still, if for whatever reason, I did design a UI where the displayed
> > state and
> > the actual state were different, then I think I'd want to implement it
> > the same
> > way.  That is, I'd make that part of the UI operate on a copy of the
> > real data,
> > and then either discard the copy, or replace the original with the
> > modified
> > copy if the user pressed OK (or whatever).
> >
> > That would have the advantage that the UI code would (mostly) not need
> > to know
> > that it wasn't manipulating the "real" data.
>
> That's what I did, but unfortunately even such a simple "bi-association"
> relationship seems to be causing complications when implementing
> buffering.

Copying such relationships is difficult; it's hard to get the logic right
(knowing what logically /must/ be copied, and what logically /must not/ be
copied), and it's not necessarily easy to get the code right either.   As I
said above, it can be a lot easier if you don't try to limit the scope of the
copy operation to just the things that are changing, but instead make a
sweeping clone of the entire state of the manipulable objects.


> Anyway, I didn't solve the problem, I merely avoided it by
> removing the references that Template is tracking, and did a runtime
> search when necessary :)

Sounds like a sensible simplification to me.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Handling object references when implementing buffering similarly to Dialog, but for Shells

Yar Hwee Boon-3
On Wed, 28 Jul 2004 09:47:33 +0100, Chris Uppal  
<[hidden email]> wrote:

> Yar Hwee Boon wrote:
>
>> > I think I'd normally prefer an interface where the action I (the user)
>> > asked
>> > for was implemented directly; i.e. without the buffering.
>>
>> Do you mean committing immediately without requiring an OK button or a
>> save? In this case, the user is doing something similar to editing a
>> document, so I had assumed that user expecting a save/buffer is fairly
>> inevitable.
>
> We're probably talking at cross purposes here...

Yup, what I'm doing is more like Microsoft word allowing the user to  
change the style (Template) used in a document (Page) and only committing  
upon save.

> So, to me, a more natural UI would have no "commit" (except  
> save-to-disk), but
> would be able to revert the state of the program objects.  Reverting to  
> the
> last-saved state is easy, just discard the current state and reload the  
> data
> from disk.

This certainly sounds simple and effective. Thanks.

--
Regards
Hwee Boon
MotionObj