Apathy, Apples and Understanding

You may notice that it's been a long time since my last post. Truth be told I've been lazy. It's tempting to say that I've been busy, but that's a sugar coating on apathy. For that I apologise! Hopefully I can get back into the habit of regular posting again soon.

Inspiration struck the other day when Jeff Atwood posted an interesting article on his blog. "Dealing With Bad Apples" talks about how single members of a programming team can be difficult, often working against the rest of the team.

Atwood quotes Robert Miesen:

I was part of a team writing an web-based job application and screening
system (a job kiosk the customer called it) and my team and our
customer signed on to implementing this job kiosk using Windows,
Apache, PHP5, and the ZendFramework -- everyone except one of our team
members, who I will refer to as "Joe". Joe kept advocating the use of
JavaScript throughout the technology deliberation phase, even though
the customer made it quite clear that he expected the vast majority of
the job kiosk to be implemented using a server-side technology and all
the validation should be done using server-side technology.

The fact that the customer signed off on this, however, did nothing
to deter Joe from advocating JavaScript -- abrasively. Every time our
project hit a bump in the road, Joe would go off on some tirade on how
much easier our lives would be if we were only writing this job kiosk
in JavaScript. Joe would constantly bicker about how we were all doing
this all wrong because we weren't doing it in JavaScript, not even
bother to learn the technologies we were actually using, and, whenever
fellow teammates would try and gently bring him back into the fold
(usually via email), Joe would just flame the poor guy. At the height
of Joe's pro-JavaScript bigotry, he would regularly belt off comments
like, "Well, if we had only done it in JavaScript," to such an extent
that the team would have been better off if he had just quit (or was
reassigned or fired.)

Jeff then goes on to suggest that perhaps the problem here is a "bad apple" - a team member that is doing more harm than good in a team. He's probably right, but I have a slightly different angle.

Perhaps the real problem here is poor team leadership / management? Without meeting "Joe" personally, I cannot make any accurate assessment of the situation, but it seems to me that perhaps Joe feels undervalued in his team? I say this because i recognize that behavior pattern - in myself.

In any team of programmers, each member will have different backgrounds, strengths and weaknesses. Joe obviously has experience using Javascript, and feels the need to share his expertise in that field. I'm not saying that this is a good thing, but perhaps the underlying problem is a lack of cohesion and understanding between team members?

So, further to Atwood's list of warning signs for detecting "bad apples", I have a list of actions team leaders could consider taking when dealing with a so-called "bad apple":
  • Listen to them. Most geeks (I use the term with all possible affection) are reasonable people. If a team member is repeating themselves, perhaps they feel that their point was never seriously considered in the first place? I can't count the number of times I've made contributions in meetings that were ignored, only to hear (usually six weeks later) "hey, we should have done X, what a pity it's too late now...". It always seems petty to point out that I suggested X from the start. Bear with me here - I'm certainly not suggesting that I'm always right - far from it; my point is that you ignore contributions from your team members at your own risk!

    Finally, I'm not suggesting that team leaders always act on suggestions from their team members, but listening is a good start.

  • Once you start listening to bad apples, you may find that some of your team members have strengths you didn't expect. Can you use these strengths in the future? This depends a lot on your business model and workload. From my own experience I can understand that programming code that doesn't interest you week in - week out can be incredibly draining. Perhaps bad-apples can be encouraged to pull together with the team?
  • Finally - I don't know what the IT job market is like where Jeff lives, but you can't fire programmers and expect to get a replacement any time soon. Jeff writes:

    You should never be afraid to remove -- or even fire -- people who do not have the best interests of the team at heart. You can develop skill, but you can't develop a positive attitude.


    I say "bollocks" to that - it's incredibly expensive to fire and replace someone. Not only is there the cost of looking for, and hiring someone new, but there's the training overhead, and there's no guarantee that you can find someone with the appropriate skill set any time soon. From where I'm sitting it looks like we have to wait around 6-8 weeks between looking for, and hiring a new programmer. That's almost two months of productivity down the drain! Suggesting that you can't develop a positive attitude in your team-members is incredibly negative and close-minded. I'm certainly glad I'm not on a team with a leader like that!


