2010-12-10

Silverlight grid brush

Intro

I was developing Silverlight 4 application for drawing floor plan on a plane. One requirement was, there should be a grid mode, and while in this mode, drawing element should snap to the grid. So I need to display this grid on drawing surface. I could think of 2 options how to display a grid:

  1. Many rectangle elements
  2. Background brush

The problem with creating rectangle for each grid point was that it appeared to be extremely slow, considering the fact that the grid was supposed to be constantly changing. Maybe it had to do something with the implementation, as grid points were stored in ItemsControl, which was databound to constantly changing ItemsSource.

The problem with background brush is that there is no such a thing in silverlight 4 off-the-shelf. There is just extremely limited range of basic brushes (like SolidColorBrush, LinearGradientBrush). Although it is written in MSDN that you can derive from Brush class, I couldn't find example on how to do this. By definition, brush maps from a point coordinate to a color. Apparently, Brush class does much more, and since it doesn’t provide something like

public abstract class Brush
{
public abstract Color Map(Point point);
}

(apparently, for performance considerations), it seemed like too much of a hassle to mess with the internals of Silverlight to implement my custom brush.

So, after some googling, I came up with 3rd option:

The idea of pixel shader effect is that each UIElement can have a pixel shader effect applied to it. Pixel shader is somewhat similar to a brush: it maps a pixel from the input image to a color at a corresponding location in the destination image. So it is like a better brush, as it can obtain color at any coordinates from the source image which regular brush cannot.

Silverlight shader effects are written in High-Level Shader Language(HLSL), a C-like language, originally invented by Microsoft for Direct3D. Ideally, pixel shaders should be executed on GPU, utilizing its high parallel throughput ability (each pixel can be processed independently). However, as of now(Silverlight 4), it only utilizes CPU’s SIMD instructions. In other words, today it tends to be quite costly, but this may improve in the future.

So, my idea was, I can create a shader effect which works just like a plain old brush: mapping from source coordinates to destination color(source color can be totally ignored). Shazzam is a good to help with WPF/Silverlight effects development. Having no experience with HLSL, I wrote the simplest thing I could think of, like this:

sampler2D input : register(s0);

// Grid effect shader

/// <summary>Size of the lattice</summary>
/// <minValue>1/minValue>
/// <maxValue>10000</maxValue>
/// <defaultValue>40</defaultValue>
float LatticeSize : register(C0);

/// <summary>Size X of the texture</summary>
/// <minValue>1/minValue>
/// <maxValue>10000</maxValue>
/// <defaultValue>1024</defaultValue>
float SizeX : register(C1);

/// <summary>Size Y of the texture</summary>
/// <minValue>1/minValue>
/// <maxValue>10000</maxValue>
/// <defaultValue>1024</defaultValue>
float SizeY : register(C2);

/// <summary>point size</summary>
/// <minValue>1/minValue>
/// <maxValue>10000</maxValue>
/// <defaultValue>2</defaultValue>
float PointSize : register(C3);

/// <summary>point color</summary>
/// <defaultValue>#FF707070</defaultValue>
float4 PointColor : register(C4);

float4 main(float2 uv : TEXCOORD) : COLOR
{
float stepX = LatticeSize/SizeX;
float stepY = LatticeSize/SizeY;
float pointSizeX = (1 / SizeX)*PointSize;
float pointSizeY = (1 / SizeY)*PointSize;

float4 Color;
Color= tex2D( input, uv.xy);

float dx = uv.x % (stepX);
float dy = uv.y % (stepY);

if(stepX - dx < dx) dx = stepX - dx;
if(stepY - dy < dy) dy = stepY - dy;

if ((dx < pointSizeX)&&(dy < pointSizeY) )
{
Color = PointColor;
}

return Color;
}

and this kind of worked, but there was a problem of edge smoothing. Instead of smoothing edges of a grid point, my shader would create them of a different size, which looks very unpleasant:

grid_shader

Another issue was, this shader effect was also quite slow, considering the fact that it had to be applied for 10000x10000 canvas. Possibly due to all the if’s in the shader code. It is certainly possible to improve this shader so that it would smooth the point edges, and also optimize it big time.

Final solution

