1 /* $Id: job.hh,v 1.5 2003/09/27 21:31:04 atterer Exp $ -*- C++ -*-
3 |_) /| Copyright (C) 2003 | richard@
4 | \/¯| Richard Atterer | atterer.net
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2. See
8 the file COPYING for details.
10 A job is a certain task - just the application logic, *no* user interface.
11 All interaction with the rest of the system (input/output, user
12 interaction) happens via an IO object.
24 //______________________________________________________________________
29 //______________________________________________________________________
31 /** Base class for interaction between the outside world and the job. For
32 example, depending on the IO object you register with a job, you can
33 control the job via a gtk app or from within a command line utility.
35 A note about the message strings passed to jobFailed() and jobMessage():
36 They are not const, and the IO child class can modify them in whatever
37 way it likes. The most useful action is to copy the contents away with
38 swap(), e.g. with myMessage.swap(*message);
40 The messages are always in valid UTF-8. Their text is *never* "quoted",
41 e.g. "<" is not replaced with "<". Neither do they contain any markup.
43 The names of all methods here start with "job_". If a child class
44 Job::SomeClass::IO adds any further methods, their name starts with
45 "someClass_". This makes it easy to see which methods are introduced
52 /** Called from IOPtr.remove(), gets as argument the object that was passed
53 to it, returns the new pointer to store inside the IOPtr. Override the
54 default implementation like this to implement chained IOs:
58 virtual Job::IO* job_removeIo(Job::IO* rmIo) {
62 delete this; // May of course omit this if not desired
64 } else if (child != 0) {
65 Job::IO* c = child->job_removeIo(rmIo);
66 Paranoid(c == 0 || dynamic_cast<IO*>(c) != 0);
67 child = static_cast<IO*>(c);
71 virtual void job_deleted() {
72 if (child != 0) child->job_deleted();
73 delete this; // May of course omit this if not desired
77 However, in the normal, simple case that there isn't a child, use:
80 virtual Job::IO* job_removeIo(Job::IO* rmIo) {
81 if (rmIo != this) return this; // Or just: Paranoid(rmIo == this);
82 delete this; // May of course omit this if not desired
83 return 0; // New value to be stored inside IOPtr
87 *Constructing* chains of IOs is not handled here, you must provide some
88 way to do this in your derived class.
90 Important: If you return a non-null value, it must point to an object
91 of your *derived* class, even though it is just passed as a plain IO*.
92 There is a runtime check (if DEBUG=1) in the IOPtr code for this.
94 The default impl doesn't delete this: */
95 virtual Job::IO* job_removeIo(Job::IO* rmIo) {
96 if (rmIo != this) return this;
100 /** Called by the IOPtr when it is deleted or when a different IO object is
101 registered with it. If the IO object considers itself owned by its job,
102 it can delete itself. */
103 virtual void job_deleted() = 0;
105 /** Called when the job has successfully completed its task. */
106 virtual void job_succeeded() = 0;
108 /** Called when the job fails. The only remaining sensible action after
109 getting this is probably to delete the job object. */
110 virtual void job_failed(string* message) = 0;
112 /** Informational message. */
113 virtual void job_message(string* message) = 0;
115 //______________________________________________________________________
117 /** For all classes which are "jobs", this provides easy, consistent
118 management of a pointer to an IO object. In your job class, use the
119 template to generate a public member:<pre>
125 MyJob(IO* ioPtr, ...) : io(ioPtr), ... { ... }
129 template<class SomeIO>
132 IOPtr(SomeIO* io) : ptr(io) { }
133 ~IOPtr() { if (ptr != 0) ptr->job_deleted(); }
135 SomeIO& operator*() { return *ptr; }
136 SomeIO* operator->() { return ptr; }
137 operator bool() { return ptr != 0; }
138 SomeIO* get() { return ptr; }
139 /** Set up pointer to IO object. Must not already have been set up. */
140 void set(SomeIO* io) {
144 /** Remove pointer from chain of IO objects. */
145 void remove(SomeIO* rmIo) {
147 Job::IO* newPtr = ptr->job_removeIo(rmIo);
148 // Upcast is OK if the job_removeIo() implementation plays by the rules
149 Paranoid(newPtr == 0 || dynamic_cast<SomeIO*>(newPtr) != 0);
150 ptr = static_cast<SomeIO*>(newPtr);
153 /** Like set(0), but doesn't call the IO object's job_deleted() method */
154 void release() { ptr = 0; }