I have moved!

I've moved my blog
CLICK HERE

Wednesday 30 April 2008

Alignment of Rectangular Objects

In my editing program, the objects that can be manipulated with the mouse are called "selectables", and they implement this interface:

public interface ISelectable
{
    IEnumerable<IGrip> Grips { get; }

    void Offset(Vector v);
}

So an object can be moved around the page by calling Offset, and it can have grips, which look like this:

public interface IGrip
{
    Point Position { get; set; }
}

The grips appear on the screen as little circles that you can grab and move with the mouse to change the shape of the object. Most rectangular objects have eight grips - you know how these things usually work. We could do without the Offset function, and just change the position of all the grips instead, but most object types can do a better (more efficient) job of moving themselves rigidly if they know that's what is required.

I also have a nice extension method on ISelectable called GetBounds() that loops through the grips to find the bounding rectangle. And another that does the same thing on IEnumerable<Selectables>.

Now what I want is a toolbar with some alignment buttons. When I press the Align Left button, all the selected objects should move so that their left-most point is aligned with the left-most point of the entire selection. And the same for the other three sides.

It's easy enough to write this for one side, given a property called Selected that is an IEnumerable<Selectables> containing all the objects that the user has selected (ignore the BeginUndoTransaction bit - it just ensures that all the changes we make will be undoable as a single atomic operation).

public void AlignLeft()
{
    using (var undo = BeginUndoTransaction())
    {
        Rect boundsTarget = Selected.GetBounds();

        foreach (ISelectable s in Selected)
            s.Offset(new Vector(
                boundsTarget.X - s.GetBounds().X, 0));

        undo.Commit();
    }
}

But if you're anything like me, you get a stomach ache if you're faced with the task of making four very similar copies of some code. We're doing basically the same thing with all four sides of the rectangle. Why do we have to write it four times?

What we need is an operator we can use on a Rect that can do the same thing to any of its sides - namely, set the position of a side without changing the size of the Rect:

public static void SetRigid(this Side e, ref Rect r, double c)
{
    switch (e)
    {
        case Side.Left: r.X = c; break;
        case Side.Top: r.Y = c; break;
        case Side.Right: r.X = c - r.Width; break;
        default:
            r.Y = c - r.Height;
            break;
    }
}

(Note that the side to operate on is specified by a parameter of type Side, introduced yesterday.)

Now our alignment function can be written like this:

public void AlignSide(Side side)
{
    using (var undo = BeginUndoTransaction())
    {
        Rect boundsTarget = Selected.GetBounds();

        foreach (ISelectable s in Selected)
        {
            Rect boundsOld = s.GetBounds(), 
                 boundsNew = boundsOld;

            side.SetRigid(ref boundsNew, boundsTarget.Get(side));

            s.Offset(boundsNew.TopLeft - boundsOld.TopLeft);
        }

        undo.Commit();
    }
}

And now that does all four directions. Just specify the side parameter.

So the moral is, don't let the lack of symmetry in classes force you to write the same code several times. Discover the operations that express the symmetry, and then write your code in terms of those operations.

Tuesday 29 April 2008

WPF and Symmetry in Coordinate Systems

WPF provides some types for representing geometrical concepts. The simplest one is Point, which is roughly like this:

public struct Point
{
    public double X { get; set; }
    public double Y { get; set; }
}

This is fine but it misses an important fact about the X and the Y fields, which is that if you tip your head over 90 degrees and look at your monitor sideways, the X and the Y swap over. Which is which is merely a matter of your point of view. And so it is frequently useful to support exactly the same operations in both dimensions, which means that you have to write very nearly exactly the same code twice.

So there are some symmetries hiding in the way WPF represents graphics, and it doesn't have a built in way of abstracting over those symmetries, and the result is code duplication. Not good.

What is needed is a way to write an algorithm that operates on a Point but can be told which dimension to mess with. So we need a variable that identifies a dimension. Simple enough:

public enum Dimension { X, Y } 

