00001 #ifndef _STR_StreamSplitter_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 #include <cstddef>
00032 #ifndef _STR_STR_ClassIdent_H_
00033 # include <StrMod/STR_ClassIdent.h>
00034 #endif
00035 #ifndef _STR_StrChunkPtr_H_
00036 # include <StrMod/StrChunkPtr.h>
00037 #endif
00038 #ifndef _STR_StreamModule_H_
00039 # include <StrMod/StreamModule.h>
00040 #endif
00041
00042 #define _STR_StreamSplitter_H_
00043
00044 namespace strmod {
00045 namespace strmod {
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 class StreamSplitterModule : public StreamModule
00074 {
00075 public:
00076 static const STR_ClassIdent identifier;
00077
00078
00079 StreamSplitterModule();
00080
00081 virtual ~StreamSplitterModule();
00082
00083
00084 enum Sides {
00085 SideIn,
00086 SideOut,
00087 SideBiDir
00088 };
00089
00090 inline virtual bool canCreate(int side) const;
00091 virtual bool deletePlug(Plug *plug);
00092 inline virtual bool ownsPlug(const Plug *p) const;
00093
00094 protected:
00095 class SPPlug;
00096 friend class SPPlug;
00097
00098
00099
00100
00101 class SPPlug : public Plug {
00102 friend class StreamSplitterModule;
00103 public:
00104 static const STR_ClassIdent identifier;
00105
00106 SPPlug(StreamSplitterModule &p, Sides s) : Plug(p), side_(s) { }
00107 virtual ~SPPlug() { }
00108
00109 inline StreamSplitterModule &getParent() const;
00110
00111 virtual int side() const { return(side_); }
00112
00113 protected:
00114 virtual const lcore::ClassIdent *i_GetIdent() const {
00115 return &identifier;
00116 }
00117
00118 virtual const StrChunkPtr i_Read();
00119 virtual void i_Write(const StrChunkPtr &ptr);
00120
00121 inline virtual bool needsNotifyReadable() const;
00122 inline virtual bool needsNotifyWriteable() const;
00123
00124 virtual void otherIsReadable();
00125 virtual void otherIsWriteable();
00126
00127 inline SPPlug *getReadPartner() const;
00128 inline SPPlug *getWritePartner() const;
00129
00130 private:
00131 Sides side_;
00132 };
00133
00134 virtual const lcore::ClassIdent *i_GetIdent() const { return &identifier; }
00135
00136
00137
00138
00139
00140
00141 virtual void plugDisconnected(Plug *plug);
00142
00143 virtual Plug *i_MakePlug(int side);
00144
00145 private:
00146 struct {
00147 int inmade : 1;
00148 int outmade : 1;
00149 int bimade : 1;
00150 } flags_;
00151 SPPlug inplug_;
00152 SPPlug outplug_;
00153 SPPlug biplug_;
00154 };
00155
00156
00157
00158 bool StreamSplitterModule::canCreate(int side) const
00159 {
00160 switch (side) {
00161 case SideIn:
00162 return(flags_.inmade == 0);
00163 case SideOut:
00164 return(flags_.outmade == 0);
00165 case SideBiDir:
00166 return(flags_.bimade == 0);
00167 default:
00168 return(false);
00169 }
00170 }
00171
00172 inline bool StreamSplitterModule::ownsPlug(const Plug *p) const
00173 {
00174 return((flags_.inmade && (&inplug_ == p))
00175 || (flags_.outmade && (&outplug_ == p))
00176 || (flags_.bimade && (&biplug_ == p)));
00177 }
00178
00179
00180
00181 inline StreamSplitterModule &StreamSplitterModule::SPPlug::getParent() const
00182 {
00183 return(static_cast<StreamSplitterModule &>(Plug::getParent()));
00184 }
00185
00186 inline bool StreamSplitterModule::SPPlug::needsNotifyReadable() const
00187 {
00188 return((side_ == SideIn) || (side_ == SideBiDir));
00189 }
00190
00191 inline bool StreamSplitterModule::SPPlug::needsNotifyWriteable() const
00192 {
00193 return((side_ == SideOut) || (side_ == SideBiDir));
00194 }
00195
00196 inline StreamSplitterModule::SPPlug *
00197 StreamSplitterModule::SPPlug::getReadPartner() const
00198 {
00199 switch (side_)
00200 {
00201 case SideOut:
00202 return(&(getParent().biplug_));
00203 case SideBiDir:
00204 return(&(getParent().inplug_));
00205 case SideIn:
00206 default:
00207 return(NULL);
00208 }
00209 }
00210
00211 inline StreamSplitterModule::SPPlug *
00212 StreamSplitterModule::SPPlug::getWritePartner() const
00213 {
00214 switch (side_)
00215 {
00216 case SideIn:
00217 return(&(getParent().biplug_));
00218 case SideBiDir:
00219 return(&(getParent().outplug_));
00220 case SideOut:
00221 default:
00222 return(NULL);
00223 }
00224 }
00225
00226 };
00227 };
00228
00229 #endif