00001 #ifndef _STR_RouterModule_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 #include <cstddef>
00030 #include <iterator>
00031 #include <deque>
00032 #include <StrMod/STR_ClassIdent.h>
00033 #include <StrMod/StreamModule.h>
00034
00035 #define _STR_RouterModule_H_
00036
00037 namespace strmod {
00038 namespace unievent {
00039 class Dispatcher;
00040 };
00041 };
00042
00043 namespace strmod {
00044 namespace strmod {
00045
00046
00047
00048
00049
00050 class RouterModule : public StreamModule
00051 {
00052 protected:
00053 class RPlug;
00054 friend class RPlug;
00055
00056 typedef std::deque<RPlug *> RPlugList;
00057
00058 typedef std::back_insert_iterator<RPlugList> RPlugAdder;
00059
00060 public:
00061 static const STR_ClassIdent identifier;
00062
00063
00064 explicit RouterModule(unievent::Dispatcher &disp);
00065
00066 virtual ~RouterModule();
00067
00068 virtual int AreYouA(const lcore::ClassIdent &cid) const {
00069 return((identifier == cid) || StreamModule::AreYouA(cid));
00070 }
00071
00072 virtual bool canCreate(int side) const = 0;
00073
00074 virtual bool ownsPlug(const Plug *plug) const;
00075
00076 virtual bool deletePlug(Plug *plug);
00077
00078 protected:
00079 virtual const lcore::ClassIdent *i_GetIdent() const { return &identifier; }
00080
00081 virtual Plug *i_MakePlug(int side) = 0;
00082
00083
00084
00085
00086 void addNewPlug(RPlug *rp);
00087
00088
00089
00090
00091
00092
00093 inline void postScan();
00094
00095
00096
00097
00098
00099
00100
00101
00102 virtual void getDestinations(const StrChunkPtr &chunk,
00103 const RPlug &source,
00104 const RPlugList::const_iterator &begin,
00105 const RPlugList::const_iterator &end,
00106 RPlugAdder &destlist) const = 0;
00107
00108 private:
00109 class ScanEvent;
00110 friend class ScanEvent;
00111 unievent::Dispatcher &disp_;
00112 bool scan_posted_;
00113 ScanEvent * const scan_;
00114 bool inroutingdone_;
00115 RPlugList allplugs_;
00116 RPlugList writeable_;
00117 RPlugList nonwriteable_;
00118 StrChunkPtr routedchunk_;
00119 size_t outgoingcopies_;
00120
00121
00122 void doPost();
00123 void doScan();
00124
00125 void routingDone();
00126 void processIncoming(RPlug &source, const StrChunkPtr &chunk);
00127 };
00128
00129
00130
00131 class RouterModule::RPlug : public StreamModule::Plug {
00132 friend class RouterModule;
00133 public:
00134 static const STR_ClassIdent identifier;
00135
00136 inline virtual int AreYouA(const lcore::ClassIdent &cid) const {
00137 return((identifier == cid) || Plug::AreYouA(cid));
00138 }
00139
00140 inline RouterModule &getParent() const;
00141
00142 virtual int side() const = 0;
00143
00144
00145 bool getDeleted() const { return(deleted_); }
00146
00147
00148 void setDeleted() { deleted_ = true; }
00149
00150 protected:
00151 inline RPlug(RouterModule &parent);
00152
00153 virtual const lcore::ClassIdent *i_GetIdent() const { return &identifier; }
00154
00155 virtual const StrChunkPtr i_Read();
00156 virtual void i_Write(const StrChunkPtr &ptr);
00157
00158 private:
00159 bool deleted_;
00160 };
00161
00162
00163
00164 inline void RouterModule::postScan()
00165 {
00166 if (!scan_posted_)
00167 {
00168 scan_posted_ = true;
00169 doPost();
00170 }
00171 }
00172
00173
00174
00175 inline RouterModule &RouterModule::RPlug::getParent() const
00176 {
00177 return static_cast<RouterModule &>(Plug::getParent());
00178 }
00179
00180 inline RouterModule::RPlug::RPlug(RouterModule &parent)
00181 : Plug(parent), deleted_(false)
00182 {
00183 }
00184
00185 };
00186 };
00187
00188 #endif