Then we need some operations we can perform on a point's dimensions. Extension methods are very nice for this:

public double Get(this Point point, Dimension dimension)
{
    if (dimension == Dimension.X)
        return point.X; 

    return point.Y;
}

So now we can retrieve the X coordinate of a point p like this:

double x = p.Get(Dimension.X);

I know this looks a lot uglier than:

double x = p.X;

but it has the major advantage that you can now write, in a fairly natural way, a big complicated algorithm that examines either the X or the Y coordinate of a lot of Points, and you can decide which by passing it a parameter.

What else? Some times my algorithm works mostly along one dimension but then needs to do something to the orthogonal dimension (i.e. the other one of the two available). So this operation is useful:

public Dimension GetOrthogonal(this Dimension dimension)
{
    if (dimension == Dimension.X)
        return Dimension.Y; 

    return Dimension.X;
}

It's like a simple mathematical operator. Maybe group theory is relevant here, though probably not worth digging into right now.

A more pressing problem is that of setting the values. The big problem is that extension methods are quite limited here. An extension method on a value type is passed a copy of the object, because it's a value type. And this isn't allowed:

public void Set(this ref Point p, Dimension dim, double val)

The compiler won't let us put the ref modifier on a this parameter. There was probably some important reason for this involving generics, but it's a real pain in most situations. But we can still use an extension method in a different way:

public void Set(this Dimension dim, ref Point p, value val)
{
    if (dim == Dimension.X)
        p.X = val;
    else
        p.Y = val;
}

In other words, the Dimension has the setter on it, rather than the Point. So:

Point p;
Dimension d = Dimension.X;
d.Set(ref p, 10);

Nice'n'easy, although it looks ugly when the Point is a property of something, because you have to copy it out into a temporary variable and then modify it, and finally copy it back into the property. But that's value-type properties for you. One of the few ugly wrinkles of C#.

Of course, the real solution is to not write functions that have side-effects on value-type parameters. Or to put it another way:

public Point GetAdjusted(this Point p, Dimension dim, double val)
{
    if (dim == Dimension.X)
        p.X = val;
    else
        p.Y = val; 

    return p;
}

So to change Dimension d of a Point p to 56.1, we would write:

p = p.GetAdjusted(d, 65.1);

Which ain't too bad. In reality, I provide extensions both for Point and Dimension so I can use the least-painful variation depending on the situation.

A similar facility can help with using Rect, which has its own special problems. It has these among its properties:

public double Left { get; }
public double Top { get; }
public double Right { get; }
public double Bottom { get; }

public double Width { get; set; }
public double Height { get; set; }

public double X { get; set; }
public double Y { get; set; }

Note that the first four can't be set, which seems unnecessarily incomplete. Anyway, just as a Point has two dimensions, a Rect has four sides:

public enum Side { Left, Top, Right, Bottom }

As well as the same operations for getting and setting the positions of the sides on a given Rect, there's this handy operation that gives you the opposite of a side:

public Side GetOpposite(this Side side)
{
    switch (side)
    {
        case Side.Left: return Side.Right;
        case Side.Right: return Side.Left;
        case Side.Top: return Side.Bottom;
    }
    return Side.Top;
}

And how about moving between the worlds of sides and dimensions? To get from a side to the corresponding dimension:

public Dimension GetDimension(this Side side)
{
    switch (side)
    {
        case Side.Left: return Dimension.X;
        case Side.Right: return Dimension.X;
        case Side.Top: return Dimension.Y;
    }
    return Dimension.Y;
}

Moving the other way presents a choice because each dimension has two sides:

public Side GetMinimumSide(this Dimension dim)
{
    if (dim == Dimension.X)
        return Side.Left;
    return Side.Right;
}

public Side GetMaximumSide(this Dimension dim)
{
    if (dim == Dimension.X)
        return Side.Right;
    return Side.Bottom;
}

Nothing too complicated. I'll post a real example use soon.

Wednesday 9 April 2008

