    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Using objects for background tasks (3)</title>
        <link>https://members.accu.org/index.php/articles/1457</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #17/18 - Jan 1997</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c228/">1718</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-228/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+228/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
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/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Using objects for background tasks (3)</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 31 January 1997 08:52:00 +00:00 or Fri, 31 January 1997 08:52:00 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<p style="font-style: italic;"> This follows on from parts 1 and 2
which were published
in CVu. Both Adrian and Francis feel that part 3 is more suitable for
Overload. So here it is! - Ed.</p>
<p> We have a system which allows 'background' processing
based on a simple cluster of classes (see previous articles). The class
that we need to derive from is the ProcessBase class. This provides the
virtual functions Prepare(), DoAction() and Cleanup(). Instances may
be part of a sequence of operations or just running con&shy;tinuously.
The latter case is the simplest to de&shy;sign for. The lifetime of a
ProcessBase being similar to that of the object or objects being acted
on, it is of little significance whether it is associated with, a part
of, or a base of the ob&shy;ject concerned.</p>
<h2>Designing your classes</h2>
<p> I'd like to look at a couple of situations where you could
reasonably use sequences in an ap&shy;plication. Needless to say, these
will be broadly modelled on an actual application (without giving away
any trade secrets, of course).</p>
<p> First, program start-up. Imagine that your ap&shy; plication
has to read a number of files (or data tables perhaps) and build an in
memory repre&shy;sentation of that data. This is going to take some
time (at least several seconds). Secondly, we'll look at performing a
long winded 'query' within the program.</p>
<p> In the first case, it is really quite easy to design the
overall structure of the classes that will hold the data in memory. If
the data is in the form of a relational database, the classes or data
structures would match records in the tables, foreign keys in detail
tables will correspond to associations in the class design.
Associations will probably be represented by pointers to classes.
Additional classes will probably be needed to manage these objects,
probably with some form of collection class. Anyway, this part of the
design should more or less do itself. Let's call these classes 'In
Memory Data' col&shy;lectively (IMD).</p>
<p> Taking the line of least resistance, you could write all
the initialisation code in the construc&shy;tors of these classes, they
could open the files or tables, read them, create objects etc. This
wouldn't allow the work to be done in the background though.</p>
<p> Obviously, this isn't just going to happen in the
background. If this work is going to be done in the background, just
where do we put our ProcessBase derived objects. In that case, we must
put that code in ProcessBase derived classes. The question is, just
where do these classes fit in? It's tempting to use ProcessBase as a
base class for some of the IMD classes. The obvious justification for
this is that you can encapsulate the reading of the data in these
classes. This isn't really going to be the case though! In practice,
the whole process of reading the data is going to need knowledge of
both the destination classes and the file or da&shy;tabase mechanism.
It is much more likely tha you will want to encapsulate the reading of
a stream of
some kind within the class. The point about streams being that you
don't have to know what kind of stream it is within the class. Streams
give us some abstraction of the source of the data, whether it is a
file or a binary data&shy;base field. Exactly where you put the 'glue'
that provides the actual stream and uses the IMD class members to read
from that stream is up to you. If there's only going to be one stream,
as in the case of serialisation to a single file, then that would
probably be opened be&shy;fore the sequence starts. In other cases, you
will almost certainly want to open the data source in the Prepare()
function of your ProcessBase derived object. It can then be closed in
Cleanup().</p>
<p>If the IMD is complex, it may well be that the reading process is
also complex. If so, con&shy;sider deriving more than one ProcessBase
class to break the task up into simpler parts. This is almost always
the best course if you find that DoAction() needs to handle multiple
states.</p>
<p> Summarising the program start-up situation, it is
probably best to create separate 'reader' ProcessBase objects with
short lifetimes, than to derive your IMD objects from ProcessBase. The
latter option is still possible but inelegant.</p>
<p> Now consider the 'query' case. I'm assuming that you're
reading data from a database, processing it, then formatting and
displaying it. In this case, we will need to interact with objects that
read data as well as user interface objects that display it. Precisely
what is read will be determined by a query object of some kind. The
layout and formatting of the data will be obtained from some kind of
class representing the query and there must be something
repre&shy;senting the displayed data (a view). Both of these are
possible candidates for derivation from ProcessBase. The alternative is
to derive one or more intermediate classes from 'layout' classes. That
might be a part of the query ob&shy;ject or it may be common to all
queries. With this set of classes, there is no obvious candidate to
double as a 'querier' object. A sophisticated design may well provide
some abstraction of the display object, if so that eliminates one
pos&shy;sibility. The query itself may seem a reason&shy;able candidate
but this is likely to be quite complex in its own right. It seems wrong
to allow the query object too much knowledge of the display object, or
any at all for that matter.</p>
<p style="font-style: italic;"> This is a key principle behind the MVC
(Model-View-Controller) architecture - Ed.</p>
<p> In my opinion, the only valid solution is to have one or
more intermediate ProcessBase derived objects to perform the query.
There are two reasons why this is likely to be the best
solution. First, the objects and resources needed to read the database
are only needed during the
querying process. Secondly, we can reduce the binding between the query
and the view.</p>
<p> In summary, it's best to first consider creating short
lifetime 'go between' classes.</p>
<h2>Tying in with the user interface</h2>
<p> When your application is busy doing some&shy; thing, it's
usually best to let the user know that it is working and hasn't just
expired. One way to do this is to display a 'progress' meter as well as
updating a 'status' bar with descriptive text: 'Packaging today's data,
10% done' or more realistically, 'Corrupting today's data, 90% done'.</p>
<p> The natural way to generate this behaviour is to fire an
'event' whenever the status text or the progress fraction
changes. The ProcessBase class can have member functions to set the
status text and progress, e.g.</p>
<pre>void SetStatus(const char *pText); <br>void SetProgress(double progress);</pre>
<p> There are several choices as to what these functions do.
Firstly, they may store the text and progress value within the class,
or they may pass them straight through to the event handlers. There is
an obvious temptation to make these functions virtual and provide the
code to hook to the user interface in the de&shy;rived code.
Unfortunately, this is likely to in&shy;crease the binding between the
derived class and the rest of the application. The class that draws the
text or updates the meter may well not be one that the ProcessBase
class otherwise needs to be associated with. For example, the
ProcessBase class may be associated with an IMD class and possibly a
database class, neither of which are concerned with the user interface
in any way. To allow this additional binding will make your classes
less portable and main&shy;tainable. Suppose that your ProcessBase
de&shy;rived class is going to be re-used in a cluster of applications,
do you want to have to derive new classes for each application, just to
hook into theUI?</p>
<p> In procedural terms, this would be a natural candidate
for a function pointer. ProcessBase can have a function pointer for
each event. Just taking the progress event:</p>
<pre>// either inside or outside of the<br>// ProcessBase class:<br>typedef void (*ProgressEventHandler)(double progress);  <br>// private member of ProcessBase, <br>// init to 0 in constructor: <br>ProgressEventHandler m_PEHandler; <br>// public members: <br>void SetProgress(double progress); <br>void SetProgressEventHandler(ProgressEventHandler peh) <br>  { m_PEHandler = peh; }<br><br>void ProcessBase::SetProgress(double progress){<br>  //. .<br>  if(m_ProgressEventHandler)<br>    m_ProgressEventHandler(progress);<br>}<br></pre>
<p>In this case, the function pointer is used to call the
supplied function with the progress value as a parameter, if the
event has been set. The ob&shy;vious deficiency in this approach is
that a plain function isn't what we would ideally call. It would be
much more natural to call a class member function directly.</p>
<p> Before we go on to do that, consider the 'progress'
parameter being passed straight through. Would it be better to store it
in the ProcessBase instance? If we do, then we will need to add a data
member and an access function:</p>
<pre>//private in ProcessBase<br>// init to 0.0 in constructor:<br>double m_Progress;<br>//public in ProcessBase<br>double GetProgress(){return m_Progress;}</pre>
<p> You wouldn't make it a public data member, now would you?</p>
<p> Then in order to access the progress value, we could
pass a class reference or pointer through to the handler function. That
is, the handler function pointer type becomes:</p>
<pre>typedef void (* ProcessEventHandler) <br>              (const ProcessBase&amp; process);</pre>
<p> One advantage of this approach is that only one handler
type is now needed for both prog&shy;ress and status events as well as
any other events that we may think of. Also, the handler function may
now access other ProcessBase properties, which gives a little more
flexibility in how these are used. Other arrangements are possible. For
example, you could also pass an enumeration for the kind of event to
the han&shy;dler. That's not necessarily the smartest way to work but
some people like that kind of thing. Note that with the event handler
being essen&shy;tially a procedure and not being able to mod&shy;ify
the ProcessBase instance, the SetProgress() member function doesn't
rely on side effects of the handler. From ProcessBase's point of view,
the presence or absence of event handlers has no effect on its
behaviour. You may wish to sacrifice the constness of the ProcessBase
reference passed to the handler. This may be valid, but it is a
decision that you should reach with caution.</p>
<h2> Dropping the procedural handlers.</h2>
<p> How can we provide another class's member function as a
handler? This is a harder question than it may seem!</p>
<p> Think what is needed to implement the proce&shy; dural handler
above. There would need to be a class instance statically available to
the func&shy;tion. This would then be used to call a member function to
display the progress or whatever.</p>
<p> C++ has 'pointer to member functions', these nearly do
the job! A combination of pointer to member function of the right type
and pointer to the instance is what's actually needed.</p>
<p>Let's try it:</p>
<pre>typedef<br>void (SomeClass::* ProcessEventHandler)<br>              (const ProcessBase&amp; process);</pre>
<p> Oh! The problem is: what's 'SomeClass'? It needs to be
the actual class of the instance whose member function is going to be
used. That's no good, ProcessBase can't know about the class that's
going to handle the event, see above! At least it must be a base of the
actual class if you're prepared to cast it. This may be an acceptable
solution if you're using some&shy;thing like MFC where you could use
CObject as the base for everything. You may then cast the actual
pointer to member in order to set it. This approach can work, if you
have a suitable candidate base class and it isn't used as a
vir&shy;tual base (you cannot then cast it).</p>
<p> If you're happy to implement it this way, then go ahead, it is
simple enough to do. If on the other hand you don't want to tie
your class library to someone else's then you will have to go to more
trouble.</p>
<p> If your compiler doesn't support templates, then go back
one paragraph, or prepare to write some horrid macros (and still not
fully solve the problem).</p>
<p> If we can't store a method pointer and use it for any
arbitrary class, what can we do? Well, we could assign a pointer to a
base class and call a virtual function! How does that help?</p>
<p> We can then derive from that class, using a template to
give us the correct class of method pointer!</p>
<pre>class ProcessBase;<br>class ProcessEvent<br>{<br>public:<br>  virtual void DoEvent(const ProcessBase&amp; process) = 0;<br>};<br><br>template &lt;class HandlerClass&gt;  <br>class ProcessEventHandler <br>: public ProcessEvent <br>{ <br>private:<br>  typedef void (HandlerClass::* FnProcessEvent)  <br>              (const ProcessBase&amp; process);
  HandlerClass *m_Handler; <br>  FnProcessEvent m_OnProcessEvent; <br>public:<br>  ProcessEventHandler()<br>    : m_Handler(0), m_OnProcessEvent(0) {} 
  ProcessEventHandler(HandlerClass<br>      *pHandler, FnProcessEvent pe)<br>   &nbsp;: m_Handler(pHandler),<br>      m_OnProcessEvent(pe) {}  <br>  void SetHandler(HandlerClass *pHandler,<br>                  FnProcessEvent pe) <br>  { m_Handler = pHandler;<br>    m_OnProcessEvent = pe; }  <br>  void DoEvent(const ProcessBase&amp; process)<br>  { if(m_Handler)<br>      (m_Handler-&gt;*in_OnProcessEvent)(process);<br>  }<br>};<br></pre>
