How did I mess up my view?

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

How did I mess up my view?

Peter Kenny-2
I have managed to dig myself out of the hole I fell into today, but I would
be grateful if anyone could explain what I did wrong, and how I can avoid it
in future.

Following the saga reported in another thread, I have developed an MVP triad
for drawing graphs, which works in a limited way. In trying to simplify and
generalise it, I tried to add another instance variable to my model class.
The effect was that, when I next tried to load my main shell, the system
generated a walkback with 'end of stream'; it looked as though the loader
was going wrong in loading the view resource for my graph MVP triad. I
eventually solved this by renaming an existing instance variable and giving
its old function to a method local - essentially it was no longer necessary
to preserve what was now just an intermediate result. Is there some danger
in adding instance variables? - I know I have done it before without
problems. The effect is puzzling, because there seems so little connection
between the model and the view - is there something in the view resource
which depends on the number of instance variables in the model class?

I have saved enough intermediate images to be able to reproduce this if
necessary, but I don't want to clutter this newsgroup with too much detail.

Grateful for any help.

Peter Kenny


Reply | Threaded
Open this post in threaded view
|

Re: How did I mess up my view?

Andy Bower-3
Peter,

> I have managed to dig myself out of the hole I fell into today, but I
> would be grateful if anyone could explain what I did wrong, and how I
> can avoid it in future.
>
> Following the saga reported in another thread, I have developed an
> MVP triad for drawing graphs, which works in a limited way. In trying
> to simplify and generalise it, I tried to add another instance
> variable to my model class.  The effect was that, when I next tried
> to load my main shell, the system generated a walkback with 'end of
> stream'; it looked as though the loader was going wrong in loading
> the view resource for my graph MVP triad. I eventually solved this by
> renaming an existing instance variable and giving its old function to
> a method local - essentially it was no longer necessary to preserve
> what was now just an intermediate result. Is there some danger in
> adding instance variables? - I know I have done it before without
> problems. The effect is puzzling, because there seems so little
> connection between the model and the view - is there something in the
> view resource which depends on the number of instance variables in
> the model class?
>
> I have saved enough intermediate images to be able to reproduce this
> if necessary, but I don't want to clutter this newsgroup with too
> much detail.

Most likely you have a #defaultModel class method for your graph view
that installs an instance of your model into any instance of the graph
view that is created (e.g. the one created by the view composer). When
you save your view as a resource this default model is saved out too
(in STB format). This is the case even though, when the view is
reloaded from the resource to be attached to its eventual presenter,
another model object (presumably of the same class) will be installed.

To get around this, you have two options:

1) Whenever you change the instance variable layout of your model
class, you should write an STB upgrade procedure for old instance of
the class so they can be loaded in the new format. This involves
writing two class side methods, #stbVersion and #stbConvertFrom:. Take
a look at the help:

http://www.object-arts.com/Lib/EducationCentre4/htm/convertingstbdataaft
erinstancelayoutchanges.htm

and dsearch for these in the image to see how they are used (try
looking at Package).

2) Alternatively you could make your view accept a nil model and make
#defaultModel for the view answer nil too. This would mean that the
only instance of your model that would get created woould be the one by
the presenter.

Hope this helps.

Andy Bower
Dolphin Support
www.object-arts.com


Reply | Threaded
Open this post in threaded view
|

Re: How did I mess up my view?

Peter Kenny-2
"Andy Bower" <[hidden email]> wrote in message
news:[hidden email]...
> Peter,


>
> Most likely you have a #defaultModel class method for your graph view
> that installs an instance of your model into any instance of the graph
> view that is created (e.g. the one created by the view composer). When
> you save your view as a resource this default model is saved out too
> (in STB format). This is the case even though, when the view is
> reloaded from the resource to be attached to its eventual presenter,
> another model object (presumably of the same class) will be installed.
>
> To get around this, you have two options:
>
> 1) Whenever you change the instance variable layout of your model
> class, you should write an STB upgrade procedure for old instance of
> the class so they can be loaded in the new format. This involves
> writing two class side methods, #stbVersion and #stbConvertFrom:. Take
> a look at the help:
>
> http://www.object-arts.com/Lib/EducationCentre4/htm/convertingstbdataaft
> erinstancelayoutchanges.htm
>
> and dsearch for these in the image to see how they are used (try
> looking at Package).
>
> 2) Alternatively you could make your view accept a nil model and make
> #defaultModel for the view answer nil too. This would mean that the
> only instance of your model that would get created woould be the one by
> the presenter.
>
> Hope this helps.
>
> Andy Bower
> Dolphin Support
> www.object-arts.com

