Journal Articles

CVu Journal Vol 16, #6 - Dec 2004 + Journal Editorial
Browse in : All > Journals > CVu > 166 (12)
All > Journal Columns > Editorial (221)
Any of these categories - All of these categories

Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.

Title: Editorial

Author: Administrator

Date: 09 December 2004 13:16:09 +00:00 or Thu, 09 December 2004 13:16:09 +00:00

Summary: 

Body: 

I really do enjoy being part of the open source movement. It really does make the mind boggle at the speed of development of software. I've been tracking Novell's Mono application for quite a while now and since the 1.0 release (which was roughly 8 months ago), things have gone on in leaps and bounds. Probably the most interesting part has been the development of System.Windows.Forms.

In the original version, Mono relied on Winelib to provide the SWF parts. Unfortunately, Winelib and Wine moved all the time, which meant that rather than concentrating on SWF, the Novell team and those around the world which contribute to the source would be trying to hit a moving target. In the end, it was decided that there would be a ground up effort to implement SWF natively. That was roughly 4 months ago. It is (at the time of writing) somewhere close to being 88% complete. To anyone, that is a big achievement and probably, without the sort of community which is found in the open source movement, the completion would be closer to 60%.

Of course, I could be wrong, but I can only call what I see. It certainly has been a rollercoaster of a ride and has been a lot of fun.

The Student Code Critique

The SCC is a critical part of C Vu. It is one of the ways for you to all participate in the magazine. However, the numbers seem to have dropped and dropped to such a point that in this issue, there is one entrant. While it does make my judging for the book a lot easier, it is worrying the level of members who will take about 20 minutes to enter. Please get involved - not only do you make it more interesting, but you're also helping to educate others.

Ever Had One of Those Moments?

I'm sure that you've all had one of those moments, those gloriously inspired moments when you know exactly how to fix that piece of code which has been bugging you for days now and better than that, by making a couple of changes to said code, you can fix a number of other problems plus make it run faster and take less time to compile? It's wonderful isn't it.

I had one of those a while back when I was hand optimising some code within a program I help develop. By replacing a lot of inefficient code with something like

QString combo[] = { "Text", "Link", "External Link",
                    "External Web-Link" };
size_t comboArray = sizeof(combo)/sizeof(*combo);
for(uint prop = 0; prop < comboArray; ++prop)
  ComboBox1->insertItem(tr(combo[prop]));

it made the program a lot tighter and quicker. There was a problem with it which wasn't apparent under the test conditions (aka on my machine with different EU locales set). tr() is the Qt translator - it is a very powerful piece of kit, but unfortunately with it set inside of the insertItem method, the translator wasn't called. This did bite into the efficiency (as shown by various calls to memory and CPU profilers) and the second version was to replace

QString combo[] = { "Text", "Link", "External Link",
                    "External Web-Link" };

with

QString combo[] = { tr("Text"), tr("Link"),
     tr("External Link"), tr("External Web-Link") };

which oddly enough worked. At first, I thought the problem was in the comboArray line, but then that really didn't make sense - all that line does is give the size of the created array. That could only mean that the insertItem method couldn't take the tr conversion step. Swine! I had altered a substantial amount of code to use my original method and then find it doesn't work as well as anticipated (though it did work).

This did lead me to suspect that perhaps my testing and programming methodology was incorrect. Up to now, I had been a single programmer, working on a project which really, not many people would use and if they did, well, the problems would not be that huge to work around. In other words, I'm not being lazy per se, just not being as considerate as perhaps I should; software, after all, is a global commodity.

What I finally concluded was that I should not have made so many changes, had one and sent that out as a simple test case and worked on the results of that. Okay, grepping through the code wasn't that big a task, neither were the changes, but it was time I could have spent doing things I enjoy - like having a relaxing pint of some foaming nut brown ale and reading my collection of Dr Who books (hey, even I have to rest sometimes!)

Leading on from that, I decided to do some more code - this time, replacing normal code with template code to try and speed things up - if not from the user's point of view, then definitely from the system's point of view. This time, I started small...

/* While this version is simpler to read and the
   final binary is around 4k smaller than the
   template version, gcc 3.4 with a few
   optimisation tools being run show this to be
   slightly less efficient in terms of processor
   time. */

#include <qapplication.h>
#include <qslider.h>
#include <qlcdnumber.h>

