Roassal internals - ROShape>>addLast:in: & ROChildrenShape

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

Roassal internals - ROShape>>addLast:in: & ROChildrenShape

Ben Coman
Just recording a bit of my learning the internals of Roassal, since it
helps me flesh out my understanding.

At first glance looking at [ROShape>>addLast:] this seemed to
recursively call itself with no exit-condition, but then I noticed its
ivar 'next' is initialized to ROChildrenShape this provides the exit
condition inherited from RONullShape. Adding a shape replaces this
ROChildrenShape in 'next', but the new shape itself has a
ROChildrenShape in its 'next' .

I haven't got as far looking at ROChildrenShape yet, but briefly thought
it might be a container holding other shapes, but then actually I think
it is the ROElements ivar 'elements' that is the container of subview
nodes - and that ROChildrenShape just stores how to draw the subview nodes.

I guess it is the lack of the [drawOn:For:] method that distinguishes
between abstract and concrete ROShape classes. By the way, what is the
design decision of leaving [ROShape>>drawOn:For] blank rather than using
[self subclassResponsibility] ?

So, just to confirm my understanding, perhaps the following or similar
would be useful as a comment on ROShape>>addLast:
"Instance variable 'next' must be a RONullShape to provide the exit
condition of this recursive call.  This is ensured by instance
initialization"

cheers -ben

_______________________________________________
Moose-dev mailing list
[hidden email]
https://www.iam.unibe.ch/mailman/listinfo/moose-dev
Reply | Threaded
Open this post in threaded view
|

Re: Roassal internals - ROShape>>addLast:in: & ROChildrenShape

abergel
> Just recording a bit of my learning the internals of Roassal, since it helps me flesh out my understanding.
> At first glance looking at [ROShape>>addLast:] this seemed to recursively call itself with no exit-condition, but then I noticed its ivar 'next' is initialized to ROChildrenShape this provides the exit condition inherited from RONullShape.

Exactly. This is an instance of the Null Object design pattern.
I try to avoid ifTrue:ifFalse: as much as I can. Only 7.6% of Roassal methods have an if statement. Slightly less than Glamour (8.08%). Mondrian has 8.63%. This figure goes to 9.57% for Moose, 10.33% for Fame and 20.96% for AST.  Less is better.

> Adding a shape replaces this ROChildrenShape in 'next', but the new shape itself has a ROChildrenShape in its 'next' .
> I haven't got as far looking at ROChildrenShape yet, but briefly thought it might be a container holding other shapes, but then actually I think it is the ROElements ivar 'elements' that is the container of subview nodes - and that ROChildrenShape just stores how to draw the subview nodes.

Yes. ROChildrenShape displays the children node. This shape is per default on an element. On some point, we will be able to change this shape for a ROLevelledChildrenShape to enable semantic zooming.

> I guess it is the lack of the [drawOn:For:] method that distinguishes between abstract and concrete ROShape classes. By the way, what is the design decision of leaving [ROShape>>drawOn:For] blank rather than using [self subclassResponsibility] ?

Because executing "self subclassResponsibility" raise an error. And drawOn: is a method that is called by the UI thread. When you create a shape, you may forget to redefine drawOn:For:.
Since in Pharo (as it was in Squeak), UI thread behaves heretically time to time, having a blank ROShape>>drawOn:For: avoid having this infinite list of opening debugger, which inevitably leads to killing the image.

Side node: Processing is a very cool graphic engine. I believe that one reason of the success of Processing to that it rarely crashes. When you do something wrong, then it just complains. There is no infinite loop of debugger opening or need to kill the running process.

> So, just to confirm my understanding, perhaps the following or similar would be useful as a comment on ROShape>>addLast:
> "Instance variable 'next' must be a RONullShape to provide the exit condition of this recursive call.  This is ensured by instance initialization"


Good idea.
In Roassal 1.96

Indeed, Roassal is not well documented. Instead, I tried to keep the code very simple.
A major documentation will soon be needed.

Cheers,
Alexandre

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.



_______________________________________________
Moose-dev mailing list
[hidden email]
https://www.iam.unibe.ch/mailman/listinfo/moose-dev