Hi,
I've checked-in an alternative implementation using prototypeInstances.
Both implementations can be installed and compared:
prototypeInstances - (Pier-Seaside-NickAger.527)
#write:usingNamed - (Pier-Seaside-NickAger.526).
I think the prototypeInstance has worked well and I'd like to push ahead
with that - converting blog, book and other add-ons - be great if anyone
has a chance to look at what I've done and provide feedback - before I push
ahead in a direction that people later don't think makes sense. Even better
would be help converting some of the components, once we've agreed on a
direction.
The check-in comment:
alternative implementation of PRCommand which takes a #prototypeInstance:
so PRStructure>>defaultEnvironment now reads as:
addChild: ((PRComponent named: 'search')
prototypeInstance: PRSearchWidget new;
yourself);
addChild: ((PRComponent named: 'children')
prototypeInstance: (PRChildrenWidget new
level: 1;
yourself);
yourself);
addChild: ((PRPage named: 'sidebar')
addChild: ((PRComponent named: 'navigation')
prototypeInstance: (PRChildrenWidget new
level: 2;
expand: true
yourself);
yourself);
addChild: ((PRComponent named: 'views')
prototypeInstance: PRViewsWidget new;
yourself);
addChild: ((PRComponent named: 'commands')
prototypeInstance: PRCommandsWidget new;
yourself);
whereas my first attempt using #write:usingNamed looks like:
addChild: ((PRComponent named: 'search')
componentClass: PRSearchWidget;
yourself);
addChild: ((PRComponent named: 'children')
componentClass: PRChildrenWidget;
write: 1 usingNamed: #descriptionLevel;
yourself);
addChild: ((PRPage named: 'sidebar')
addChild: ((PRComponent named: 'navigation')
componentClass: PRChildrenWidget;
write: 2 usingNamed: #descriptionLevel;
write: true usingNamed: #descriptionExpand;
yourself);
addChild: ((PRComponent named: 'views')
componentClass: PRViewsWidget;
yourself);
addChild: ((PRComponent named: 'commands')
componentClass: PRCommandsWidget;
yourself);
The alternative implementation with prototypeInstances simplifies
PRComponent, and is more efficient (though I doubt that is significant with
the larger context of Pier). Another advantage is that there is less of a
conceptual jump for people making a move from WAComponents to PRWidgets -
as it allows an alternative form of widget development. That is widgets can
use instance variables to hold their state rather than being required to
map state onto #properties stored within PRWidget. As an example I've
modified PRBatcherWidget, PRContentsWidget, PRHtmlWidget, PRSearchWidget
and PRTocWidget to use this instance variable state holding form of
widgets. Other widgets keep the old property mapping form, and to support
both forms I've introduced a new base PRWidgetPropertyBase, which
encapsulates the property support.
The prototypeInstance implementation does require that PRWidgets implement
setters; in the examples above I had to modify PRChildenWidget to add
#level: and #expand:. I've modified all PRWidgets to add setters -
potentially this could be automated through a refactoriing or rewrite rule.