int main(int argc, char* argv[]) {
  QApplication myapp(argc, argv);

  QWidget* mywidget = new QWidget();
  mywidget->setGeometry(400, 300, 170, 110);

  QSlider* myslider = new QSlider(0, 9, 1, 1,
                     QSlider::Horizontal, mywidget);
  myslider->setGeometry(10, 10, 150, 30);

  QLCDNumber* mylcdnum = new QLCDNumber(1, mywidget);
  mylcdnum->setGeometry(60, 50, 50, 50);
  mylcdnum->display(1); // display initial value

  // connect slider and number display
  QObject::connect(myslider, SIGNAL(sliderMoved(int)), 
                   mylcdnum, SLOT(display(int)));

  myapp.setMainWidget(mywidget);
  mywidget->show();
  return myapp.exec();
}

Okay, not exactly rocket science in terms of code (and as you've all been reading the Qt series over the past couple of issues, you can tell me what it does). However, some of the methods are very similar and how they work even more so.

Now, I could have written a simple wrapper, but instead came up with this

// Qslider v2 - template version.
// qslider-template.cpp

#include <qapplication.h>
#include <qslider.h>
#include <qlcdnumber.h>

#include "memory.h"

template <typename N, typename T>
void setGeometry(N m, T *x) {
  m->setGeometry(x[0], x[1], x[2], x[3]);
}

int main(int argc, char* argv[]) {
  QApplication myapp(argc, argv);
  QWidget *mywidget(allocate_memory<QWidget>());
  testAlloc(mywidget);

  int geom[4];
  geom[0] = 400; geom[1] = 300; geom[2] = 170;
  geom[3] = 100;
  setGeometry(mywidget, geom);

  geom[0] = 0; geom[1] = 9;
  geom[2] = geom[3] = 1;
  QSlider *myslider(allocate_memory<QSlider>(geom,
                   QSlider::Horizontal, mywidget));
  testAlloc(myslider);

  geom[0] = geom[1] = 10; geom[2] = 150;
  geom[3] = 30;
  setGeometry(myslider, geom);

  QLCDNumber *mylcdnum(
         allocate_memory<QLCDNumber>(1, mywidget));
  testAlloc(mylcdnum);

  geom[0] = 60; geom[1] = geom[2] = geom[3] = 50;
  setGeometry(mylcdnum, geom);

  mylcdnum->display(1); // display initial value

  QObject::connect(myslider, SIGNAL(sliderMoved(int)), 
                  mylcdnum, SLOT(display(int)));

  myapp.setMainWidget(mywidget);
  mywidget->show();
  return myapp.exec();
}
// memory.cpp
#include <qapplication.h>
#include <qslider.h>
#include <qlcdnumber.h>
#include <new>
#include <cstdlib>
using std::nothrow;

template <typename N>
N *allocate_memory() {
  return new(std::nothrow) N;
}
template <typename N, typename M>
N *allocate_memory(int val, M *&m) {
  return new(std::nothrow) N(val, m);
}

template <typename N, typename M, typename O,
          typename T>
N *allocate_memory(T *t, M m, O o) {
  return new(std::nothrow) N(t[0], t[1], t[2], t[3],
                             m , o);
} 

template <typename N>
void testAlloc(N &w) {
  if(!w)
    exit(EXIT_FAILURE);
}

What is the advantage over the original version? Well, for a start in memory.cpp I have a very simple, yet very effective memory handling routine - given it was only a test bed, it is probably not win any prizes for the best and tightest code around, but the important thing was for what I threw at it, the code worked and worked well (the profilers I use showed roughly a 10% improvement over the original).

Was there really a point to the exercise though? The code never did make the release version after all. Yes. Yes there was. It is a proof of concept that demonstrates that it is entirely possible not only make the code tighter and more importantly, more secure (there is a planned network of the application so everything has to be as secure as possible).

Sad Times

Unfortunately, I have to report that our production editor of many moons has decided to very reluctantly move on to pastures new. Pippa has been possibly one of the best production editors I've had the pleasure to work with. Not only has she been patient, but has that rare quality of knowing about the subject matter in hand.

We will all miss her and wish her well. C Vu and Overload are now after a new production editor. If you would like further details, please contact John Merrells ().

And So...

Well, this is the final edition of C Vu for 2004. All that remains for me to say is that from all of the ACCU Committee and C Vu + Overload production staff, may we all wish you a warm and merry yuletide and that 2005 be a fantastic year for you all. See you in 2005!

Notes: 

More fields may be available via dynamicdata ..