On Mar 30, 2007, at 11:21, Vincent Hennebert wrote:

Hi Vincent,

I have little knowledge of the FO tree construction, so I'll perhaps
make naive questions and remarks. I write them in the hope they will
trigger further thoughts.

That was the general idea. :-)
Besides, people who are not all too familiar yet with that part of the code are sometimes more likely to offer helpful hints (as their thinking has not yet been contaminated ;-))

<snip />
Also, that causes the same code to be replicated in every class; for
example each object for which the margin properties apply will have (1)
a CommonMarginBlock field; (2) a "commonMarginBlock =
pList.getMarginBlockProps();" line in the bind method. This replication
of code is unfortunate as it artificially increases the codebase size,
is more error-prone and more difficult to maintain.

Indeed! Yet another reason pro refactoring in that area.

In ancient times, each FO had a full PropertyList, so the properties
could be queried via a generic get(PROPERTY_ID) accessor that was simply a proxy to the PropertyList's corresponding get(). This was, however, a
much less efficient approach than what we currently have.

To be sure I understand: each object had the very same list of
properties, with null values for the properties wich were not applicable
to it?

Errm... yes, if what you mean by 'the very same' is 'a different instance of the very same type'. Each FObj instance had its very own instance of the same PropertyList type.

And the loss of efficiency was due to the indirection caused by
the generic get(PROPERTY_ID) I guess?

The biggest inefficiency was the space that these lists consume. They allocate space for an array with a number of elements equal to the number of /possible/ properties, effectively wasting space in case of FOs to which only a handful properties apply. On top of that, this space was not reclaimed until very late in the process, whereas now, the PropertyLists and their backing arrays in most cases can be garbage-collected right after endElement().

A FO to which only three properties apply will currently have only three instance variables corresponding to those properties. In the old architecture, it would have one PropertyList member, containing an array that could store some 250 Property instances, but only three elements were actually in use...

The inefficiency caused by the indirection I would consider to be a small but necessary price to pay for an increased amount of flexibility and extensibility.

<snip />
Each of the particular FO classes can then define its own
implementation, which stores the applicable properties and maybe, for
some FOs (like FOText!), this implementation can simply search the
ancestors, instead of having to allocate space for properties that are
always identical and can't be specified anyway...

Hmmm. My understanding of the whole thing is still a bit vague, but
wouldn't that lead to the same code replication as we have now?
I'm wondering if it's not possible to define a restricted number of
implementations of this interface, each applying to a whole set of
similar FOs.

Good point!

Or use object composition: there would be objects dealing
with a particular set of properties (say, border/padddin/background),
and each FO for which that set applies would be composed of the
corresponding object.

Perhaps the flyweight pattern could apply here: only one object for each
set of properties, initializing the correct fields in the FObj. With
some means to automagically wire everything by using marker interfaces
or whatever.

Also fine suggestions. I'm going to chew on these a bit more.

As I said my ideas are still all pretty vague... Also, does anyone have
knowledge about aspect programming? I've the feeling that could apply
quite well here.

Just been reading up on AOSD, and it does indeed seem to be fitting in here.

The downside would be the loss in convenience, for instance, where we
now have individual accessors returning a Length, LengthRange,
Numeric... Not sure how I would address this, yet. :/

I'm not sure of what you mean? The same property can be accessed in
different ways?

What I mean is that right now, the bind() method already takes care of getting the right type of Property.
pList.get(PROPERTY_ID).getLengthRange() for instance...

An accessor getInlineProgressionDimension(), for example, returns a LengthRange (not a Property).

This treatment would obviously have to be moved or performed somewhere else, if a generic get() would always return an instance of type Property.

If anyone has suggestions, feedback is welcome.

I hope what I wrote makes sense :-\

It did.


Cheers,

Andreas

Reply via email to