I have moved!

I've moved my blog
CLICK HERE

Friday 21 December 2007

Simpler Animation in WPF

WPF has a very powerful animation system built into it. But you can tell just by looking at the design that Microsoft created it before certain features became available in C#.

It works by storing a reference to an object that has the ability to modify the value of a property on another object. That's not very clear in abstract, so an example will be helpful. The "other object" might be a rectangle painted on the screen. The property on that object might be its opacity (the inverse of transparency). So an animation is an object that contains code that modifies the opacity of the rectangle, causing it to fade out of existence in a visually satisfying way.

This works very nicely for classes already provided by Microsoft. What if I have my own property on my own class, and I want to make an animation that varies the value of that property? I have two options:

  1. Make it an ordinary property. I will have to give the animation object a string containing the name of that property, so it can look it up using reflection. This is pretty nasty. If I rename the property, the compiler will not notice a problem. Reflection is "binding at runtime". Aside from the loss of static checking, there's the small matter of the extra work this involves at runtime, potentially slowing down my animation.
  2. Make it a dependency property. This is a concept introduced with WPF. It basically means that the value is stored in a sort of map, where the key is a special object that acts as the name of the property at runtime. This restores compile-time checking, but there is no direct language support in C# for dependency properties, and it shows; turning an ordinary field into a dependency property requires a lot of boilerplate code.

An added complexity is that there have to be animation objects for manipulating all the different possible datatypes.

Meanwhile, C# has a very nice feature in version 3.0 called "lambda expressions". Suppose an animation was defined as a delegate with this signature:

delegate void Animate(double progress);

The progress parameter indicates how far through the animation sequence we are, so at the beginning it has the value zero, and at the end it has the value one. The delegate is called repeatedly during the predefined time period, each time receiving an appropriate progress value.

Now suppose in order to run an animation, the system has a static class called AnimationSystem provided us with a function like this:

void Start(int duration, Animate animation);

To get animation to happen, you just call Start with a duration in milliseconds and an implementation of the Animate delegate. Thanks to lamda expressions, this can be done very neatly.

For example, when the user clicks on my canvas, I add a rectangle and I want it to "fade up" over one second. The rectangle r has an Opacity property. So I just do this:

Animation.Start(1000, p => { r.Opacity = p; });

If I wanted to do anything more complicated, delegates can have any code in them, so there are no limitations. And yet the simple (yet useful) case above is very succinct and clean.

As an example of something more complicated, and yet not very hard to figure out how to do with this system, consider making an object move diagonally, adjusting the X and Y coordinates simultaneously over a range of values from 0 to 100:

AnimationSystem.Start(1000, p => {

r.X = p * 100;

r.Y = p * 100;

});

Look up how to do that with the WPF framework and I think you'll agree this is a lot simpler! No need to write your own separate animation class.

Fortunately we don't need to cry about the fact that Microsoft didn't implement animation this way, because it's very easy to write that AnimationSystem.Start function. (Clue: WPF has a class called CompositionTarget with a static event called Rendering.)

Friday 30 November 2007

A new use for the C# using keyword

It worries me that the using keyword doesn't have enough meanings already! But coming from a C++ background I'm very keen on the using (...) { scope } syntactic sugar. It helps with clients of IDisposable objects. But so far, it provides no help for implementors. So my suggestion is to allow the using keyword to act as a modifier on member variables.

Simple example:

class B { using FussyResource X; } 

is equivalent to:

class B : IDisposable 
{
  FussyResource X;

  public virtual void Dispose()
  {
    if (X != null)
      X.Dispose();  
  }
} 

So we can compose objects hierarchically and the IDisposable pattern is followed automatically through the hierarchy.

The using keyword in this context indicates that the outer object owns the inner object, determining its lifetime. Applying the using keyword to a type that does not implement IDisposable is an error. Of course inheritance needs to work too:

class C : B { } 

already works, because C inherits B's implementation of IDisposable. But consider:

class D : B {  using FussyResource Y; }

This needs to be translated as:

class D : B 
{
  FussyResource Y;

  public override void Dispose()
  {
    if (Y != null)
      Y.Dispose();

    base.Dispose();
  }
}

This need to override the base class's Dispose means that the base class must have a virtual Dispose. If it doesn't, then the user will not be able to take advantage of the using field modifier when they inherit from that base class.

Finally, to allow it to freely mix with existing code or to allow custom disposal in advanced cases, we also need work well alongside explicit declarations of IDisposable in the same class:

class E : IDisposable 
{
  using FussyResource X;
  IntPtr Win32Resource Y;

  public void Dispose()
  {
    Win32Helpers.FreeWin32Resource(Y);
  }
}

produces:

class E : IDisposable
{
  FussyResource X;
  IntPtr Win32Resource Y;

  public virtual void Dispose()
  {
    __Custom_Dispose();

    if (X != null)
      X.Dispose();
  }

  private void __Custom_Dispose()
  {
     Win32Helpers.FreeWin32Resource(Y);
  }
}

This could be added to C# as a pure language feature, requiring no changes to the CLR. It fits in with the existing use of using as defining a scope control the lifetime of objects. It gives C# support for implementing the IDisposable pattern that is on a par with C++/CLR. And it would mean that most of the time, writing IDisposable.Dispose by hand would be unnecessary. A little more procedural code is moved into a simple declaration.