simple display (from: GUI library for D)

Adam D. Ruppe destructionator at gmail.com
Sat Apr 9 19:30:37 PDT 2011


bearophile wrote:
> More little tasks for your module:
> http://rosettacode.org/wiki/Fractal_tree#Python

This one's use of recursion caused me to hit what I think is a
compiler bug. Not in the recursion itself, but in a struct's
copy constructor when it had a significant mixin.

I worked around it by declaring a private struct and using a pointer
to it rather than mixing in the implementation directly. I believe
this will be a net-positive too, since ScreenPainter is now
referenced counted.

Here's the implementation:

====
import simpledisplay;
import std.math;

void main() {
    // auto image = new Image(600, 600);
    auto window = new SimpleWindow(600, 600, "Fractal Tree");

    void drawTree(ScreenPainter p, in int x1, in int y1, in real angle, in int
depth) {
        if(depth == 0)
            return;
        immutable x2 = x1 + cast(int) (cos(angle) * depth * 10);
        immutable y2 = y1 + cast(int) (sin(angle) * depth * 10);
        p.drawLine(Point(x1, y1), Point(x2, y2));

        drawTree(p, x2, y2, angle - 0.35, depth - 1);
        drawTree(p, x2, y2, angle + 0.35, depth - 1);
    }

    drawTree(window.draw, 300, 550, -PI / 2, 9);
    window.eventLoop(0, (dchar) { window.close(); });
    // displayImage(image);
}

===

The reason Image is there, but commented out, is that such things
might be better done as images, then displayed once finished.
But, since we don't have drawing lines to images yet*, I went
direct to screen instead.

(well, I do have my implementation of Bresenham's algorithm, but I
want to see Mathias' code before falling back on mine. Mine worked
well for DOS, but better anti-aliasing is expected nowadays.)

DrawTree takes an existing ScreenPainter so I can limit it's scope
to only where it's used. The new reference counting under the hood
means that while the struct is copied several times here, it isn't
wasteful.

The eventLoop inline delegate allows you to close the window by
pressing any key as well as using the button in the corner. I
don't think the Python version on rosetta code would allow this.


Comparing to the Python version, mine is a little shorter, primarily
due to the much simpler initialization. The Python one took three
lines to do what SimpleWindow's constructor does in one. I also
put the "get_surface" kind of thing that allows drawing inline
to the drawTree line. Like I said above, this was for reasons of
scope, but it coincidentally shaves a line too. As does the struct
destructor doing the job of display.flip().

The last place where I save a couple lines is the event loop, doing
all that in one place instead of a separate function, loop, and
fetcher. (Note: the delegate in there is not strictly necessary!
It handles quit events sanely by default.)


All in all, I'm very happy with this approach so far. It's simple,
it's short, it's readable, it's reasonably efficient, and the
implementation is moderately lean. Everything I was hoping for!


More information about the Digitalmars-d mailing list