That said and done, I do hope that the current skill shortage in this country develops a greater appreciation of the worker. I suspect that most companies vastly underestimate the value of their skilled (and unskilled) workers.
Next time you have a problem with someone, consider the massive cost of replacing them, and - more importantly - consider the huge amounts of good work they've done, before you concentrate on the bad.

Masters of the big buildup

The Foo Fighters are the masters of the big buildup. Listen to a track like "Let it Die" from their album "Echoes, Silence, Patience and Grace" - Brilliant!

QtScript: Exposing C++ classes (part two)

This is the second part of my QtScript walkthrough / tutorial. You can read the first part here.

As in the last tutorial, I must add the following disclaimer:

I'm writing these posts as I learn to use the QtScript module. As such, the solution I present here may not be the best / most elegant way of doing things. However, if I find a better solution, I'll certainly post back here in the future with corrections.

If there's any (QtScript-related) topic you'd like me to write about in the future, just leave a message and I'll endeavor to fulfill your request.

Background:

The last post was all about deferring some execution from a C++ class to an ECMAScript. The basic idea was that the C++ class could emit signals, zero or more of which were connected to functions in the script file. The script file set up these connections, so the the C++ code doesn't need to know which signals are being overridden, and which aren't.

This is all well and good, but you'll soon find that there's very little you can do in the script file, since the only functionality you have available is the builtin ECMASCript functions.What I'm going to look at today is how to make your own, and Qt classes available for use in the script file. In my example, I'm going to make the QMessageBox class available, but you can choose any other method you want.


Take 1:

First off, I want to be able to write "mb = new QMessageBox;" on my script, and have it work. This is actually pretty simple to achieve. The way I have chosen to do this is with a wrapper class. This wrapper derives from QMessageBox and QScriptable, and contains the magic "qscript_call" method. Here's the code:


// wrapper around QMessageBox:
class Wrapper_QMessageBox: public QMessageBox, protected QScriptable
{
Q_OBJECT
public:

Wrapper_QMessageBox(QWidget *parent =0)
: QMessageBox(parent) {}

public slots:
QScriptValue qscript_call(QWidget *parent = 0)
{
QMessageBox * const iface = new Wrapper_QMessageBox(parent);
return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
}
};


This is the complete wrapper so far. Note that normally I wouldn't write all this code inline, as I firmly believe that inline functions are evil, but for demonstration code I think this makes it more readable. As you can see, we inherit from QMessageBox and from QScriptable. Note the protected inheritance! QScriptable gives us the engine() call we need later on.

The constructor is pretty straight forward - no surprises there!

Then we have a special slot called "qscript_call". This seems to be an undocumented feature in Qt, (try searching for qscript_call on google and you get very few results). Essentially, this slot gets called when our wrapper class is called as a function. I guess this is similar to the meta-method "__call__" in python. All we do in this slot is make a new instance of the wrapper class (remember that our wrapper class is a QMessageBox as well), and return it.

Our wrapper class still isn't available in the scripts however. In order to do that, we need to add this one line of code:


m_pEngine->globalObject().setProperty("QMessageBox", m_pEngine->newQObject(new Wrapper_QMessageBox, QScriptEngine::AutoOwnership));




This one line adds our wrapper class to the script global object. Once you've done this, you can no create QMessageBox instances from within a script file, like so:


mb = new QMessageBox();
mb.text = "Test!";
mb.exec();



However, there are still a few issues left to resolve:
  1. We can only use the default - empty constructor.
  2. Only properties and slots of the QMessageBox are available from the script. For example, there's no way to set the window title text<> right now. If we could use the overloaded QMessageBox constructor that took the window title as a parameter then we could just specify it at creation time, but we'll need a way to export non-slot methods as well.
Let's tackle these issues one at a time:

