Thursday, July 28, 2011

Another Victory in the War Against Macros

wxWidgets is notorious for using many macros. While evils of macros in C++ are well-known, sometimes they are really necessary, e.g. wxIMPLEMENT_APP hides the difference between using main() or WinMain() as entry point and sometimes, even if there are alternative approaches not involving macros, e.g. using a base class instead of wxDECLARE_NO_COPY_CLASS macro, their use is still not particularly offending. In still other cases macros are used to provide a kind of a DSL, such as event table macros that allow to describe event handler connections statically and less flexibly but more concisely than Connect().

However in some cases there is really nothing that can be said in defense of
using the macros and they are present in the code just for "historical
reasons", i.e. because nobody thought about doing it better back when the code was first written, often enough almost 20 years ago. We try to deprecate (which is a polite term for "get rid of") such macros progressively and there are not that many of them left, at least on the interface side.

A couple of days ago I finally managed to ditch a particularly aggravating set of them: the so-called "control container" macros. They must be used in the classes that represent windows containing other windows ("controls") in order to allow TAB navigation inside them. While wxPanel and wxDialog, which are two of the usual control containers, already do it, you had to explicitly use macros such as WX_DECLARE_CONTROL_CONTAINER() and WX_DELEGATE_TO_CONTROL_CONTAINER() if you wanted to write your own composite controls. Luckily few people did this because these macros were not even documented but even just using them in wxWidgets itself causes much teeth gnashing. And particularly so from my part, almost surely because I wrote these macros myself (and only 10 years ago so even the "explanation for using macros here is forever lost in the mists of time" excuse is at most half-valid).

So when I had to add correct keyboard navigation to wxSearchCtrl to fix another bug, I finally decided to atone for my mistake. The solution turned out to be surprisingly simple and nice: instead of all these macros I added a new wxNavigationEnabled class which uses CRTP to inject the TAB-handling logic into the derived class. So, as the example in the documentation shows, you now simply have to inherit your custom composite control from wxNavigationEnabled<wxWindow> instead of directly deriving from wxWindow to get correct keyboard handling, e.g.:
class MyCompositeControl : wxNavigationEnabled {

Using wxNavigationEnabled is definitely much simpler than using macros -- in fact, it's so simple that it could even finally be documented quite painlessly, which is a good criteria -- so I'm quite happy with it (as you can see, even happy enough to write a blog post about this). Even though not having to do anything at all and have TAB-navigation just work would certainly be even better, this can't be done without moving all the TAB navigation logic down into wxWindow itself and there are many, many windows which don't contain any other controls this doesn't look like a good idea.

Anyhow, this battle against macros was won but the war is not over yet. Getting rid of (or at least providing non preprocessor-based alternatives to) all macros in wxWidgets is not the highest priority issue but it's still nice to make some progress on it. And if you have any candidates for irritating macros to be dealt with next, please let us know!

Sunday, July 24, 2011

Less flattering statistics

I've stopped counting the number of opened and fixed Trac bugs quite some time ago because it was too much trouble to do it semi-manually. But one of the side effects of the recrudescence of my love affair with Perl is that I'm looking for excuses to write more Perl code and so I spent half an hour today on writing a small script allowing to gather ticket statistics automatically. This is probably not the best way to do it (it would be better to install some Trac statistics plugin server-side) and the script itself is pretty trivial so it didn't quench my quest for more Perl neither but at least it does quickly give the statistics I wanted.

The bad part is that I didn't want the statistics I got because it in spite of all our efforts the number of opened bugs in wxWidgets keeps increasing. The only good news is that the rate of increase seems to have decreased or at least stabilized: if in 2009 we had 271 new bugs (computed as the difference between 1270 opened and 145 reopened ones and 1144 closed ones), in 2010 we had "only" 275 new bugs and so far in 2011 we have only 20 news ones (and it's not as people got simply tired of reporting them, there were still 521 newly opened bugs since the beginning of the year). But in all, we still have 544 more bugs today than in May 2008 when Trac statistics begin so the journey towards bug-free future remains long...

