Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

Dispatcher.h

00001 #ifndef _UNEVT_Dispatcher_H_  // -*-c++-*-
00002 
00003 /*
00004  * Copyright 1991-2002 Eric M. Hopper <hopper@omnifarious.org>
00005  * 
00006  *     This program is free software; you can redistribute it and/or modify it
00007  *     under the terms of the GNU Lesser General Public License as published
00008  *     by the Free Software Foundation; either version 2 of the License, or
00009  *     (at your option) any later version.
00010  * 
00011  *     This program is distributed in the hope that it will be useful, but
00012  *     WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *     Lesser General Public License for more details.
00015  * 
00016  *     You should have received a copy of the GNU Lesser General Public
00017  *     License along with this program; if not, write to the Free Software
00018  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #ifdef __GNUG__
00022 #  pragma interface
00023 #endif
00024 
00025 /* $Header: /home/hopper/src/cvs/C++/UniEvent/UniEvent/Dispatcher.h,v 1.18 2002/08/29 00:58:05 hopper Exp $ */
00026 
00027 // For log see ../ChangeLog
00028 
00029 #include <LCore/Protocol.h>
00030 #include <UniEvent/UNEVT_ClassIdent.h>
00031 
00032 #define _UNEVT_Dispatcher_H_
00033 
00034 namespace strmod {
00035 namespace unievent {
00036 
00037 class EventPtr;
00038 
00039 /** \class Dispatcher Dispatcher.h UniEvent/Dispatcher.h
00040  * \brief An interface for a simple queuer and dispatcher of events.
00041  *
00042  * This provides an interface for classes that want to implement a queue of
00043  * Event objects that are removed from the queue in FIFO order and 'fired' by
00044  * calling their triggerEvent methods.
00045  */
00046 class Dispatcher : virtual public lcore::Protocol
00047 {
00048  public:
00049    static const UNEVT_ClassIdent identifier;
00050 
00051    //! Because every class (even abstract ones) should have a constructor.
00052    Dispatcher()                                     { }
00053    //! Because abstract classes should have a virtual destructor.
00054    virtual ~Dispatcher()                            { }
00055 
00056    inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00057 
00058    //! Add an event to the queue.
00059    virtual void addEvent(const EventPtr &ev) = 0;
00060 
00061    /**
00062     * Add an event that will be posted to poll something if the queue is busy.
00063     *
00064     * The Dispatcher maintains the concept of <em>external</em>
00065     * and <em>internal</em> events.  External events are those posted by the
00066     * addEvent function.  Internal events are those posted in response to some
00067     * internal condition.
00068     *
00069     * When external events cause other external events to be added, busy loops
00070     * can take over the system.  In order to prevent this, an event from this
00071     * queue will be posted if the queue contains only external events.
00072     *
00073     * Events in this queue should query some outside event source for events and
00074     * use addEvent to add any there may be.  <strong>Under no circumstance
00075     * should one of these events <em>always</em> cause events to be added
00076     * through addEvent.</strong> Doing this would just propogate the bad busy
00077     * loop behavior.
00078     */
00079    virtual void addBusyPollEvent(const EventPtr &ev) = 0;
00080 
00081    /**
00082     * \brief This event is only triggered whenever an event dispatch is
00083     * attempted when there's an empty queue.
00084     *
00085     * @param ev The event to fire when the queue is empty.
00086     * @return <code>true</code> if the event was successfully set,
00087     * <code>false</code> if the event was not set because some other event was
00088     * already set.
00089     */
00090    virtual bool onQueueEmpty(const EventPtr &ev) = 0;
00091 
00092    /**
00093     * \brief This event is only triggered when interrupt() is called.
00094     *
00095     * When interrupt() is called, a flag is set so this event is put onto the
00096     * front of the queue as soon as the Dispatcher's event loop gets control
00097     * again.
00098     *
00099     * @param ev The event to fire when interrupt() is called.
00100     * @return <code>true</code> if the event was successfully set,
00101     * <code>false</code> if the event was not set because some other event was
00102     * already set.
00103     */
00104    virtual bool onInterrupt(const EventPtr &ev) = 0;
00105 
00106    //! Dispatch a single event.
00107    inline void dispatchEvent(Dispatcher *enclosing = 0);
00108 
00109    /**
00110     * \brief Dispatch until a certain number of events have been dispatched, or
00111     * the queue is empty.
00112    */
00113    virtual void dispatchEvents(unsigned int numevents,
00114                                Dispatcher *enclosing = 0) = 0;
00115    //! Dispatch until the queue is empty.
00116    virtual void dispatchUntilEmpty(Dispatcher *enclosing = 0) = 0;
00117 
00118    /**
00119     * \brief Interrupts the dispatcher to execute a high priority event.
00120     *
00121     * This sets a flag so that as soon as the Dispatcher's event loop gets
00122     * control, the event set by onInterrupt() will be put on the front of the
00123     * queue.  It will also call the Event::interrupt() method of any
00124     * currently executing event.
00125     *
00126     * \note Implementations of this method should be safe to call from a thread
00127     * or a signal handling context.
00128     */
00129    virtual void interrupt() = 0;
00130 
00131    /**
00132     * Cause the multiple event dispatch methods to halt before they normally
00133     * would.
00134     */
00135    virtual void stopDispatching() = 0;
00136    //! Does the queue have any events in it?
00137    virtual bool isQueueEmpty() const = 0;
00138 
00139  protected:
00140    virtual const lcore::ClassIdent *i_GetIdent() const  { return &identifier; }
00141 
00142  private:
00143    //! Purposely left undefined.
00144    Dispatcher(const Dispatcher &b);
00145    //! Purposely left undefined.
00146    const Dispatcher &operator =(const Dispatcher &b);
00147 };
00148 
00149 //-----------------------------inline functions--------------------------------
00150 
00151 inline int Dispatcher::AreYouA(const lcore::ClassIdent &cid) const
00152 {
00153    return((identifier == cid) || Protocol::AreYouA(cid));
00154 }
00155 
00156 inline void Dispatcher::dispatchEvent(Dispatcher *enclosing)
00157 {
00158    dispatchEvents(1, enclosing);
00159 }
00160 
00161 } // namespace unievent
00162 } // namespace strmod
00163 
00164 #endif

Generated on Wed Jan 29 00:32:43 2003 for libNet by doxygen1.3-rc1