<p> This template class will be instantiated for each handler class
that is used to handle these events.</p>
<p>Here are the relevant parts of the ProcessBase class, with code
inlined for compactness:</p>
<pre>class ProcessBase <br>{<br>  ProcessEvent *m_pPE; <br>  double m_Progress;  <br>public:<br>  ProcessBase()<br>    : m_Progress (0) , m_pPE(0) {}  <br>  virtual ~ProcessBase()<br>    { SetProgressEvent(0);}  <br>  void SetProgress(double progress)<br>    { m_Progress = progress;<br>      if(m_pPE)<br>      m_pPE-&gt;DoEvent(*this); <br>    } <br>  void SetProgressEvent(ProcessEvent *pPE)<br>    { if(m_pPE) delete m_pPE; m_pPE = pPE;}<br>};<br></pre>
<p> Note that the progress event property is now a simple
pointer to a ProcessEvent instance. In this implementation, the
ProcessEvent once assigned is owned by the ProcessBase class. If you
want to enforce this, you will need to do additional work.</p>
<p> In use, suppose we want to supply a member of a
'MainWindow' class:</p>
<pre>class MainWindow<br>{<br>  // public event handler:<br>  void ShowProgress(const ProcessBase&amp; process) {}  <br>};<br><br>ProcessBase pb; <br>MainWindow mainWin;<br>//This is how to assign the event handler: 
pb.SetProgressEvent(<br>    new ProcessEventHandler&lt;Test&gt;(&amp;mainWin,
        MainWindow::ShowProgress));</pre>
<h2>Other events</h2>
<p> Getting back to the ProcessBase and Sequence classes,
there are several other events that you may wish to fire. One of the
most useful events is after the Cleanup() function has finished,
particularly for instances of the Sequence class. Think of the startup
sequence. Until the sequence is finished, menu items and the like
will need to be disabled, they will need to be enabled once it's
finished. Given that the code that kicks off the sequence will have
finished long ago, an event is the best place to do this.</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
