Dec 6, 2010

A cute quick colorpicker


Declarative user interface programming is slowly becoming a mainstream, being backed by technologies like WPF, JavaFX, Flex and others.

And now Qt is catching up with Qt Quick and QML.

While the basic ideas behind it are pretty similar to what we've already seen in those other technologies, there are several things which potentially can make it stand out, not the last one being the fact that Qt is open-source and multi-platform and that Qt Quick is naturally built on top of the solid, tried and true Qt Framework.

There is hardly a better way of getting the impression of some technology than just trying to make something functional with it, struggling your way through the documentation/examples and counting the number of hoops to jump through in the process.

So let's try and make a simple QML colorpicker control from scratch, just for the hell of it.

The first step is, obviously, downloading and installing Qt SDK (at the time of writing it was Qt Creator 2.0.1 with Qt Libraries 4.7.0). Run it and create a new QML project, named "colorpicker" (File-> New File or Project... -> Qt Quick Project -> Qt Quick UI -> Choose...).

After we're done, the final code can be found here.

Act 1

Scene 0

Enter Rectangle, Gradient.

It all starts with a simple square, filled with a white-red gradient (so it does not appear completely dull).

QML script essentially descibes a hierarchy of objects, with a single root element. Every object can have nested children objects, as well as a list of property values.

That's pretty common way of specifying what the UI's logical structure is (e.g. XAML does the same thing via XML with its tags and attributes). The "is" part here is essential, because that's where "declarative" comes from (as opposed to imperative code, which describes what something "does").

We make a Rectangle as a root element, tell that its "width" and "height" properties should be 120 pixels, and it's "gradient" property (which is by default a vertical gradient, from top to bottom) is itself a Gradient object, going from "white" to "red" color (those colors are in turn described inside GradientStop objects, its children):
import Qt 4.7
Rectangle {
    width: 120; height: 120
    gradient: Gradient {
        GradientStop { position: 0.0; color: "white" }
        GradientStop { position: 1.0; color: "red" }
    }
}
Pressing Ctrl+R will open the QML Viewer window, which would show the result.

Scene 1

Enter Rotation, Anchors, Blending, Color Notation.

Now, let's try to mimic the saturation/brightness picking area appearance. For that we take our red/white square, rotate it by 90 degrees, and blend a black square on top, with a gradient alpha.

Here we use an alternate color representation, as a string in a form "#RRGGBB" or "#AARRGGBB" (where, "AA" stands for "transparency", or "alpha").

We'll stuff both rectangles as children of a common parent object, an Item, which is a base visual object type in QML (all other types, including Rectangle, derive from it). It handles basic positioning and size, and also is often used as a lookless grouping container for other objects.

We'd explicitly specify the size only for this top-level object, and for the children rectangles use the "anchors.fill" property, which means "use the same size as some other object", the other object in this case being the "parent" object (in fact, here we see the first example of the property binding in action. Besides, the "." in the property name means that property is an attached property... but let's ignore these gory details for now):
import Qt 4.7
Item {
    width: 120; height: 120
    Rectangle {
        anchors.fill: parent;
        rotation: -90
        gradient: Gradient {
            GradientStop {
                position: 0.0; color: "#FFFFFFFF"
            }
            GradientStop {
                position: 1.0; color: "#FFFF0000"
            }
        }
    }
    Rectangle {
        anchors.fill: parent
        gradient: Gradient {
            GradientStop {
                position: 1.0; color: "#FF000000"
            }
            GradientStop {
                position: 0.0; color: "#00000000"
            }
        }
    }
}

Interlude

A bevel made with rectangles.

Continuing the rectangles topic, let's make a fancy "bevel", which could serve, for example, as a border for an edit box control.

Here we have a more intense usage of anchor-properties, margins in particular. Also, borders width and color for Rectangles, as well as corner radius.

The clip: true property is used to cut away right and bottom parts of the dark ("shadow") rectangle. Note, that the outermost rectangle here is used just as a background for our "bevel":
import Qt 4.7
Rectangle {
    color: "#3C3C3C"
    width: 80; height: 35
    Rectangle {
        x: 20; y: 10
        width : 40; height : 15; radius: 2
        border.width: 1; border.color: "#FF101010"
        color: "transparent"
        anchors.leftMargin: 1; anchors.topMargin: 3
        clip: true
        Rectangle {
            anchors.fill: parent; radius: 2
            anchors.leftMargin: -1; anchors.topMargin: -1
            border.width: 1; border.color: "#FF525255"
            color: "transparent"
        }
    }
}

Scene 2

Enter Custom Properties, Property Binding, Expressions.

I guess at this point everyone should be fed up with rectangles, so let's try something else.

Circles, for example. Let's try and make a visual representation for the cursor in the saturation/brightness area of the colorpicker.

So, we'll make our circles with... correct, with Rectangles.

The QML code here is pretty similar to the "bevel" example, with a new twist: custom properties.

We add our own new property to the root Item, and call it "r" (as in "radius"):
    property int r : 8
This will behave as a regular, existing property of the object (e.g. the "width" property) would. In this case, "8" will be a default value for the radius of our cursor.

Next, let's use this new custom property to turn the child rectangle into a proper circle:
       radius: parent.r
which means "keep the radius of this rectangle the same as the value of parents r property is".

What just happened here is called property binding (AKA "data binding") and is another cornerstone in declarative UI programming.

