In the code, we have several instances of vtables: RenderOps, ObjectOps
etc. These are created by the actual objects and filled mostly with their
own function pointers, though occasionally explicitly using generic
functions. The ObjectOps structure has 10 words reserved for expansion,
the RenderOps structure has none.
In particular when looking at the RenderOps structure, I find that a more
flexible approach to this kind of inheritance is needed. We need to be
able to expand the structures, to build more complicated structures from
simpler ones, and to make more use of inheritance.
Here's an alternate setup of the vtables that gives us this flexibility
without losing performance. Each inheriting class (renderers and objects)
calls the 'parent' function to create and initialize the vtable.
Afterwards, it overwrites with its own functions where needed.
This takes slightly more time at startup, as all classes must fill their
vtables, but not I think a significant amount.
The most important gain is that we can expand the structure at any time
without losing binary compatibility. Since the parent allocates the
structure, childs that don't know about the new functions will still get
the proper vtables.
By having a default set of functions set by the parent, we can construct
more complicated shapes from simpler ones, while allowing advanced
renderers to use specialized functions. For instance, a
draw_line_with_arrows function could by default call the normal draw_line
and arrow rendering functions, but an xfig renderer may just dump it as a
line with arrows. More importantly, if we want to make better arrow
implementations, we can encapsulate the rendering tricks in the default
functions and have all renderers benefit.
To implement this, we need to convert all objects and renderers to call the
parent alloc function, I can do that. After that, we can start pulling
common functionality (e.g. arrows, rounded rectangles) from the objects
into the renderers, allowing easier use of such primitives, easier building
of new renderers and better output to higher-level formats.
Old binaries will not be able to handle any extended versions we make, but
after a recompile, they should be happy. Thus, this will be the binary
incompatibility to end all binary incompatibilities:)
-Lars
--
Lars Clausen (http://shasta.cs.uiuc.edu/~lrclause)| Hårdgrim of Numenor
"I do not agree with a word that you say, but I |----------------------------
will defend to the death your right to say it." | Where are we going, and
--Evelyn Beatrice Hall paraphrasing Voltaire | what's with the handbasket?