The final solution came to my mind after I saw it is possible to create striped brush in Silverlight using LinearGradientBrush, like this

<LinearGradientBrush StartPoint="0,0" EndPoint="0.1,0" SpreadMethod="Repeat">
<GradientStop Offset="0" Color="Red"/>
<GradientStop Offset="0.5" Color="Red"/>
<GradientStop Offset="0.5" Color="White"/>
<GradientStop Offset="1" Color="White"/>
</LinearGradientBrush>

and the idea that we can overlay one canvas on top of the another. So the solution looks like this:

<Grid>
<Canvas Width="300" Height="300">
<Canvas.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,0.05" SpreadMethod="Repeat" >
<GradientStop Offset="0" Color="#FF101010"/>
<GradientStop Offset="0.1" Color="#FF101010"/>
<GradientStop Offset="0.1" Color="#FFF0F0F0"/>
<GradientStop Offset="1" Color="#FFF0F0F0"/>
</LinearGradientBrush>
</Canvas.Background>
</Canvas>
<Canvas Width="300" Height="300">
<Canvas.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0.05,0" SpreadMethod="Repeat" >
<GradientStop Offset="0" Color="Transparent"/>
<GradientStop Offset="0.1" Color="Transparent"/>
<GradientStop Offset="0.1" Color="#FFF0F0F0"/>
<GradientStop Offset="1" Color="#FFF0F0F0"/>
</LinearGradientBrush>
</Canvas.Background>
</Canvas>
</Grid>

Which produces the output:

grid_combinedBrush

It is still not ideal, as the grid points are somewhat blurred which becomes very apparent as point size approaches 1px on the display. This approach, however, has huge advantage over the others: it is lightning-fast! I think that this, combined with “right” resolutions, will be a reasonable solution.

2010-11-10

Scala: reduceLeft vs foldLeft

Let’s say we have two types: Soccer ball, Auto.

Also, let’s say we have operator +, for which Soccer ball+Soccer ball=Soccer ball and Auto+Soccer ball=Auto. Then, speaking in types:

val a = List(Soccer ball, Soccer ball, Soccer ball, Soccer ball)

a.reduceLeft( (Soccer ball, Soccer ball) => Soccer ball + Soccer ball ) : Soccer ball ==

((Soccer ball+Soccer ball)+Soccer ball)+Soccer ball

a.foldLeft(Auto)( (Auto,Soccer ball) => Auto + Soccer ball ) : Auto ==

(((Auto+Soccer ball)+Soccer ball)+Soccer ball)+Soccer ball

Edge cases:

val b = List[Soccer ball]() //empty list of Soccer ball

b.reduceLeft(_+_) //throw exception

b.foldLeft(Auto)(_+_) //returns Auto

val c = List[](Soccer ball) //list of single Soccer ball

c.reduceLeft(_+_) // returns Soccer ball, the single element in the list

c.foldLeft(Auto)(_+_) //returns Auto, result of operation Auto+Soccer ball

Notice the difference: when list is empty, reduceLeft throws an exception, while foldLeft returns starting value. This can often help to decide which one to use.

Examples:

val a = List(1, 2, 3, 4)

//sum of integers in the list
val sum = a.reduceLeft( (u, v) => u+v )
//integers in the list separated by comma, using reduce
val strRepr1 = a.map( u => u.toString() )
  .reduceLeft( (u, v) => u+","+v ) 
  
//sum of squares, we use Long to support larger values
val sqrSum = a.foldLeft(0L)( (u, v)=> u+v*v )
//number if items in the list
var count = a.foldLeft(0) ( (u, v) => u+1 )
//integers in the list separated by comma, using fold
val strRepr2 = a.tail.foldLeft(a.head.toString())( (u, v) =>
  u+","+v )

2010-09-24

The Right Methodology

Is Lean better than Agile? Scrum vs XP? Of course it all depends, and all methodologies can only be to some degree beneficial for current situation. And in the future new methodologies will appear, which will better address problems of the day. There can be no single “body of knowledge” which is relevant forever.

“But what about math”, you may ask. It seems to have stable body of knowledge (say, axiomatic set theory). Well yes, but we are solving problems on a different level today, taking as a foundation all that has been proven before. It’s not that the foundation is irrelevant, it’s that our focus is elsewhere, as we believe the foundation is stable :).