Property binding is a mechanism which keeps the values of certain properties in sync, i.e. when one property changes its value, then the corresponding bound property will update it's value automatically.

Furthermore, this value can be transformed ("converted") on the way. In QML this is done in a simple and elegant way, by using expressions, written in JavaScript language:
width: parent.r*2; height: parent.r*2
Here it means "keep the width and height of the object equal to be a double of the parent's r property". Expressions can refer more than one property from more than one object, in which case all of them get automatically "bound".

I must admit, WPF's converters and multiple bindings look quite a bit more awkward comparing to this... anyway, here's our cursor's code:
import Qt 4.7
Item {
    property int r : 8
    x: 50; y: 50; width: 100; height: 100;
    Rectangle {
        x: -parent.r; y: -parent.r
        width: parent.r*2; height: parent.r*2
        radius: parent.r
        border.color: "black"; border.width: 2
        color: "transparent"
        Rectangle {
            anchors.fill: parent; anchors.margins: 2;
            border.color: "gray"; border.width: 2
            radius: width/2
            color: "transparent"
        }
    }
}

Scene 3

Enter IDs, Grid, Repeater, Data Models.

What about some more rectangles?.. I knew you looked forward.

This time, though, let's organize them in a checkerboard pattern.

But first, let's mention that every object in QML object tree can have it's own "identifier", specified by the id property. This identifier can be used in property binding, so properties of one object get bound to properties of another object, referenced by its identifier. Here, we'll name the root object as "root":
    id: root
Next, let's combine a Grid element, which lays out its children in a grid with the given number of rows/columns, together with a Repeater element, which creates many similar objects based on two main parameters: visual template (specified as a child of the Repeater object) and data model.

Data model, generally, is a list of data items, each of them serving as an input context to the corresponding separate object created by the Repeater. In simpler cases (such as ours) it can be just a number, specifying how many copies of the object to create. The visual template can reference the property called index, which corresponds to the order of the item in the array.

We paint all the even elements gray and all the odd elements white, assuming, for the sake of simplicity, that the number of rows in the grid is always odd:
import Qt 4.7
Grid {
    id: root
    property int cellSide: 10
    width: 110; height: 110
    rows: height/cellSide; columns: width/cellSide
    Repeater {
        model: root.columns*root.rows
        Rectangle {
            width: root.cellSide; height: root.cellSide
            color: (index%2 == 0) ? "gray" : "white"
        }
    }
}

Act 2

Scene 0

Enter MouseArea, Signals, Inline JavaScript Code

Let's add some interaction now and make a circle, draggable with the mouse. For that we'll use a MouseArea element, which handles basic mouse tracking. One of the ways it does it is by receiving signals whenever certain changes in mouse status happen.

