- Empath's asynchronous 'job' scheduling mechanism
- Rik Hemsley <rik@kde.org>

Empath has the concept of a 'job', which is a simple name for an
operation that will be performed asynchronously.

The class 'EmpathJob' is the base class for such an operation.
If you know DP language, this is called a 'Command', 'Action' or
'Transaction'.

You can see a draft UML diagram showing how this works by looking
at empath.eps (or empath.dia, if you have the program 'dia')

From the user's perspective, the interface is extremely simple and
easy to use.

To retrieve a message with URL 'empath://Local/Inbox/999', user code
could look like this:

empath->retrieve(EmpathURL("empath://Local/Inbox/999"), this);

The final parameter used when calling any of these job-related methods
is always a pointer to a QObject. If the QObject you pass implements
the correct slot, you get a signal when the job is complete.

Of course, if you don't care what happens to the job, you simply
don't pass the final parameter.

The various methods are: createFolder, removeFolder, copy, move,
retrieve, write, remove and mark.

Those methods whose name does not end in 'Folder' work on messages.

All jobs either inherit from 'EmpathSingleJob' or 'EmpathMultiJob'.
Those that inherit from EmpathMultiJob actually create multiple
EmpathSingleJob objects and run them one after the other.

This may change in the future. Perhaps an EmpathMultiJob will
add its EmpathSingleJob objects to the queue and wait for completion.

Another thing that may change in future is the way that you get
the signal that a job has completed. Currently you have to implement
the correct slot in your QObject-derived class. It would be nicer
if you could pass the name of a slot instead of being forced to
find out the correct name and implement it.

The new API would probably look like this:
empath->copy(sourceURL, destURL, QObject *, SLOT(someSlot(EmpathCopyJob)));

If anyone can be bothered to do this, please go ahead ;)

As mentioned above, you have to look up the correct name for the
slot you should make available. You should look this up in
lib/EmpathJobScheduler.cpp

Can you see why that's a hassle ? :)

Well despite these little niggles, this design seems rather logical
and straightforward. Comments are appreciated.