Adding Overloaded Constructors:

This one's pretty simple. All you need to do is add another constructor that takes the additional parameters, and passes them up to the QMessageBox class. Then, you overload the qscript_call method in a similar fashion. Here's what my class looks like now:


// wrapper around QMessageBox:
class Wrapper_QMessageBox: public QMessageBox, protected QScriptable
{
Q_OBJECT
public:

Wrapper_QMessageBox(QWidget *parent =0)
: QMessageBox(parent) {}

Wrapper_QMessageBox(Icon icon, const QString & title, const QString & text, StandardButtons buttons = NoButton, QWidget * parent = 0, Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint)
: QMessageBox(icon,title,text,buttons,parent,f) {}

public slots:
QScriptValue qscript_call(QWidget *parent = 0)
{
QMessageBox * const iface = new Wrapper_QMessageBox(parent);
return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
}
QScriptValue qscript_call( Icon icon, const QString & title, const QString & text, StandardButtons buttons = NoButton, QWidget * parent = 0, Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint )
{
QMessageBox * const iface = new Wrapper_QMessageBox(icon,title,text,buttons,parent,f);
return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
}
};


You can now call this new constructor straight from your script file, just as you could earlier!

Exposing Additional Methods:

Finally, we need a way to expose arbitrary methods that are not slots in our base class. This is pretty simple. We make our own method with the same name, and call into the base class method with the parameters passed to us. Consider my wrapper class, now that I have exposed the setWindowTitle method:


// wrapper around QMessageBox:
class Wrapper_QMessageBox: public QMessageBox, protected QScriptable
{
Q_OBJECT
public:

Wrapper_QMessageBox(QWidget *parent =0)
: QMessageBox(parent) {}

Wrapper_QMessageBox(Icon icon, const QString & title, const QString & text, StandardButtons buttons = NoButton, QWidget * parent = 0, Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint)
: QMessageBox(icon,title,text,buttons,parent,f) {}

public slots:
QScriptValue qscript_call(QWidget *parent = 0)
{
QMessageBox * const iface = new Wrapper_QMessageBox(parent);
return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
}
QScriptValue qscript_call( Icon icon, const QString & title, const QString & text, StandardButtons buttons = NoButton, QWidget * parent = 0, Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint )
{
QMessageBox * const iface = new Wrapper_QMessageBox(icon,title,text,buttons,parent,f);
return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
}
void setWindowTitle ( const QString & title )
{
QMessageBox::setWindowTitle(title);
}
};


Simple!

Conclusion:

Combined with my earlier post, this should be all you need to make a Qt application extensible through ECMAScript files. I'm doing all this work to write a small game, but the techniques covered should work for all types of projects. If / When I find anything that requires updating, I will endeavour to update these posts. Since I'm still learning QtScript myself, I'm sure these pages will be filled with innacuracies.

How to make C++ classes available in QtScript

It's been a while since I posted here. What have I been doing? Mostly working, and in my spare time trying to get my head around QtScript. What follows is a short introduction into QtScript. I'm sure that there are points of inaccuracy in this post - this is only to be expected, since I'm just starting out.

What I need for my game, is a single C++ class that can defer some of it's processing to a script, thereby changing the behavior of the class. For example, I want a "GameObject" class, that takes a script filename as a constructor parameter, and defers certain parts of the processing to the script. In the case of the game object, I may want to defer the following functionality to a script:

  • Graphics loading (so different game objects look different).
  • AI processing.
  • Generic event handling.
However, not all scripts will do all of the above - some may only customize a very small amount.

The easiest way to do this is to have signals in the C++ class, that the script can choose to connect to (or not, as the case may be). As the C++ class is executed, it can emit these signals, and the corresponding slots in the script file can be called.

The Code

The C++ code is relatively simple. Consider the following header file:


#ifndef TESTSCRIPTOBJECT_H
#define TESTSCRIPTOBJECT_H
//
#include <qobject>
#include <qscriptvalue>
#include <qscriptable>
#include <qscriptengine>
#include <qmessagebox>
//