Coroutines with IEnumerable and yield return

There was a brief flurry of excitement about the fancy yield return syntax when the C# 2.0 specification was first published some years ago, and the idea of it being used for creating coroutines.

This quickly died down, as far as I can see anyway. Either people forgot the idea, or it became such boringly standard practice that no one ever thinks to discuss it anymore. I don't know which, but I think it deserves more attention either way.

There were a few people at the time saying that it was a shame that C# appeared to only support coroutines in a special case where the function returns some weird IEnumerable<T> thing, and wouldn't it have been better if it was more general?

But that's a misunderstanding. The caller that drives the execution of the coroutine needs some uniform way of doing so, and also of getting results as they become available. So an enumeration is in fact an ideal and general interface to a coroutine. Nor is it necessary to use the enumerated results as the "actual" results of the coroutine, as I will soon demonstrate.

Aside: A word about threads. Obviously using a background thread is the most general solution, but it can be difficult to get right (or difficult to know when you've got it wrong, which amounts to the same thing). It also requires the results to be marshalled to the foreground thread because most GUI frameworks can't cope with direct calls from multiple threads.

The single-threaded approach requires you to break your long-running algorithm into little slices that can be performed one at a time. This may be impossible, if the long waits are caused by going out to some 3rd party library function that you don't have the ability to break up into multiple short-lived calls.

Supposing you own the code for a lengthy algorithm, and you want to break it up into steps that can be executed one at a time, allowing you to keep interacting with the user. How should you go about doing it? It's not fun to turn a function inside out and convert it into a state machine. The end result is often harder to understand and maintain. But this is where yield return comes to the rescue.

An example: suppose my very complicated algorithm is going to fill in a list with the numbers from 1 to a million. Here's the simple version:

void Fill(ListView listView)
{
    for (int n = 1; n <= Million; n++)
    {
        listView.Items.Add(n.ToString());
    }
}
 
And I might call it like this:
 
Fill(myListView);
 
Which is fine except that the user interface locks up for about ten seconds until it's done. So here's a different way of writing it:
 
IEnumerable<double> Fill(ListView listView)
{
    for (int n = 1; n <= Million; n++)
    {
        listView.Items.Add(n.ToString());
        yield return (double)n / (double)Million;
    }
}
 

It returns an IEnumerable and it spits out a double each time it goes round the loop. The doubles actually just indicate how far through the operation we are, ranging from 0 to 1. This is what I mean by not using the enumerated values as the "actual" results of the coroutine. The actual results are whatever we do with the parameters to the coroutine - in this case, we put the results in a ListView.

By emitting doubles between 0 and 1 that indicate the progress, we have a completely general interface to a coroutine. Of course, you could just yield zero or a random number each time - it just means you lose out on a nice feature as we'll see in a moment.

Now we need some way of starting it running in parallel, a little like launching a thread. This is what my CoroutineOnEnumerable class is for:

// Using a coroutine
var listFiller = new CoroutineOnEnumerable();

listFiller.Start(Fill(myListView));

We can also insert an extra step in that snippet to tie the listFiller object to a progress bar to show the user how far we've progressed:

// Using a coroutine
var listFiller = new CoroutineOnEnumerable();

// Attach to progress bar
listFiller.Progressed += (s, e) =>
        myProgressBar.Value = listFiller.Progress;

listFiller.Start(Fill(myListView));

Each time the routine progresses, we set the Value of myProgressBar, which of course has a range of 0 to 1. This is the only reason why you need to care about what values you yield during your coroutine's execution. They supply the value of the Progress property. If you aren't going to use that to indicate progress to the user, you can just say yield return 0. That's what I do when the coroutine has no easy way to figure out how far it has gone (for example, recursively scanning a tree structure such as the file system).

You can also attach a handler for when it finishes, as it has a Completed event (this fires when the coroutine actually finishes, not when it yields a 1).

If the caller wants to abandon the operation (for example, the user got tired of waiting and pressed a Cancel button), you should call the Stop method on your CoroutineOnEnumerable instance (or alternatively, call the standard Dispose method - both have the same effect). If you don't do this then any finally blocks within the coroutine will never run.

It also has an adjustable MinimumTimeSlice, which is the minimum number of milliseconds that it will spend executing the routine before actually yielding control to the environment. This is important - if we actually yielded control back to the environment every time yield return in the coroutine, it could run very slowly. Note that this is only a minimum limit, not a maximum - this is cooperative multithreading, and is dependent on the coroutine calling yield return at regular intervals.

Here's CoroutineOnEnumerable.cs:
using System;
using System.Windows.Threading;
using System.Collections.Generic;

namespace WpfApplication1
{
    public class CoroutineOnEnumerable : IDisposable
    {
        private DispatcherTimer m_timer;
        private IEnumerator<double> m_routine;
        private double m_progress;

        public event EventHandler Progressed, Completed;
        public double MinimumTimeSlice { get; set; }

        public CoroutineOnEnumerable()
        {
            MinimumTimeSlice = 100;
        }

        public bool Busy
        {
            get { return m_timer != null; }
        }

        public double Progress
        {
            get { return m_progress; }

            set
            {
                if (m_progress != value)
                {
                    m_progress = value;

                    if (Progressed != null)
                        Progressed(this, EventArgs.Empty);
                }
            }
        }

        public void Start(IEnumerable<double> routine)
        {
            Stop();

            m_routine = routine.GetEnumerator();

            m_timer = new DispatcherTimer(DispatcherPriority.Normal,
                                          Dispatcher.CurrentDispatcher);
            m_timer.Interval = TimeSpan.FromMilliseconds(1);
            m_timer.Tick += OnTick;
            m_timer.Start();
        }

        public void Stop()
        {
            if (m_timer != null)
            {
                m_timer.Stop();
                m_timer = null;
            }

            if (m_routine != null)
            {
                IDisposable disp = m_routine as IDisposable;
                if (disp != null)
                    disp.Dispose();
            }
        }

        void OnTick(object sender, EventArgs e)
        {
            if (m_routine != null)
            {
                System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
                stopWatch.Start();

                while (stopWatch.ElapsedMilliseconds < MinimumTimeSlice)
                {
                    if (!m_routine.MoveNext())
                    {
                        Stop();
                        Progress = 1;
                        if (Completed != null)
                            Completed(this, EventArgs.Empty);

                        return;
                    }
                }

                Progress = m_routine.Current;
            }
        }

        public void Dispose()
        {
            Stop();
        }
    }
}

And here's the example app code that you can paste into a Wizard generated WPF application. Firstly the XAML in Window1.xaml:

<Window x:Class="WpfApplication1.Window1"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Title="Window1" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ProgressBar Grid.Row="0" Name="myProgressBar" Minimum="0" Maximum="1"/>
        <ListView Grid.Row="1" Name="myListView"/>
    </Grid>
</Window>
And the code-behind in Window1.xaml.cs:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        const int Million = 1000000;

        public Window1()
        {
            InitializeComponent();

            // Fill(myListView);   -- Traditional subroutine

            // Using a coroutine
            var listFiller = new CoroutineOnEnumerable();

            // Attach to progress bar
            listFiller.Progressed += (s, e) =>
                    myProgressBar.Value = listFiller.Progress;

            listFiller.Start(Fill(myListView));
        }

        /* The traditional subroutine definition

        void Fill(ListView listView)
        {
            for (int n = 1; n <= Million; n++)
            {
                listView.Items.Add(n.ToString());
            }
        }
        */
        
        // The coroutine definition
        IEnumerable<double> Fill(ListView listView)
        {
            for (int n = 1; n <= Million; n++)
            {
                listView.Items.Add(n.ToString());
                yield return (double)n / (double)Million;
            }
        }
    }
}

Speaking as a long-time suffering of thread anxiety, this built-in support for coroutines is reason enough for me to prefer C# over any other mainstream language.