In this case particular signals of interest are onPositionChanged and onPressed, as we want to change cursor position in both the case when user clicks with the mouse and when the mouse cursor is dragged. The code, is going to be identical in both cases, so it looks like a good idea to put it into a separate JavaScript function (which we'll call "handleMouse"). The mentioned signals pass a MouseEvent object (named "mouse") with parameters describing the mouse status change ("x" and."y" corresponding to the current mouse position in particular).

Our helper JavaScript function can reside right in the scope of the MouseArea object (which makes this a kind of "custom method" for this object, somewhat similarly tho the custom properties case we've looked into earlier).

Additionally, the standard JavaSript Math module is used to clamp the cursor position to the area of interest:
import Qt 4.7
Item {
    width: 120; height: 120
    Item {
        id: pickerCursor
        Rectangle {
            x: -10; y: -10
            width: 20; height: 20; radius: 10
            border.color: "black"; border.width: 2
        }
    }
    MouseArea {
        anchors.fill: parent
        function handleMouse(mouse) {
            if (mouse.buttons & Qt.LeftButton) {
                pickerCursor.x = Math.max(0, 
                    Math.min(width,  mouse.x));
                pickerCursor.y = Math.max(0, 
                    Math.min(height, mouse.y));
            }
        }
        onPositionChanged: handleMouse(mouse)
        onPressed: handleMouse(mouse)
    }
}

Scene 1

Enter Components, Layout

Now, let's start putting things together.

Besides of the saturation/brightness picking area, we'd also like to have a couple of vertical sliders - one for hue and one for transparency. The only difference betwen them would be a background picture. I the case of hue slider it is a gradient of colors from the rim of the color wheel, and for the alpha slider it's a good old checkerboard with a black-white gradient on top. The vertical slider can be made in exactly the same way as the draggable cursor from the previous example, except it's limited to the vertical direction.

We don't really want to copypaste around the identical code for sliders, and that's where components come into play.

Components are reusable chunks of code (most often extracted into a separate file), and they serve as building blocks for Qt Quick application.

Let's create three separate files: ColorSlider.qml (the vertical slider component, used in hue and alpha sliders), SBPicker.qml (saturation/brightness picking box, with code from the earlier examples) and Checkerboard.qml (also familiar checkerboard rectangle) and put them inside the folder named, for example, "content". Our project starts to get some structure:



Note that component file names should start from a capital letter (CamelCasing is a common idiom here), and those names will be used to reference components from other code. A QML file can reference all the components, wich have files placed in the same folder. In our case, though, in order for the root file (colorpicker.qml) to use components from the "content" folder, we add the following line:
import "content"
This makes all the components from the "content" folder available inside colorpicker.qml.

Now that we can reference ColorSlider and SBPicker components, we'd like to arrange them horizontally. For that we use QML's Row element, which does exactly that:
// colorpicker.qml
import Qt 4.7
import "content"

Rectangle {
    width: 230; height: 200
    color: "#3C3C3C"
    Row {
        anchors.fill: parent
        spacing: 3

        // saturation/brightness picker box
        SBPicker {
            id: sbPicker
            hueColor : "green"
            width: parent.height; height: parent.height
        }

        // hue picking slider
        Item {
            width: 12; height: parent.height
            Rectangle {
                anchors.fill: parent
                gradient: Gradient {
                    GradientStop { position: 1.0;  color: "#FF0000" }
                    GradientStop { position: 0.85; color: "#FFFF00" }
                    GradientStop { position: 0.76; color: "#00FF00" }
                    GradientStop { position: 0.5;  color: "#00FFFF" }
                    GradientStop { position: 0.33; color: "#0000FF" }
                    GradientStop { position: 0.16; color: "#FF00FF" }
                    GradientStop { position: 0.0;  color: "#FF0000" }
                }
            }
            ColorSlider { id: hueSlider; anchors.fill: parent }
        }

        // alpha (transparency) picking slider
        Item {
            id: alphaPicker
            width: 12; height: parent.height
            Checkerboard { cellSide: 4 }
            //  alpha intensity gradient background
            Rectangle {
                anchors.fill: parent
                gradient: Gradient {
                    GradientStop { position: 0.0; color: "#FF000000" }
                    GradientStop { position: 1.0; color: "#00000000" }
                }
            }
            ColorSlider { id: alphaSlider; anchors.fill: parent }
        }

    }
}


Scene 2

Enter TextInput, Validators, Property Aliases

What we also want to have in our colorpicker is a textbox displaying the whole color in "#AARRGGBB" string format, as well as separate numeric boxes with H, S, V and R, G, B, A values.

Those numeric boxes, again, are all lookalike, so it's a perfect candidate for a new component.

The element, which in QML is used for a simple one-line text input, is called TextInput, and it has a few properties, specific to text editing - such as if text is selectable, what is the selection color, font properties etc.

One interesting property is validator, which has a function of allowing only input of a certain type from the user. DoubleValidator, in particular, only allows floating-point numbers in a specified range and with a specified number of digits after the decimal point.

So, the NumberBox component would consist of three parts: text input, caption text (drawn to the left of the text input), and a border around the text input.

External clients are not supposed to see the internal structure of a component, for them it's a black box with an interface. Property aliases is a convenient way of wiring certain properties of component's internal objects as a part of component's interface. For example, an internal Text component, which is used to display the NumberBox's caption, can have its "text" property "routed" to the component's interface without exposing the unnecessary details to client:
    property alias  caption: captionBox.text
The final number edit box component we place into a separate file: NumberBox.qml.

//  NumberBox.qml
import Qt 4.7

Row {
    property alias  caption: captionBox.text
    property alias  value: inputBox.text
    property alias  min: numValidator.bottom
    property alias  max: numValidator.top
    property alias  decimals: numValidator.decimals

    width: 80;
    height: 15
    spacing: 4
    anchors.margins: 2
    Text {
        id: captionBox
        width: 18; height: parent.height
        color: "#AAAAAA"
        font.pixelSize: 11; font.bold: true
        horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignBottom
        anchors.bottomMargin: 3
    }
    PanelBorder {
        height: parent.height
        anchors.leftMargin: 4;
        anchors.left: captionBox.right; anchors.right: parent.right
        TextInput {
            id: inputBox
            anchors.leftMargin: 4; anchors.topMargin: 1; anchors.fill: parent
            color: "#AAAAAA"; selectionColor: "#FF7777AA"
            font.pixelSize: 11            
            maximumLength: 10
            focus: true
            selectByMouse: true
            validator: DoubleValidator {
                id: numValidator
                bottom: 0; top: 1; decimals: 2
                notation: DoubleValidator.StandardNotation
            }
        }
    }
}


Note that this in turn uses another component, the bevel we already know: PanelBorder.qml.

And then the QML file for the details part of the colorpicker looks like this:
import Qt 4.7
import "content"
Rectangle {
    width: 100; height: 200
    color: "#3C3C3C"
    Column {
        anchors.fill: parent
        anchors.leftMargin: 4; anchors.rightMargin: 3
        height: parent.height
        spacing: 4

        // current color/alpha display rectangle
        Rectangle {
            width: parent.width; height: 30
            Checkerboard { cellSide: 5 }
            Rectangle {
                width: parent.width; height: 30
                border.width: 1; border.color: "black"
                color: "#AAFFFF00"
            }
        }

        // "#AARRGGBB" color value box
        PanelBorder {
            id: colorEditBox
            height: 15; width: parent.width
            TextInput {
                anchors.fill: parent
                color: "#AAAAAA"
                selectionColor: "#FF7777AA"
                font.pixelSize: 11
                maximumLength: 9
                focus: true
                text: "#AAFFFF00"
                selectByMouse: true
            }
        }

        // H, S, B color values boxes
        Column {
            width: parent.width
            NumberBox { caption: "H:"; value: "0.1" }
            NumberBox { caption: "S:"; value: "0.2" }
            NumberBox { caption: "B:"; value: "0.3" }
        }

        // filler rectangle
        Rectangle {
            width: parent.width; height: 5
            color: "transparent"
        }

        // R, G, B color values boxes
        Column {
            width: parent.width
            NumberBox {
                caption: "R:"; value: "255"
                min: 0; max: 255
            }
            NumberBox {
                caption: "G:"; value: "255"
                min: 0; max: 255
            }
            NumberBox {
                caption: "B:"; value: "0"
                min: 0; max: 255
            }
        }

        // alpha value box
        NumberBox {
            caption: "A:"; value: "100"
            min: 0; max: 255
        }
    }
}


We've used another layout element here, Column, which is a vertical version of Row.

Act 3

Scene 0

Enter Qt Source Code, JavaScript Modules

We have all the controls in place, and what is left is wiring them together with property binding. For that we need to have some ways of converting between QML's color values, "#AARRGGBB" text representations, as well as between hue/saturation/brighness/alpha and red/green/blue/alpha.

The original expectation was that QML would already provide the methods needed. Unfortunately, it turned to be not as straightforward. One of the problems, for example, is that when converting color value to string, the "AA" part in "#AARRGGBB" is for some reason omitted. The documentation regarding the QML color type is rather scarce at the moment.

But we have the source code, which is a kind of documentation on its own, given that one has time and desire to understand the internal workings of Qt Framework. Personally I do find this kind of looking inside the black box to be quite a useful experience, especially since Qt has generally nice code and architecture.

The source code can be conveniently browsed in the Qt Creator itself, by opening the "[QtSDK Folder]/src/src.pro" project.

Looking into the code confirms that current support for the color manipulation is indeed rather basic (not going beyond what documentation suggests), and problem with the color-to-string conversion appears to be a bug, as code does indeed just ignore the alpha component when composing the color string. Which basically leaves us on our own with the color conversion.

What we can do, however, is to write the corresponding utility functions ourselves, in a separate JavaScript file. So let's create a file named ColorUtils.js and add it to the "components" folder:
//  ColorUtils.js
//  Color manipulation utilities

//  creates color value from hue, saturation, brightness, alpha
function hsba(h, s, b, a) {
    var lightness = (2 - s)*b;
    var satHSL = s*b/((lightness <= 1) ? lightness : 2 - lightness);
    lightness /= 2;
    return Qt.hsla(h, satHSL, lightness, a);
}

//  creates a full color string from color value and alpha[0..1], e.g. "#FF00FF00"
function fullColorString(clr, a) {
    return "#" + ((Math.ceil(a*255) + 256).toString(16).substr(1, 2) +
            clr.toString().substr(1, 6)).toUpperCase();
}

//  extracts integer color channel value [0..255] from color value
function getChannelStr(clr, channelIdx) {
    return parseInt(clr.toString().substr(channelIdx*2 + 1, 2), 16);
}
There are many things which are wrong with this code, but hopefully its main purpose - to demonstrate the idea - is fulfilled.

One thing to note is that it uses Qt.hsla method, which is a built-in QML function for creating color value from hue/saturation/alpha/lightness values. As we use HSB space, not HSL, there is an additional conversion performed.

Now, to be able to use these utilities in our colorpicker.qml file, we add the following line:
import "content/ColorUtils.js" as ColorUtils
and refer to the utility functions as, e.g. "ColorUtils.hsba(hue, saturation, brightness, alpha);".

After that, we finally wire all the text in the numberboxes to the actual color value, the color in the saturation/brightness picking area to correspond to the current hue slider position, and the color/alpha display rectangle to be of the current color, which gives us the final version of colorpicker.qml.

Grand Finale

I've been fascinated with the idea of declarative user interface programming, even playing with that in a game development framework long time ago (quite ironically, my "JML" markup language from 2003 was pretty similar to QML).

The paradigm does indeed seem to improve productivity when developing user interfaces, and experience with QML in particular was that it's fun to learn and use.

There've been a few gotchas, however.

For example, I could not figure out how to emulate two-way property binding, that's why our colorpicker does not react on input in the edit boxes. While there might be an obscure way of doing this, it's not supported out of the box.

Also, the layout engine is rather flaky - e.g. margins do not seem to work as expected when using Row and Column containers, and in few cases I had to use direct property binding to simulate the desired layout behaviour.

There is no complex brushes and vector graphics, as one would see in WPF, etc.

However, there is also a plenty of strong points, which competitors lack, and those points are extremely appealing.

Let's wait and see where it moves. I sincerely hope that Qt Quick/QML will take a strong position eventually.

Apr 13, 2010

Learn yourself some innovation

Looking at today's programmer job positions, a lot of them, along with those usual lists of funky acronyms, include a somewhat confusing line: "strong problem solving skills."

To measure "amount of experience" in any concrete technology is already a tricky business, so how does one go with such an abstract thing as "problem solving ability"?

In software development there usually are many problems to solve, and for each of them there are many possible solutions. So it's not just about finding a solution, but rather about consistently picking the right solutions from many possible (and picking the right problems, for that matter). At this point we start talking about creativity and innovation.

The question is: is it possible at all to develop such a skill, in a deliberate way? Is this a personality trait, or intuition, experience, knowledge... or all of these?..

Turns out, people were trying to answer the question for ages. Socrates, Descartes, Poincare and many more researched the topic of creativity, innovation and problem solving, looking for answers to the same question: how good ideas are born in human mind?

The particular research which I've been poking into for a while, is called "Theory of Inventive Problem Solving" (aka TRIZ). The author, Russian inventor Genrich Altshuller, having worked in a patent office (it's interesting that Einstein had similar experience) and examined thousands of technical inventions, embarked on a task of finding some common traits in all these seemingly unrelated innovative ideas.

Essentially, he was reverse-engineering - first the good technical solutions themselves, and then mental processes, which could lead to such solutions emerging as an idea in one's head. And he came up with some core principles, building them later into his methodology, which managed to become quite recognized.

As with any good and recognized methodology which goes mainstream and gets the potential to commercialize (it's claimed to have been used at Xerox, Jonson&Jonson, Ford and other industrial giants), it eventually became somewhat complex and confusing, quite often being diluted with a snake oil (must...not...mention...agile...).

However, the core principles are simple and sound.

The first step is to understand the environment (system) in which problem is being solved. This includes building a mental model of what are the actors in the system, the useful (desired) and harmful properties of the system.

Furthermore, one should try to extend the boundaries of vision and see not just the system itself, but other interacting systems. Then, going even wider and seeing macro-level ("metasystems") and micro-level ("subsystems"). And not just that - all this should also be extended in time to the past and the future.

TRIZ claims that there are certain principles of technical systems evolution, and the need of inventions stems from the fact that some parts of the system are not developed in harmony with some other parts. This tension essentially creates the problems we are trying to solve.

At this point one is supposed to understand which exactly problem is tried to be solved, and thus this problem then gets reduced to a simple model. Essential part of this is about finding so called contradiction between two certain properties (parts) of the system. Note that real-world problems usually are not that straightforward - there can be more than single conflicting pair of system properties, but it's claimed that most of the problems can be decomposed to simpler subproblems which would satisfy that duality requirement.

The next thing to realize is the exact locality of the contradiction in time and space (when and where exactly the conflict does take place) - so called operating zone.

Then, solving the problem is essentially about overcoming the contradiction, but not in just any way - while doing that one should aim for so called ideal solution.

Ideal solution is another central principle in TRIZ. What we are trying to achieve should happen "on it's own", i.e. desired new property of the system should be achieved without modifying the system at all (remember "the fastest code is the one you never run"?..)

Now, it's obviously not always possible, and in practice one would end with some kind of compromise anyway. But the point here is to build a proper mental setup, which would divert mind from aiming at compromises prematurely.

To achieve this ideal solution we try to identify existing system resources and then employ them in some way. If there is no easy way - we may try transforming them first.

Particular resources and their transformations are subject of rigorous classification in TRIZ - there are tables, guidelines, principles which are built as the result of analysis of classes of existing good solutions. Some of those may be directly applied to the the software development as well (even though I am skeptical about attempts to map all of them). But what is more important here is another (rather obvious) principle: borrow existing good ideas.

For that to happen one has to build the awareness (implicit "knowledge base") about what good software ideas are already out there. No, it's not just about Design Patterns, even though they are certainly have some place in this awareness.

This proccess has iterative nature. One should be ready to "restart" the chain of thinking in the case that particular original model does not really lead to the desired solution. In this case it means returning back to analysing the system (subsystems, metasystems) and either building a different model, or even trying to solve different problem. It's also important to constantly reflect on own thinking process and especially on the solutions which are being found.

Now, just for an example of how this kind of thinking could map to the activity of problem solving in software development world. There was this wonderful talk, "Self and Self" by David Ungar, which I highly recommend watching.

He mentions about how the idea of generational garbage collector (today used in some form in the most of modern virtual machines) visited him when solving performance problems in virtual machine of Self.


There are some parallels to observe:


  • Memory usage/CPU conflict during garbage collection (two useful system properties conflicting with each other)
  • Exploiting skewed probabilities (identify and use existing system resources)
  • Optimize by eliminating work (ideal solution)
  • Optimize what's important (operating zone)
  • Garbage collection should happen to free the memory, and it should not happen because it is time-consuming (contradiction)
  • "Generations" - birth, getting old, dying ("little fellas" method)

  • I dare to speculate that there is a chance that aforementioned mental devices could lead to this idea. Even though it's a pure speculation, it's still interesting.

    According to the authors, TRIZ "works" because it helps to chunk the solution space and direct the mind of inventor towards good solutions, shifting the focus away from the "bad" ones.

    Metaphorically, if problem solving is a game (so one is picking the "best" move out of many possible), then TRIZ is probably something like alpha-beta pruning with heuristics. It reduces the amount of solutions to examine by cutting away the whole "bad solutions branches" when searching the game tree. Essentially, "the algoritm of invention" is nothing else as an attempt to heuristically optimize the huge solution space search, which happens in human mind:
    The conclusion is that in normal chess play, certain types of situation recur - certain patterns - and it is to those high-level patterns that master is sensitive. He thinks on a different level from the novice; his set of concepts is different. Nearly everyone is surprised to find out that in actual play, a master rarely looks ahead any further than a novice does - and moreover, a master usually examines only a handful of possible moves!

    The trick is that his mode of perceiving the board is like a filter: he literally does not see bad moves when he looks at a chess situation - no more than chess amateurs see illegal moves when they look at a chess situation. [...] This might be called implicit pruningof the giant branching tree of possibilities. By contrast,explicit pruning would involve thinking of a move, and after superficial examination, deciding not to pursue examining any further.

    Does it all mean that one can universally apply TRIZ or similar methodology to creatively solve programming problems?.. I don't really think so. Every person is unique in which mental processes work for them better.

    Still, the described principles, such as: refining the problem, finding the contradiction and bending it to extreme, looking for an ideal solution and trying to employ existing resources of the system (possibly transforming them), borrowing the ideas from existing great software solutions, fighting the psychological inertia - all of them can be useful regardless.

    I guess the process of developing one's own mental toolset is neverending and happens continuously through the career and life.

    And this is just another tool. Who knows, maybe it will find its place.

    Apr 2, 2010

    Getting a good habit, the easy way

    I consider myself an extremely unorganized person, which makes me sometimes wonder what the hell am I doing being a programmer.

    In software development, planning is an essential activity for getting the job done - something that I've learned the hard way - and personal traits must be essential in this regard.

    However, I've also learned that some of those traits can be actually gained with a bit of effort. Specifically, when we talk about habits, there are several mind exploits, which can be used to rewire the brain.

    Here's one particularly dead simple, nevertheless useful professional habit, which I managed to get during the last year: using ToDo list for everyday microplanning.


    As with any good habit, there are several things which can help:
    • should be simple to do, non-burdened with time-wasting activities
    • consistent, repeatable in a simple ritual-like steps 
    • providing positive feedback
    • have some triggering mechanisms  
    • be forgiving to yourself, no giving up early because of false starts
    • some kind of public commitment, even artificial one, can also help
    I use AbstractSpoon  ToDoList (it's really nice and free but Windows-only, unfortunately... however there are many Linux alternatives - the particular application does not really matter).

    There are some simple things to make its usage feel streamlined:
    • system-wide shortcut to toggle the application window quickly (Ctrl+Shift+T in my case)
    • it starts on system start and resides as an icon in the system tray
    • auto-saves on window losing focus
    • I use dropbox as a simple way to share the tasklist between different computers.
    I start every working day with a simple ritual:
    • open ToDoList with keyboard shortcut and create the new top-level task named by the current date (e.g. "30 mar").
    • look at the previous day's ("29 mar") undone tasks, and either move them to the new day, or to the special "Maybe Later" top-level task.
    • think about what else is to be done today (usually there is some higher-level issue tracking system, such as Trac or JIRA, which already has a list of issues assigned to me and can serve as a guide), and roughly populate "30 mar" with today's goals.
    • look into the "Maybe Later" box and consider if there's something that can be fetched from there for this day. Also, close those of the entries there which are not actual anymore.
    • the current day's goals should be pretty fine-grained (I feel more or less comfortable when there are around 10 of them, doable during the working day), but it's not necessary to go into all the details now, they can be refined later, when it actually comes to doing them.
    • assign priorities to all the entries (10 being the highest), and they get automatically sorted, topmost being with the highest priority.
    • close the task list and start working on the topmost task.
    During the day the shape of the list can change - and it's fine.
    Some new things may pop in, in which case they get dispatched correspondingly:
    • if it's an urgent emergency task, then it gets right to the top of the current task list, with the highest priority.
    • if it is something which needs to be done, but not necessarily today, then it gets into "Maybe Later" box.
    • if this is just a "nice to have" kind of thing, then it gets into the special "IDEAS" box, which is located below the "Maybe Later" one.
    • some tasks can happen to become obsolete during the day, then they just get crossed out.
    Also, priorities of the tasks can change during the day - I also consider it to be an expected phenomena.

    Whenever this "popping in", or any other kind of distraction (quite usual on the working place, unfortunately) happens, there is always this magical "what was I doing" keyboard shortcut, which helps to switch the context back and focus again at the task at hand.

    It did not work all that well from the first attempt, of course, but eventually I managed to get into this simple everyday rhythm and started to feel comfortable with it.

    There is this inherent sense of satisfaction in seeing several things crossed out at the end of the day, and being able to answer these simple, yet important questions: "what have I done today? is there anything exceptional about it? why not, exactly?"

    I believe that this manner of dispatching tasks somewhat resembles the Getting Things Done method.

    There are few "buckets" of prioritized tasks, which periodically get processed, with the "short term" bucket being a list of today's tasks.

    It's not exactly the same, of course. But perhaps I will try to follow the GTD method more closely, eventually.

    After all, it's just another useful habit to try developing. There is no harm in trying it, and no penalty if it does not work for me.

    Doing the impossible things (such as changing one's personality traits, for example) turns out to be not that hard - with a little bit of persistence and open-mindedness.

    Mar 17, 2010

    The Dragon Age of mainstream game scripting

    It's amazing how much depth great role-playing games can have to them. Some of the quests, which start as usual pre-canned in-game experience, can suddenly spill themselves onto higher layers of reality, sometimes in quite unanticipated ways.

    I had been enjoying Dragon Age: Origins for quite a while already, before I found myself engaged into one of such meta-quests, which I'd like to tell about.

    So, I went to Orzammar, the underground dwarven capital, where the "A Paragon of Her Kind" storyline subplot started to unwrap. There was quite intricate political struggle for the crown between two houses going on there, and apparently I was expected to eventually side with one of the parties.

    In quite a boilerplate way, the two emissaries were giving tasks to be fullfilled in order to prove the loyalty to either of houses. Apparently, it was also anticipated by the developers that player might want to try playing both sides in a double-agent kind of way, and that's what I've tried doing...
    just to find out that the whole plot got stuck into a logical deadlock, which turned out to be a bug. Of course, I did not have the recent save games to reload from (of course!), so I became disappointed and unmotivated.

    Luckily, Bioware released the Dragon Age Toolkit, which any owner of the game can download and use to modify the game to his taste. It's a great move from their side to have it released, which me and I believe a lot of other people really appreciate. So, I downloaded it, installed and digged straight into the scripts trying to find the place which could be patched to allow me keep playing.

    Long story short, I succeeded at hacking the game plot script and could enjoy the game again. It would be a perfect time for the happy end, perhaps, but the whole "fix the quest scripts to allow continuing playing the game" meta-quest spawned even new set of quests in different layers of reality.

    The first quest was about learning how the DA Toolset works, getting insight into the tools and workflow which developers used to produce this great game, examining its strengths and weaknesses. Very useful experience.

    But there was another thing, which somewhat stroke me. In the process of digging the scripts I've got the impression that the script code structure is quite a bit more complicated than it could be. The logical deadlock bug in the scripts, mentioned above, turned out to be not as surprising as one would expect, given that author had to anticipate the combinatorial explosion of all the many possible developments in the plot, and the language used for that did not seem helping much in that... and I wonder how much QA efforts and bugfixes  it needed before getting into the shippable state.

    This another meta-quest was about understanding the current state of higher-level game programming DSLs (aka "game scripting languages"), which in turn made me also sidetracked into such side-quests as trying to learn about the Prolog programming language, semantic networks and what else... but I digress.

    In case of Dragon Age, the scripting language has a simple C-like structure, and workflow in scripts is centered around events coming from the engine and other scripts.

    When it comes to the story development, scripts collaborate closely with the conversation editor, which is used to build the dialog trees (which are not actually trees, but rather DAGs, still represented in a tree view in the editor). Each branch in the dialog tree can be masked out by some global flag, as well as it can change some global flag if player picks this dialog branch in the conversation.

    This leads to the following patterns:
    • there is a rather extensive set of global flags, related to the given storyline. Sometimes these flags can be quite complicated (e.g. "A_HAPPENED_BUT_B_HAVENT_HAPPENED_YET_AND_PLAYER_DID_C")
    • when flag changes (triggered by the player picking certain dialog branch or for some other reason), it fires the event. Events are handled in the scripts, in rather big switch/case blocks.
    • every case block can have complex and nested conditions checks, which may change other flags as the result, for example enabling/disabling some other dialog tree branches.
    All in all, amount of bookkeeping-style code compared to the actual logic code seems to be incredibly high, and logic code itself is spread over different places, the code being heavy on side-effects.  And it's not due to the bad coding, obviously, but rather because of the traits of the scripting language and framework itself.

    It seems that one of the main criterias in picking the scripting language for game development still remains familiarity, which most of the time just means syntax familiarity.
    Familiarity is considered to be important, so that designers and generally people not having "extensive programming background" can use it without much problems.

    And I guess it makes sense. For example, in case of Dragon Age, majority of the scripts appear to be written by intern and fresh from the college folks (one can track the author names from the scripts themselves). Now, by no means I am trying to imply that it somehow correlates with the code quality - years of experience quite often mean nothing, and no doubt those people coming from college are brilliant. But I believe it still kind of shows the general attitude in the industry. Which is: "Game logic scripting is a beginner level, routine task".

    Still, the question arises: is this really the most productive level of abstraction to work with? Could be  low-level imperative manipulation with global flags and multiply nested blocks of if-then-else logic, giant case switches with side effects replaced with something which maps better into the domain area? Something, which would allow to do more complex, rich, interesting, emergent things without need focusing attention on the spaghetti logic and fighting the peculiarities of the scripting language?..

    Despite all the interest, research and developments in this area, it seems that on the industrial, mainstream level, the technologies which serve as the game designer's medium for creating the high-level game playing experience, remain grossly underdeveloped. But it would be unfair to call it "the stone age", of course. It is developing, albeit slowly. And, no matter what tools are used to achieve it, in the end of the day it's the end result which matters.

    Thus I dub the present as "The dragon age of mainstream game scripting".

    Jan 27, 2010

    Code opera: using Gource to watch a story of Perforce depot

    Gource is a neat open-source tool which allows to visualize dynamics of source code repositories, using a planar, spring-based tree layout ("balloon tree").

    Showing P4 depot
    Why being interested in Perforce in particular - a proprietary, non-free (and rather expensive) software?.. For a couple of reasons:
    * It's quite commonly used in a big, corporate software shops (including the one I am working at), and still theoretically can be used in open software projects, for free (as in a beer)
    * Gource does not seem to have an official support for it yet (it supports Git/Mercurial out of the box, and SVN/CVS via contrib Python scripts)

    As an example we can check Adobe Source Libraries:
    export P4PORT=stlab.adobe.com:10666
    export P4USER=guest
    echo "AdobeGuest" | p4 login
    perl gource-p4.pl //adobe_source_libraries/ > gil.log
    gource --log-format custom gil.log
    (it may take a little while to gather the log file).

    Another example is Jam (open-source build system) depot. This time in Windows command line:
    p4 set P4PORT=public.perforce.com:1666
    p4 set P4USER=anon
    p4 login
    perl gource-p4.pl //public/jam/src/ > jam.log
    gource --log-format custom jam.log
    The gource-p4.pl script looks like this:
    #!/usr/bin/perl
    
    $root = $ARGV[0];
    map { my($change, $user) = $_ =~ /Change (.*) on.*by (.*?)@.*/;
        map { my($file, $act, $time) = 
                $_ =~ /$root(.*)\n.+headAction (.*)\n.+\n.+headTime (.*)\n.*/; 
            $act =~ s/edit|integrate|branch/M/; 
            $act =~ s/delete/D/; $act =~ s/add/A/; 
            $line = $time."|".$user."|".$act."|".$file."|\n";
            print $line if $file;
        } split(/\.+ depotFile /, `p4 fstat -e $change $root...`);
    } reverse split(/\n+/, `p4 changes $root...`);


    Granted, both examples of open-source Perforce depots visualizations do not look very exciting, because neither of them seems to be a primary development depot, and most of the commits are done by a few maintenance people.

    However, I've also tried it at the company where I work, watching one-year's worth evolution of the main code branch, and that was quite insightful.

    Gource also allows to supply a folder with images to be used as user portraits, which adds personality to the show, so I used that as well.

    Stories in code
    And I was quite amazed with what I've seen: the code tells stories.

    To an outsider it might look like just a boring pictures flying around and zapping with lasers some colored circles tagged by the file names.
    And generally that's the way how it is - plain boring. Boring when observed out of the context, that is.

    And even if one of those flying pictures was myself, I was quite under-impressed at first.

    But then small stories began to pop in my head:

    "Oh yes, I remember that refactoring when part of public API was renamed and it triggered the chain reaction..."
    "Here, ... Bill integrates his branch to ours"
    "Oh, he found the reason for that bug everyone was puzzled about... see, three seemingly unrelated folders were changed to fix it"
    "We have quite an activity of people working at the same on that clump of files, maybe we should improve modularity there?.. and then some people have to touch too many different files at once, it seems... could it be bad cohesiveness of code?"
    "Yeah... there, Peter makes that commit with funny comments we laughed at all together"
    "Right... Christmas. No commits, obviously... And then, see - what a rush! People fly around like crazy, apparently having a few days off was a good idea"
    "And here Mark and Frank are working on that new API together... it's nice to see an activity in the unit tests' folders"
    "Oh, see, John have just committed his new system there, in that new tidy bunch of files... cool stuff, he knows his job... surgical changes"
    "Ah, that... such a pity we had to revert that... And now - ha-ha, see, Brandon started to fly around like crazy, such a productivity again, huh?.. What was that? A new girlfriend or something?"

    And so on.

    That really reminds me the topic of emergent storytelling in games, when players create their own stories and enjoy them:
    Human beings like stories. Our brains have a natural affinity not only for enjoying narratives and learning from them, but also for creating them. In the same way that your mind sees an abstract pattern and resolves it into a face, your imagination sees a pattern and resolves it into a story.
    Games have always had a close affinity with story-making. Adding a few lines of description to a video game or a background and artwork to an abstract board game gives dramatic context and an added sense of depth, allowing the player to create an internal narrative as the game progresses.
    (from "Second Person: Role-Playing and Story in Games and Playable Media")

    Here it's not a game, but rather a meta-game of a kind (it's quite ironic that this is rather a process of making a game in this particular case, because I work in a game development company). There are still quite a few parallels, it seems.

    Quite frankly, Gource provides only the most basic display. It does not tell too much about the code structure and how well different areas of work are factored between different contributors (even though quite often well-though folder structure is a sign of overall good code organization).

    But I can imagine even more narrative devices added, for example:
    * Fetching the information from the continuous integration system and display some crazy particle explosions when build was broken
    * Doing similar, but even more intense display when automatic regression tests were broken
    * Integrate with bug tracker, and give some visual cues about the nature of work being done (bugs, regressions, crashes, new features)
    * Visually tracking the physical code dependencies as well (like #include graphs in C++) and their evolution

    I believe all this is can be useful in a practical sense as well.
    It seems that entertaining things generally have bigger cognitive potential. Andy Hunt tells in "Pragmatic Thinking&Learning":
    ...In fact, additional studies have shown exactly that: positive emotions are essential to learning and creative thinking. Being "happy" broadens your thought processes and brings more of the brain's hardware online.
    Aesthetics make a difference, whether it's an user interface, the layout of your code and comments, the choices of variable names, the arrangement of your desktop or whatever.
    Nice things matter, especially if they provide a useful view, yet another mental projection upon the code base, which allows to extend one's mental models of this code in a fun, aesthetically pleasing way.

    Work should not necessary be boring.

    So what?..
    From the practical perspective, one quite satisfying thing to me was that such generally useless one evening exercise gave me quite a bit of awareness about several (seemingly unrelated) things:

    * Reading the source code of Gource (C++), compiling and running it both on Linux and Windows
    * Making up somewhat artificial problem in this context (how to use it with Perforce) and figuring out what steps can be taken to solve it
    * Getting to know a little bit of Perl (yes, this is my first Perl script ever... it must be quite obvious from the code, anyway), while solving a real-life problem
    * Trying to do it in a (somewhat) functional programming style
    * Improving my regular expressions skills
    * Getting to know a bit of p4 command line interface, again while solving a real-life problem
    * Getting some insight about the Adobe GIL and Perforce Jam open source code bases
    * Using Gource to visualize evolution of the code base at the company where I work.
    * Reflecting on it

    I am certainly not sure if regular solving of such small artificial problems (and learning a few random things while doing that) make you a better developer or something.
    Perhaps it does. But if it does not - who cares?..
    It was fun, after all.