Also, there is no “single true” foundation. We may take another set of axioms and start building all over from there. It just depends on a problem at hand which theory is better.

That said, i feel Lean and Agile are both very beneficial methodologies for the environment I’m working in, ant it’s really pity how badly they can be misinterpreted. (“You’re not following the plan! Can’t you be a little more agile?”, “Agile is total and thorough crap. Lean, that’s out thing!”)

2010-08-31

Making crap to hit deadline

Of course this works, and of course the other part (and then cleaning up the mess afterwards) doesn’t. If you have to clean things up afterwards, the only way is to sacrifice your own spare time.

I’ve never been allowed to do “code improvements” after feature perceivably works. “It works, go on with the next task! Can’t you see how far behind schedule are we?”. No one builds the perfect thing first time, and sadly I often find that my newborn code is not of high enough quality to be sufficiently maintainable. This is reality. I can write good code, but only when I spend some iterations improving it. I cannot make it good enough first time. Yes, it may be possible to do this, but only when working on familiar problem nth time. For instance good OO skills may do half the job, but what remains, the problem domain, and I don’t see a way to model it perfectly the first time.

I don’t want to work on the same damn problem for the nth time…

2010-05-24

C# Switch statement & enums

I wish i could write something like this:

void foo(MyEnum e)

{

  switch(e) complete

  {
    case MyOption1:

      bar(); break;

    case MyOption2:

      baz(); break;

  }

}

and expect compiler error is MyEnum also contains MyOption3. Of course, I can add

default: throw new Exception();

but this is not always appropriate when the code is not covered by automated tests. In my case, that’s how it is exactly. Some code similar to above is executed only on rare occasions, so there is little probability that the problem will be spotted by manual testing. And when it is in production, it would rather fail silently than throw unhandled exception.

Of course is is considered a bad practice to litter code with such switch statements everywhere, and bar() and baz() would better be virtual functions on polymorphic objects.

2010-05-17

Semi-Complex code

The codebase I am currently working on has some parts having as I call it, semi-complex logic. It has good names most of times, it adheres to reasonable coding standard, and it actually works. Well, most of time. However, it has copy-paste-alike constructs all around. There are lots of dead / redundant code. And each class has just too many responsibilities. This looks like a kind of code our developers seem to be happy with. Must be because they are most productive producing it. I too seem to be most productive when producing highly-entangled, low level of abstraction code. But in a few past years I settled to opinion that long-term qualities of code matter the most, event for small applications. And hence, nowadays I tend to write code I am not most productive writing, taking time to manage dependencies, eliminate duplication, extract methods. I’m still not that good at it, and of course no one appreciates it. But still I try…

What troubles me about this semi-complex code, is that it carries lots traits of bad code. Most notably, out-of-place dependencies. It suffices to have one wrong dependency, and soon inconveniences start to emerge. Like, having executable module link to seemingly unrelated one. And everyone seems to be OK with it, taking this as necessary evil. Another trouble point is that the code itself is easy to read, but it doesn’t mean you understand how it is working. Because responsibilities are not clearly separated, and some side-effects take place occasionally.

2010-04-27

Exception handling in ASP.NET MVC. Clear the output when returning error view

Today spent half a day figuring out why my error handling code sometimes returns “strange” view, as if error page was rendered inside partial view in which exception occured. Which by the way is exactly what was happening.

Exception handling looked like:

public abstract class MyController : Controller

{

//… other stuff

protected override void OnException(ExceptionContext filterContext)
{

    //log exception
    var exception = filterContext.Exception;              
    var model = new ErrorModel(exception);
    filterContext.Result = View("Error", "Site", model);
    filterContext.ExceptionHandled = true;

}

}

Until finally I found the fix:

public abstract class MyController : Controller

{

//… other stuff

protected override void OnException(ExceptionContext filterContext)
{

    //log exception
    var exception = filterContext.Exception;              
    var model = new ErrorModel(exception);
    filterContext.Result = View("Error", "Site", model);

    filterContext.HttpContext.Response.Clear();
    filterContext.HttpContext.Response.StatusCode = 500;
 
    filterContext.ExceptionHandled = true;

}

}