class QScriptEngine;


//
// Test script object class - used to demonstrate the fundamentals of QtScript.
//
class testScriptObject : public QObject
{
Q_OBJECT
public:
// ctor for this class - pass in the script engine to bind to.
testScriptObject( QScriptEngine *pEngine, QObject *parent =0);

// attach ourselves to a script file - this could be done inside the ctor. I
// have chosen to use a separate method instead.
void runScript(const QString &strProgram);

signals:
// test signal - we can emit this, and have some QtScript code run.
void signal1();

public slots:
// test slot - just displays a message box.
void slot1();
// second test slot - displays the string in a combo box.
void displayMsg(QString strMsg);

private:
// store a pointer to the script engine.
QScriptEngine *m_pEngine;

// store the "this" object, so we can manually call script functions if we need to.
QScriptValue m_thisObject;
};
This should all be fairly easy stuff. If it's not, you should probably look at the Qt tutorials before going any further.

Before we can use this class in any sensible manner, we need to do two things:
  1. Create a QScriptValue object that represents the "this" pointer. We do this so that we can call a script function, and pass it the C++ class object as "this" (we'll see this later).
  2. Open a script file and execute a "create" function, the contents of which will set up any signal / slot connections we require.
Let's dive into the C++ code, and take a look at the constructor for the above class:


testScriptObject::testScriptObject( QScriptEngine *pEngine, QObject *parent)
: QObject(parent),
m_pEngine(pEngine)
{
// create this object in the scripting land:
m_thisObject = m_pEngine->newQObject(this);

}
This is also pretty simple - the only line of any significance is the one where we create "m_thisObject".

Now on to step 2 - running the script file. Let's take a look at the runScript method:


void testScriptObject::runScript(const QString &strAppName)
{
QFile file(strAppName + ".js");

if (! file.exists())
{
QMessageBox::critical(0, "Error", "Could not find program file!");
return;
}

if (! file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox::critical(0, "Error", "Could not open program file!");
return;
}

QString strProgram = file.readAll();

// do static check so far of code:
if (! m_pEngine->canEvaluate(strProgram) )
{
QMessageBox::critical(0, "Error", "canEvaluate returned false!");
return;
}

// actually do the eval:
m_pEngine->evaluate(strProgram);

// uncaught exception?
if (m_pEngine->hasUncaughtException())
{
QScriptValue exception = m_pEngine->uncaughtException();
QMessageBox::critical(0, "Script error", QString("Script threw an uncaught exception: ") + exception.toString());
return;
}

QScriptValue createFunc = m_pEngine->evaluate("create");

if (m_pEngine->hasUncaughtException())
{
QScriptValue exception = m_pEngine->uncaughtException();
QMessageBox::critical(0, "Script error", QString("Script threw an uncaught exception while looking for create func: ") + exception.toString());
return;
}

if (!createFunc.isFunction())
{
QMessageBox::critical(0, "Script Error", "createFunc is not a function!");
}

createFunc.call(m_thisObject);

if (m_pEngine->hasUncaughtException())
{
QScriptValue exception = m_pEngine->uncaughtException();
QMessageBox::critical(0, "Script error", QString("Script threw an uncaught exception while looking for create func: ") + exception.toString());
return;
}
// now emit our test signal:
emit signal1();
}
Again, this is all pretty simple stuff. This method does the following:
  • Looks for, and opens the script file specified.
  • Does a static check of the code (makes sure that it's syntactically correct, but does not ensure that the script will run without error).
  • Evaluates the script file.
  • Retrieves the function named "create" from the script file.
  • Executes this function, passing our previously created "m_thisObject" as the "this" object for the script to use. This function then binds our signals to slots in the script file.
  • Finally, we emit our test signal.
Finally, let's look at the ECMAScript file I'm using:



// set up the game object - the 'this' object will be an actual QObject
// derived class passed in from the application.
function create()
{
// test 1 - call a slot in the class:
this.slot1();

this.signal1.connect(this, testSlot);
}

// create our own slot:
function testSlot()
{
this.displayMsg("Testing testing.. 123");
}

...and that's it! The "create" method will first call the "test2" slot in our C++ class, then connect our test signal to a scripted function. When we emit the signal in our C++ class, the "testSlot" function will be called.


This is just a starting point. The more I use the QtScript module, the more I marvel at the possibilities created with this tool. I shall post follow-up articles with more information and techniques as I see fit. In the meantime, go add scripting extension support to your faviourite project. With tools this easy to use, there's no excuse not to!

Game update

A few things I should clarify about my earlier post:

I'm writing this for fun. I don't expect this game will come to anything much at all. If it's fun and playable, I might release it and try and get it packaged for a few different distros. My main motivation in writing the game is for me to improve my own programming skills.

I'm using Qt4 and qDevelop, nothing else. Qt4 is simply the best cross-platform C++ library I've ever seen, and qDevelop is a nice cross platform IDE that does everything I want it to.

Right now I have collision detection going, although it needs a few tweaks for fast-moving objects (like bullets). My next step is to investigate The QtScript module. Basically I want to be able to write the AI routines for the game in ECMAScript, so I can change them without having to recompile the game. This should also make the game easily extensible, possibly by people who aren't hard-core programmers.


Will post another video when I get something worth showing!

Pet Project: game

Yep, I'm writing a small game. I'm usually rather tight-arsed about proper code design before you start writing code, but I've realized that a lot of the time this stops me writing any code at all.

For this project my general methodology is to write whatever comes to mind, and be prepared to throw away code that I think is too crap to last in the final build.

In fact, my design phase has been so minimalistic I don't even have a name for the game. For now, it's just called "game". It's going to be a land-cased top-down 2D shooter, with lots of weapons and cool stuff. Right now it can load a very simple level format from XML; you can control the player using the keyboard "WASD" keys, and fire the players rifle using the mouse. Bullets have collision detection.

Here's an early video that shows the game sans collision detection:



My next step will be to have predefined objects for a level (right now they're all just boxes). I might start with an immobile gun turret - that should let me get some AI going for the enemies, as well as some health stats for the player and enemies.

Eventually I want to make the game easily extensible using QtScript for enemy AI.

Working with Qt4 has made this project an absolute breeze - there's hardly any code in this project! When it gets a few more features I'll upload the source online.

Cheers,!

When source code control goes wrong

Question: when is source code control not source code control?


Answer: when your development model forces you to have working copies outside the source control environment.


This happened to me recently - I lost alot of work due to a bug in the source code control package we use. I had several weeks worth of changes checked out on my local hard disk. The development model at this company is such that I cannot check in my changes until they are finished and stable. I guess I've known that this is a bad idea from the start, but it took a catastrophic loss of data for me to find out.

So let this be a lesson to all of you - whatever source code control package you use (you DO use one, right?) make sure you're using it properly. That means:

  • Regular commits (at least daily, but I recommend hourly or even less).
  • Useful commit messages. If you're committing work often, you'll need to know what you've been working on.
  • Use branches to separate high-risk code, so you don't pollute the main source tree with your changes.
  • Keep release code and development code separate, yet easily accessible. Branches are a good way to go here as well.

As far as I'm concerned, branches are absolutely critical to a decent source control environment. Creating a branch should be dead easy. If I can't create a usable branch in less than 10 seconds, then I probably won't bother. Some tools (like vault for example) create branches by copying the part of the source tree you're branching to a new folder with a different name. The problem with this is that it breaks Visual Studio's SCC integration. In fact, *any* embedded reference to the code location within the code repository will be rendered useless for the new branched code. A much better method is to create true parallel branches - either as a separate instance of the repository, or using the same instance with tags.

Linus Torvalds has the right idea in this presentation on git. The things most important to programmers should be dead-easy to do. That's branching, merging, and tracking changes over time.