00001 #ifndef _STR_ProcessorModule_H_ // -*-c++-*-
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef __GNUG__
00022 # pragma interface
00023 #endif
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
00051
00052
00053
00054 class ProcessorModule : public StreamModule
00055 {
00056 class PMPlug;
00057 friend class PMPlug;
00058 public:
00059 static const STR_ClassIdent identifier;
00060
00061
00062 enum PlugSide {
00063 OneSide,
00064 OtherSide
00065 };
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 inline ProcessorModule(StreamProcessor &from_one,
00084 StreamProcessor &from_other,
00085 bool own = true);
00086
00087
00088
00089
00090
00091
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
00150
00151
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
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 };
00228 };
00229
00230 #endif