Monthly Archives: April 2015

How the Cursor Learned to Move

While implementing the new box model for Vex, I came to the point, where I needed a representation for the cursor. I started with a very simple class that knew how to draw the cursor at a given offset. That’s easy to understand, one simple responsibility in one class: SRP check!

But then there happend what always happens when you have a simple and elegant solution in place: there was a new requirement: I needed the ability to move the cursor. Just add that damn feature

The first idea could be to add new methods to Cursor in order to extend Cursor‘s behaviour. The cursor should move, then let’s add move methods for that.

I know this is too easy and you don’t want to go for this solution. But I also know that there was a time where this would have been the only solution I would have seen. So I will at least mention here why it is not the solution to go for, just for the case.

Moving is a whole new responsibility for the Cursor class, that has nothing in common with the already existing responsibility of painting. And, there are a lot of different kinds of movement: left/right, up/down, page up/down, one word forward/backward, just to name a few.

Adding just new methods for each distinct movement will clutter the small elegant Cursor class. It will make the class harder to understand. It will lower the inhibition to add further features, which will make the class even harder to understand and in the end we have a Big Ball of Mud, a God Class or however you would call that mess.

There has to be a better solution.

Separate responsibilities

The SRP and “Composition over Inheritance” lead to another approach: put all the movement implementations into a separate class that takes the responsibilty for moving the cursor. This will leave the Cursor class as it is, isolating it against changes that are related to movement, which also makes the OCP happy – at least in this regard. So let’s try it and call this class CursorMovement for the further discussion.

When starting with the implementation of CursorMovement, it is clear very soon, that this approach also has some flaws. The different kinds of movement need different information about the current cursor position:

For left/right it is sufficient to know the current offset, because moving left or right is just a matter of decreasing or increasing the offset.

Moving the cursor in vertical direction requires detailed information about the spatial relation of boxes and the current graphical representation of the cursor. Having the implementation of the movement outside of the Cursor class means that this information somehow has to be made available through Cursor‘s public interface. This leads to a very tight coupling between Cursor and the CursorMovement class.

The need for access to the graphical representation revealed another flaw that was already there in the first approach. Information provided by the graphic framework (e.g. font sizes, text length in pixels) is only available during painting (see Double Buffering in SWT for more details), but the cursor movement is triggered by a key stroke – totally independent of the painting. To solve this in a clean way, vertical movement has to be postponed until the next paint event.

Content-related movement (e.g. one word forward/backward) requires information about the textual content of the document, totally independent of the graphical representation. This adds another dependency from CursorMovement to a new, so far unrelated entity.

All in all there is no cohesion in CursorMovement and no reuse of code. The class simply piles up unrelated methods and dependencies. We had this already. Together with the unsolved temporal dependency between the graphical information and the paint event, we can come to the conclusion that this approach is also not suitable.

At this point there are a lot of indicators that something is wrong, but it is difficult to see the way out of this. Some impulse from outside might be helpful.

Solutions have to be simple in order to work

Rich Hickey’s talk “Simple Made Easy” gave me this impulse: queues are simple and a great way to do temporal decoupling. This is the missing part in the puzzle. Now the solution is really straight forward:

  • We put each single move into its own class, implementing a simple functional interface (ICursorMove).
  • When triggered by the key strokes, those move instances are added to a queue in Cursor.
  • After adding the move to the queue, also a redraw of the widget is triggered.
  • In its paint method, Cursor first applies the queued moves and then does the actual painting.

This use of (some variant of) the command pattern in conjunction with the queue solved most of the problems:

  • The access to internal data of the Cursor class is restricted to the call of the execution method of the move implementations. No need to provide data through the public interface of Cursor.
  • Each move implementation can have only the dependencies that are needed. Dependencies of a certain kind of move are more explicit.
  • There is no single class that piles up unrelated move implementations and dependencies.
  • Moves are executed within the paint handler, this resolves the temporal dependency between the move and the availability of information from the graphic framework.
  • Adding new moves is just a matter of adding new classes, no changes in existing classes are required. It is even possible to have an extension point which allows other bundles to provide special move implementations for certain document structures (e.g. semantic tables).

Conclusion

It really pays off to know about clean code development. If you listen to your code and you are able to understand the signs, it will always show you the way to a better solution.

If you interested in more details about the implementation, just have a look into the package org.eclipse.vex.core.internal.cursor in Vex’s git repository.

Double Buffering in SWT

