[wx-discuss] wxTNG: backends
Mart Raudsepp
leio at dustbite.net
Tue Mar 7 01:19:49 PST 2006
Hello,
Another late reply due to clearing up some INBOX mess so late:
On Fri, 2006-02-17 at 20:14 +0100, Vadim Zeitlin wrote:
> JS> But how will deriving classes and overriding functionality work when
> JS> the basic work is being done by an object of a different class than the
> JS> one you're deriving from? We do away with the normal use of virtual
> JS> functions to override functionality as hinted at in another thread?
>
> pImpl-based implementation and virtual functions don't mix well so yes,
> the idea would be to not have many virtual hooks if we do it like this. But
> unfortunately this is still quite vague for me at the moment...
We did exactly this in OMGUI - no virtuals, pImpl-based implementations.
This has also an interesting additional (theoretical) benefit:
No virtual methods ever used => no breaking of backwards ABI with adding
new methods
There is the user visible layer (the one commonly used), the API layer,
common layer and implementation layer:
The user layer (namespace omgui) creates the implementation and simply
forwards all methods to the m_impl. There are no virtuals (other than
the dtor).
The API layer (namespace omgui::api) is full of pure virtuals and
dictates the public API for all ports to implement. It should be
possible to inherit at the API layer to achieve extending of classes in
user code, that require a vtable (behaviour extension, as opposed to new
methods). I don't recall how this was thought, Robin McNeill
(SnakeChomp) has the insight there (and might be able to correct me
other facts here) - he implemented this after discussion and ideas of
his own.
The common layer (namespace omgui::common) implements common bits of the
API - primarily convenience methods are put here, and implementations of
truly common classes (e.g, sizers).
Classes in the common layer inherit the API layers class and (if
applicable) the parent class in the common layer.
For example:
namespace omgui {
namespace common {
class TextWidget : public virtual Widget, public virtual omgui::api::TextWidget
{ .. };
} }
Often the classes in the common layer are completely empty, and existing
to contain convenience methods that are added in the future.
The implementation layers (namespaces omgui::gtk2, omgui::win32,
omgui::cocoa)... implements the platform specific API.
Classes in the implementation layer inherit the common layers class and
(if applicable) the parent class in the implementation layer.
For example:
namespace omgui {
namespace gtk2 {
class EntryBox : public virtual Widget, public virtual
omgui::common::EntryBox
{ .. };
} }
Note that the inheritance goes like this:
Widget -> TextWidget -> EntryBox
And note that TextWidget is kind of like an interface - it doesn't have
a public ctor and is meant as a class gathering together the common
methods of an EntryBox (single-line entrybox a la GtkEntry), a TextBox
(multi-line simple text control), and others (rich-text text widget in
the future).
Now notice that omgui::gtk2::EntryBox inherits from omgui::gtk2::Widget,
and not from omgui::gtk2::TextWidget. I might add that the win32
implementation of EntryBox does inherit from omgui::win32::TextWidget.
This is done so because there is no code to be shared among the gtk2
implementations of EntryBox and TextBox - the implementation uses
completely different classes, so there simply is no
omgui::gtk2::TextWidget class. But in win32 the same native class is
used, so the common code is in omgui::win32::TextWidget.
This gives quite some flexibility in the implementation - as long you
implement the methods in the equivalent API class you are good to go.
omgui::api::TextWidget methods are all implemented in the EntryBox and
TextBox implementations, so we are good (and TextWidget class doesn't
have to exist, because it's an abstract class).
One can change practically anything in the port implementations without
breaking any public API.
Add new virtuals? No problem. New members? Sure.
Drawing the inheritance relationships can be quite an interesting
practice for C++ newcomers, eh ;)
This has worked pretty well for us, but for obvious reasons it isn't
much tested in actual use. We (at least I) are not sure how easy
extending is, and if it works out well in wide-spread use.
I hope SnakeChomp has something to add, too.
Any comments/questions welcome. OMGUI can be kind of looked at as our
stab at a wxTNG - but with no compatibility concerns whatsoever.
Regards,
Mart Raudsepp
Gtk+ port maintainer of OMGUI
http://www.omgui.org
---------------------------------------------------------------------
To unsubscribe, e-mail: wx-discuss-unsubscribe at lists.wxwidgets.org
For additional commands, e-mail: wx-discuss-help at lists.wxwidgets.org
More information about the wx-discuss
mailing list