How to add instance variables to View

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

How to add instance variables to View

Udo Schneider
I'm just playing around with alpha blending and color keying. I wanted to
add additional
instance variables to view but this seems to be harder than I thought.

Just execute the following an you'll see what I mean:

--------------------------------
Object subclass: #View
instanceVariableNames: 'handle creationParent creationStyle presenter model
backcolor preferredExtent flags contextMenu font events hasAlphaBlend
alphaBlend hasColorKey colorKey'
classVariableNames: 'CreateCenteredMask DragSourceMask DropTargetMask
LayoutValidMask ManagedMask MessageMap MinimizedMask NextId
PersistentFlagsMask StateRestoringMask UIValidMask UsePreferredExtentMask
ViewClosedError WmUserLast'
poolDictionaries: 'Win32Constants Win32Errors'
classInstanceVariableNames: ''.
View destroyAll.

--------------------------------

This class definition adds four instance variables (hasAlphaBlend alphaBlend
hasColorKey colorKey).



Any ideas or hints how to fix this?



Udo


Reply | Threaded
Open this post in threaded view
|

Re: How to add instance variables to View

Ian Bartholomew-7
Udo,

> I'm just playing around with alpha blending and color keying. I wanted to
> add additional
> instance variables to view but this seems to be harder than I thought.
[]
> Any ideas or hints how to fix this?

Adding extra instance variables to most View subclasses isn't too difficult.
Adding instance variables to View itself is a different matter and, although
it is probably possible?, won't be very easy.

NB: What follows should be considered an idiots guide, with me as the idiot
<g>. It's how I think of the way that Dolphin works and is lacking in most
of the detail but, I hope, is easier to follow and is not _too_ wrong.

When you create a view, or set of views, in the ViewComposer then you are
actually instantiating new instances of each view you use, you end up with a
collection of correctly initialised, interconnected objects. When you save
this creation as a resource then the whole thing is converted to a sequence
of bytes. This is done by converting every Smalltalk object referenced in
the resource into a form from which it can be regenerated at a later stage.
This basically consists of the class of the object and the contents of it's
instanceVariables - it's state.  This can best (?) be thought of as a tree
with each node representing an object's class and state with subnodes for
anything in the state that is not a simple object (not Integer, Character
etc)

When the resource needs to be displayed the complete view is recreated from
the binary representation. A new instance of the class for each node in the
tree is created and the instance variables for them are set from the stored
binary values.

That last bit is part of the problem you have come across. Say the resource
was created using a view that had two instance variables. The resource was
converted to binary and stored in the image. Now you add a new instance
variable to the view. When you try and reload the resource then the attempt
to recreate the view instance fails because the stored object knew about two

instVars but the newly created instance requires three.

Dolphin gets around this using some class side methods. Among them are

#stbVersion
stbConvertFromVersion:

Every class is given a stbVersion number (defaulting to Object which answers
0). If the shape of the class, the number of instVars is changed, then you
must do two things.

1) increase the number answered by #stbVersion. This is stored as part of
the binary representation of instances of the class.

2) provide a method (usually named #stbConvertFromVersionX:) that an
converts from an earlier version into a newer version.  This normally
involves the copying of values between two Arrays, one being the values
stored in the binary resource and the other the instVar slots in the new
instance.

When an object with a lower #stbVersion number is loaded it is therefore
converted, one step at a time, into a form that is acceptable for instances
of the current shape of the class.

Two other points that have some bearing

- The state is stored as a simple Array, no use is made of the
instanceVariable names. When a view is recreated it is the position in the
array that defines which instVar it is put back into.

- The state of an object involves the instVars defined in the object _and_
the instVars defined in the superclasses of the object. Changing the number
of instVars in a class that is high in the hierarchy (eg View) will have
repercussions for subclasses.

This last point is the one that is going to cause you problems. Take a look
at ShellView class>>stbConvertFromVersion9: for example . It expects the
superclass to have a specific number of instVars and assumes it can access
the Array at a certain place to update the instVars that the stb version
changed. If you alter the number of instVars in View then this alignment
will be broken and the reconstructed ShellView instance will have it's
instVars restored to the wrong place.

Regards
    Ian


Reply | Threaded
Open this post in threaded view
|

Re: How to add instance variables to View

Chris Uppal-3
In reply to this post by Udo Schneider
Udo Schneider wrote:

> I'm just playing around with alpha blending and color keying. I wanted to
> add additional
> instance variables to view but this seems to be harder than I thought.
[snip]
> Any ideas or hints how to fix this?

You could maybe use Object>>propertyAt:ifAbsent:, Object>>propertyAt:put:,
and their friends.

    -- chris