To draw the contents of a custom widget in SWT, you have to implement a PaintListener. The paint method is the only place where you have access to the widget’s GC (aka “Graphic Context”), which provides the actual drawing methods.Paint events are handled in the Display thread. This means, the UI is not responding while you are drawing. If you do complex calculations while drawing, this results in flickering.

To prevent this flickering and to keep the UI responsive, the usual approach is to use double buffering: you use two buffers, one is used for drawing and one is visible. When you are finished with drawing a complete frame, you swap the two buffers: the buffer for drawing is now visible and vice versa.

In SWT, you don’t have an explicit buffer you are working on, but you have the GC which provides the methods to manipulate the contents of the buffer. You get the GC instance for your widget visible on the screen as part of the PaintEvent that is provided to the paint callback method. To obtain an independent GC for drawing, you have to do a little trick: create an Image with the size of your widget. For this Image, you can create a GC instance which is usable independently of the UI thread.

Putting all pieces together, you use two Image instances which are used alternating for drawing and showing. The paint callback method just draws the one image that is currently used for showing to the GC of the widget.

SWT snippet 48 shows a basic version of this approach. For Vex, I started to implement a more gerneral version, applicable to Scrollable instances, that uses a dedicated rendering thread for drawing: the DoubleBufferedRenderer.

DoubleBufferedRenderer

The DoubleBufferedRenderer handles the paint events for an instance of Scrollable using double buffering as described above. It allows you to schedule a list of IRenderStep instances, a simple functional interface to implement the distinct steps of your drawing logic, that depend on access to the GC.

Internally, the execution of the render steps happens in a dedicated rendering thread. When all steps are executed, a redraw of the widget is triggered. The finished Image is then used in the paint callback method until a new image is ready.

Usage

Example: When the control is resized, we have to layout the content and paint it. Therefor we schedule two IRenderStep instances:

renderer.schedule(layoutContent(), paintContent());

To make it more readible, I put the creation of the IRenderStep into factory methods, which return an anonymous implementation:

private IRenderStep layoutContent() {
   return new IRenderStep() {
     public void render(final Graphics graphics) {
       rootBox.layout(graphics);
       cursor.reconcile(graphics);
       updateVerticalBar();
    }
  };
}

The anonymous class looks cumbersome. In Java 8 this can be expressed in a much more elegant way, but unfortunately the Eclipse platform is still on Java 6.

For more examples of how DoubleBufferedRenderer can be used, you should have a look at the implementation of BoxWidget.

Outlook

This all is still work in progress. For example the schedule method does not queue the lists of IRenderStep instances, it just knows about the currently executed list of steps and the following list of steps. Each call to schedule overwrites the latter.

Also the usage of threads is still very ineffective. If you have multiple widgets, each using its own instance of DoubleBufferedRenderer, each one will run its own thread. Using a thread pool or more sophisticated techniques will help here.

If you still want to give it a try, there is one dependency to Vex that you have to be aware of: IRenderStep provides an instance of Graphics, an abstraction of the graphics framework in use. For use outside of Vex, you can just replace this with an instance of GC.

The Maintenance Analogy

In engineering, maintenance means to tear a machine apart, clean it, replace broken parts, oil it and put everything together as it was before. Maintenance is needed to ensure the longevity, the quality of service and also the safety of a machine.

Some people say, that this is not needed for software. Bits do not wear out or break and bits do not need recurrent lubrication. You know what: they are right. This is not what happens in software development. But, as with many other analogies in software development, it is not that easy. You have to think about the goal of maintenance instead: make sure that the software is useful for a long time. Useful means in terms of software, that you are able to change the behavior of the software, either to fix bugs, or to react to changes in the requirements of the software.

Some people say, if you practice clean code development with due diligence, the software is always in shape for changes. But concepts, structures and algorithms wear out over time. When requirements change, the existing implementation does not fit anymore. The many small changes that accumulate over time dillute the original architecture. While the code in detail might be in perfect clean shape, the bigger picture will show some flaws after a certain period.

Some day you will come into the situation where you have to take apart your application and replace some of its parts with better fitting implementations. This is for sure. The problem most of the time is to realize this situation and actually do what is necessary instead of taking a shortcut. And this is the secret of successful software maintenance. Its not about fixing bugs and adding new features until a single change is more expensive than writing everything from scratch. Its mainly about doing those changes that keep the big picture in shape. Its about being able to fix bugs and add new features forever.

By the way: having clean code makes maintenance much much easier, because you only have to take care of the big picture’s shape. If you don’t do clean code development, start now! No really, do it! Now!