Andy

You are right about the default model. I shall try to get round it by the
second route if I can - I can't now remember why it's there.

Many thanks

Peter


Reply | Threaded
Open this post in threaded view
|

Re: How did I mess up my view?

Pieter Emmelot-2
In reply to this post by Andy Bower-3
> To get around this, you have two options:
>
> 1) Whenever you change the instance variable layout of your model
> class, you should write an STB upgrade procedure for old instance of
> the class so they can be loaded in the new format. This involves
> writing two class side methods, #stbVersion and #stbConvertFrom:. Take
> a look at the help:
>
> http://www.object-arts.com/Lib/EducationCentre4/htm/convertingstbdataaft
> erinstancelayoutchanges.htm
>
> and dsearch for these in the image to see how they are used (try
> looking at Package).
>
> 2) Alternatively you could make your view accept a nil model and make
> #defaultModel for the view answer nil too. This would mean that the
> only instance of your model that would get created woould be the one by
> the presenter.
>
> Hope this helps.
>
> Andy Bower
> Dolphin Support
> www.object-arts.com

Third option:
Have a ViewComposer open on the view in question while making changes in
the model. Save the view when you're done.

Pieter


Reply | Threaded
Open this post in threaded view
|

Re: How did I mess up my view?

Peter Kenny-2
"Pieter Emmelot" <[hidden email]> wrote in message
news:[hidden email]...
> > To get around this, you have two options:
>
> Third option:
> Have a ViewComposer open on the view in question while making changes in
> the model. Save the view when you're done.
>
> Pieter

Pieter - Thanks, this looks brilliantly simple. I tried it, even though I no
longer need the extra instance variable. The one odd thing was that, as I
pressed 'Accept' for the revised class definition, the system showed a
warning: 'Raised signal - end of stream'. However, I saved the new view and
loaded my shell with no problems, and an inspector showed that the model has
the extra instance variable. So it works!

Thanks

Peter.


Reply | Threaded
Open this post in threaded view
|

Re: How did I mess up my view?

Blair McGlashan-3
In reply to this post by Pieter Emmelot-2
"Pieter Emmelot" <[hidden email]> wrote in message
news:[hidden email]...

>> To get around this, you have two options:
>>
>> 1) Whenever you change the instance variable layout of your model
>> class, you should write an STB upgrade procedure for old instance of
>> the class so they can be loaded in the new format. This involves
>> writing two class side methods, #stbVersion and #stbConvertFrom:. Take
>> a look at the help:
>>
>> http://www.object-arts.com/Lib/EducationCentre4/htm/convertingstbdataaft
>> erinstancelayoutchanges.htm
>>
>> and dsearch for these in the image to see how they are used (try
>> looking at Package).
>>
>> 2) Alternatively you could make your view accept a nil model and make
>> #defaultModel for the view answer nil too. This would mean that the
>> only instance of your model that would get created woould be the one by
>> the presenter.
>>
>> Hope this helps.
>>
>> Andy Bower
>> Dolphin Support
>> www.object-arts.com
>
> Third option:
> Have a ViewComposer open on the view in question while making changes in
> the model. Save the view when you're done.
>

Yes, this is indeed the best approach during development before one has
"published" a view resource. It is certainly the method I use.

If anyone is wondering why it works, well it is just taking advantage of the
normal class schema migration capabilities that are used whenever you modify
any other class that has existing instances. This is done by the
ClassBuilder, and the effect is that any same named instance variables in
the "new" class are preserved (i.e. you can reorder them), and values in
deleted instance variables are discarded, and any new instance variables are
initialized to nil. This last may mean that you need to partially initialize
any existing instances after adding a new instance variable, but this is
easily achieved by either a simple #allInstances enumeration, or by using a
lazy accessor for the variable.

A couple of other useful STB tips are:
1) Never re-order instance variables - add them on the end. If you do this,
and you use lazy accessors, you won't need to write an STB conversion method
for leaf classes, just increment the stbVersion number.
2) Never delete instance variables - just reserve them for future use.
3) When adding instance variables, reserve a few extra spares.


Regards

Blair