Boost logo

Boost :

From: Dave Abrahams (abrahams_at_[hidden])
Date: 1999-12-13 21:21:56


> Hi,
>
> Sorry to come late to this discussion; my DSL connection was (and still
> is) out.
>
> I don't think adding a windowing toolkit to boost is a good idea; it's
> hard to come up with an integrated cross-platform framework that everyone
> is going to be happy to use -- too many design tradeoffs at every level
> of the job.

A windowing toolkit is not a complete GUI framework. You could use other
toolkits if things are loosely integrated enough. You seem to agree with me
that too much integration is bad (at the end of the message), but do you
really grasp the upshot of that idea?

> However, there are certainly design patterns that have
> emerged over the years, initially in the various Macintosh frameworks
> (MacApp, PowerPlant), that may be worth adding to boost. There are also a
> number of smaller opportunities to provide platform-independent wrappers
> for concepts that seem to be relatively universal across platforms. I'd
> love to see boost incorporate a set of these, just as it seeks to
> incorporate fundamental building blocks for other programming tasks.
>
> Examples I have in mind. I'm sure there are more, but these are the ones
> I use in my own framework:
>
> - a message-passing facility that can tunnel OS-specific events. The
> design pattern I use is the one in the Be OS Application Framework, with
> the following general class structure:

<BeOS-like messaging facility snipped>

This is an important concept, but not neccessarily the best design. Messages
should just be member functions on an abstract base class, e.g.

// infrastructure
class receiver;

class broadcaster : // implementation details
{
public:
    void add_receiver(receiver*);
    void remove_receiver(receiver*);

    template <class X>
    broadcast(void (X::*)());

    template <class X, class T1>
    broadcast(void (X::*)(T1));

    template <class X, class T1, class T2>
    broadcast(void (X::*)(T1, T2));

    template <class X, class T1, class T2, class T3>
    broadcast(void (X::*)(T1, T2, T3));
    // etc...
};

class receiver : // implementation details
{
public:
    listen_to(broadcaster*);
    stop_listening(broadcaster*);
};

// user code
class button : public broadcaster
{
public:
    class listener
    {
        virtual void
        button_pressed(button* b, T1 arg1, T2 arg2, T3 arg3) = 0;
    };

    void f( T2 t2, T3 t3) {
        ...
        broadcast(&listener::button_pressed, this, T1(), t2, t3);
    };
};

class foo : public receiver, public button::listener
{
    void button_pressed(button*, T1, T2, T3);
};

Possibly I'm not really talking about the same kind of facility you are,
though?

> - classes for point, and rectangle. I template by scalar type, to support
> "device" coordinates, which are usually integers, as well as "view"
> coordinates, which can be integers (shorts or longs), fixed point
> numbers, or floats. Conversion to platform-specific structures is
> efficient here (even if coordinates have to be swapped), since the data
> structures are so small.

The most important thing missing from most of the coordinate classes I've
seen (which mine support, though) is operators for the common, simple
operations. For example, point classes should support vector arithmetic.
Rectangles should be composable of two points, etc.

> - a class that encapsulates what I call "input state" -- mouse position,
> keyboard state, etc. An instance of this class would be generated
> whenever an interface event is raised, and passed around as a way of
> encapsulating access to the input state at the time of the event. A
> similar class is possible that encapsulates output state -- coordinate
> system transforms, platform-specific references to drawing context, etc.

I am firmly opposed to the existence of output state in APIs. More drawing
bugs have been caused by relying on such environments being left in place
than I can count. My APIs have no state. For coordinate transformation, you
create new canvases by applying the transformation to existing canvases.

> Even if the input/output attributes are platform-specific, encapsulating
> those details in one object is very useful when building event-driven
> frameworks -- you can pass the object around without knowing what's inside it.

A basic idiom I have tried to use for many platform-specific resources, etc.
Passing references around is always easy.

> - a standard (XML?) way of describing control hierarchies, with a
> cross-platform API for writing a control hierarchy to disk, and reading
> one in from disk. Adobe's new desktop publishing application, InDesign,
> includes in its SDK a cross-platform resource compiler called ODFRC,
> except it doesn't use XML.

That's a neat idea.

> - a cross-platform (XML again? Unicode definitely) way of storing
> strings, with an API for accessing string libraries keyed on locale (e.g.
> French, Canadian, Russian, etc.).

Also interesting.

> I think there is potential to build a larger set of interface tools, but
> I agree with Dave Abrahams that any such "framework" should use C++
> idioms, and make use of namespaces to hide platform-specific details. I
> strongly believe that the most successful UI framework is no more than a
> composable set of cleanly separated sub-libraries; too much integration
> is bad, in my opinion. I'd love to see generic programming used to design
> a set of generic interfaces that support UI programming; I'm not yet sure
> what it would look like, but I'm convinced it's worth the effort.

There's some use for generic programming in UI design, but polymorphism
really is an important concept in this domain. I don't think you can get too
far away from traditional OOP here. Maybe I'm missing something?

-Dave


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk