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

ProcessorModule.h

00001 #ifndef _STR_ProcessorModule_H_  // -*-c++-*-
00002 
00003 /*
00004  * Copyright 1991-9 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++/StrMod/StrMod/ProcessorModule.h,v 1.8 2002/08/29 00:58:04 hopper Exp $ */
00026 
00027 // For a log, see ../Changelog
00028 //
00029 // Revision 1.2  1996/09/21 18:38:21  hopper
00030 // Added forward declaration of class ProcessorModule::Plug, presumably to
00031 // work around a compiler bug.
00032 //
00033 // Revision 1.1  1996/09/02 23:31:20  hopper
00034 // Added class that would turn two StreamProcessors into a StreamModule
00035 // that used one StreamProcessor for the data flowing in each direction.
00036 //
00037 
00038 #include <StrMod/STR_ClassIdent.h>
00039 #include <StrMod/StreamModule.h>
00040 #include <cassert>
00041 
00042 #define _STR_ProcessorModule_H_
00043 
00044 namespace strmod {
00045 namespace strmod {
00046 
00047 class StrChunkPtr;
00048 class StreamProcessor;
00049 
00050 /** \class ProcessorModule ProcessorModule.h StrMod/ProcessorModule.h
00051  * This wraps two objects that follow the unidirectional StreamProcessor
00052  * interface in a StreamModule interface.
00053  */
00054 class ProcessorModule : public StreamModule
00055 {
00056    class PMPlug;
00057    friend class PMPlug;
00058  public:
00059    static const STR_ClassIdent identifier;
00060 
00061    //! Labels for the sides of this StreamModule implementation
00062    enum PlugSide {
00063       OneSide,  //!< Distinguishable name.
00064       OtherSide //!< Another distinguishable name.
00065    };
00066 
00067    /** Construct a ProcessorModule from the two given StreamProcessor objects.
00068     *
00069     * @param from_one The StreamProcessor that will process data going from
00070     * OneSide to OtherSide.
00071     *
00072     * @param from_other The StreamProcessor that will process data going from
00073     * OtherSide to OneSide.
00074     *
00075     * @param own Whether or not this module 'owns' or assumes the duty of
00076     * deleting the two passed in StreamProcessor objects.
00077     *
00078     * \note If \c own is \c false, it's your responsibility to make sure the
00079     * ProcessorModule goes away before the StreamProcessors do.  If you're
00080     * building a derived class, ~ProccesorModule is guaranteed not to require
00081     * the StreamProcessors to exist if \c own is \c false.
00082     */
00083    inline ProcessorModule(StreamProcessor &from_one,
00084                           StreamProcessor &from_other,
00085                           bool own = true);
00086 
00087    /** Destruct a ProcessorModule, possibly deleting the associated
00088     * StreamProcessor objects.
00089     *
00090     * If created with \c own equal to \c false, this function guaranteed not to
00091     * require subsidiary StreamProcessors to exist.
00092     */
00093    virtual ~ProcessorModule()                           { }
00094 
00095    inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00096 
00097    inline virtual bool canCreate(int side) const;
00098 
00099    inline virtual bool ownsPlug(const Plug *plug) const;
00100 
00101    virtual bool deletePlug(Plug *plug);
00102 
00103  protected:
00104    virtual const lcore::ClassIdent *i_GetIdent() const  { return &identifier; }
00105 
00106    inline virtual Plug *i_MakePlug(int side);
00107 
00108  private:
00109    class PMPlug : public Plug {
00110       friend class ProcessorModule;
00111 
00112     public:
00113       static const STR_ClassIdent identifier;
00114 
00115       inline PMPlug(ProcessorModule &prnt, Plug &sibling, PlugSide side,
00116                     StreamProcessor &readproc, StreamProcessor &writeproc);
00117       virtual ~PMPlug();
00118 
00119       inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00120 
00121       inline ProcessorModule &getParent() const;
00122 
00123       inline virtual int side() const                   { return(side_); }
00124 
00125     protected:
00126       virtual const lcore::ClassIdent *i_GetIdent() const {
00127          return &identifier;
00128       }
00129 
00130       virtual const StrChunkPtr i_Read();
00131       virtual void i_Write(const StrChunkPtr &chnk);
00132 
00133    private:
00134       Plug &sibling_;
00135       const PlugSide side_;
00136       StreamProcessor &readproc_;
00137       StreamProcessor &writeproc_;
00138    };
00139 
00140    PMPlug side_;
00141    PMPlug otherside_;
00142    struct {
00143       bool side : 1;
00144       bool otherside : 1;
00145       bool owns : 1;
00146    } pulled_;
00147 };
00148 
00149 //-----------------------------inline functions--------------------------------
00150 
00151 //----------ProcessorModule::PMPlug inlines-----
00152 
00153 inline int ProcessorModule::PMPlug::AreYouA(const lcore::ClassIdent &cid) const
00154 {
00155    return((identifier == cid) || Plug::AreYouA(cid));
00156 }
00157 
00158 inline ProcessorModule &ProcessorModule::PMPlug::getParent() const
00159 {
00160    return(static_cast<ProcessorModule &>(Plug::getParent()));
00161 }
00162 
00163 inline ProcessorModule::PMPlug::PMPlug(ProcessorModule &prnt, Plug &sibling,
00164                                        PlugSide side,
00165                                        StreamProcessor &readproc,
00166                                        StreamProcessor &writeproc)
00167      : Plug(prnt), sibling_(sibling), side_(side),
00168        readproc_(readproc), writeproc_(writeproc)
00169 {
00170 }
00171 
00172 //----------ProcessorModule inlines-----
00173 
00174 inline ProcessorModule::ProcessorModule(StreamProcessor &from_one,
00175                                         StreamProcessor &from_other,
00176                                         bool own)
00177      : side_(*this, otherside_, OneSide, from_other, from_one),
00178        otherside_(*this, side_, OtherSide, from_one, from_other)
00179 {
00180    assert(&from_one != &from_other);
00181    pulled_.side = pulled_.otherside = false;
00182    pulled_.owns = own;
00183    side_.setWriteable(true);
00184    otherside_.setWriteable(true);
00185 }
00186 
00187 inline int ProcessorModule::AreYouA(const lcore::ClassIdent &cid) const
00188 {
00189    return((identifier == cid) || StreamModule::AreYouA(cid));
00190 }
00191 
00192 inline bool ProcessorModule::canCreate(int side) const
00193 {
00194    assert((side == OneSide) || (side == OtherSide));
00195    return((side == OneSide) ? !pulled_.side : !pulled_.otherside);
00196 }
00197 
00198 inline bool ProcessorModule::ownsPlug(const Plug *plug) const
00199 {
00200    const Plug * const sidep = &side_;
00201    const Plug * const othersidep = &otherside_;
00202 
00203    return((plug == sidep && pulled_.side) ||
00204           (plug == othersidep && pulled_.otherside));
00205 }
00206 
00207 inline StreamModule::Plug *ProcessorModule::i_MakePlug(int side)
00208 {
00209    assert((side == OneSide) || (side == OtherSide));
00210    if ((side == OneSide) && (!pulled_.side))
00211    {
00212       pulled_.side = true;
00213       return(&side_);
00214    }
00215    else if ((side == OtherSide) && (!pulled_.otherside))
00216    {
00217       pulled_.otherside = true;
00218       return(&otherside_);
00219    }
00220    else
00221    {
00222       assert(false);
00223       return(0);
00224    }
00225 }
00226 
00227 };  // namespace strmod
00228 };  // namespace strmod
00229 
00230 #endif

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