Out of curiosity I also collected the month statistics using the following intimidating command combining the wonders of zsh short loop syntax and GNU date relative dates support:

% for ((year=2008;$year<=2011;year++)); \
for ((i=1;$i<=12;i++)); \
./trac-ticket-stats --csv $year-$i-01 \
`date --date="1 day ago 1 month $year-$i-01" +%F`

and discovered somewhat surprising variations between the months: on average, we get 60 net new tickets per month but there are some outliers. In Januaries there are almost no new bugs (2) while in October there are 112 of them. Looking at the number of bugs created, more bugs are created in March, October and July (which are very close) while wxWidgets users seem to be on vacation in June when almost twice less bugs are opened. As for us, the developers, we seem to start every new year with good resolutions as January is the month with by far the most bug fixes while by June working on them really loses its appeal and two times fewer of them are resolved.

Friday, July 15, 2011

Self flattering statistics

After receiving the latest monthly Source Forge newsletter with their list of top 25 projects I became curious because at first glance it had seemed like most of them were Web-based applications and I wondered if it really was so. So I spent 10 minutes clicking on all the 25 links and quickly looking at the programming languages/environments/frameworks these projects used and here is what I found (please bear in mind that I could easily make some errors, all this is very quick and rough):

  1. Web/PHP

  2. Java

  3. Java

  4. Java

  5. Perl(?)

  6. Python

  7. C++/wx (and Qt?)

  8. Java

  9. C

  10. C++

  11. Python/wx

  12. Web/PHP

  13. Web/PHP

  14. C++/Qt

  15. Java

  16. C

  17. C

  18. C++/wx

  19. C#

  20. Java

  21. C/SDL

  22. C++/wx

  23. C++/MFC

  24. C++ (?)

  25. C++

As you can see, actually my initial impression was totally wrong and there are only 3 web-based applications (incidentally, all written in PHP) whereas there are twice as many written in Java. What really surprised me, however, was that 4 of them used wxWidgets (although I'm not sure if it's the main UI used by MediaInfo as it also seems to use Qt). I knew about DVDStyler but not the other ones so it was a pleasant surprise.

Of course, I have no idea what are the exact criteria for choosing these 25 "top" projects and there are plenty of Open Source projects not hosted on SourceForge, without even speaking about all the other ones, and so on but, still, it seems like wxWidgets is more popular than I thought (and otherwise I wouldn't have written this post, would I?).

Friday, July 08, 2011

2.9.2 and plans for the future

As you've probably noticed at, the new 2.9.2 release was finally officially released this Tuesday. I won't detail its new features in details here as most important of them were already covered before but just wanted to say a few words about our future plans.

The next release -- incredibly enough -- will be 2.9.3 and we plan to do it at the end of September, after merging the work of GSoC 2011 students in the trunk. So ideally this release will have GTK+ 3 support, a new wxiOS port, wxWebViewCtrl for embedding a "true" HTML rendering engine (such as Trident under MSW or Webkit elsewhere) and a new UI animation library. Being realistic (although I'd certainly like to be proven wrong!), at least some of these things will probably be delayed but the release itself should still happen.

Depending on the things included in or omitted from 2.9.3 we may need to do 2.9.4 with all the big features we want in 3.0 next, although I'd like to avoid it and, again, ideally, 2.9.3 would already have all of them. If 2.9.3 does have everything and if no huge problems are discovered in it, we'd like to release 3.0 before the end of the year (meaning not later than mi-December). But then again, you have to be realistic about these things, so 3.0 will probably happen in the beginning of the next year rather than in this one. Still, planning it for 2011 at least gives us a target to miss.

As usual, let me end any roadmap discussion with a plea for help: we need your help. Most obviously with testing the huge amounts of the new code that will hopefully be in 2.9.3. But also with wxOS port as Stefan is almost alone working on it and with GTK+ 3 stuff as few people know it (yet). Please help us make 3.0 available sooner and, most importantly, better -- thanks in advance!