00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _TokenDelay_
00025 #define _TokenDelay_
00026
00027 #include "Processing.hxx"
00028 #include "InControl.hxx"
00029 #include "InPort.hxx"
00030 #include "OutPort.hxx"
00031 #include "Component.hxx"
00032 #include "Enum.hxx"
00033 #include <string>
00034 #include <deque>
00035
00036 #include "Array.hxx"
00037
00038 namespace CLAM
00039 {
00040
00041
00046 class TokenDelayConfig : public ProcessingConfig
00047 {
00048 public:
00049 DYNAMIC_TYPE_USING_INTERFACE (TokenDelayConfig, 2, ProcessingConfig);
00050 DYN_ATTRIBUTE (0, public, unsigned, Delay);
00051 DYN_ATTRIBUTE (1, public, unsigned, MaxDelay );
00052 protected:
00058 void DefaultInit(void)
00059 {
00060 AddDelay();
00061 AddMaxDelay();
00062 UpdateData();
00063 SetDelay(0);
00064 SetMaxDelay(1);
00065 }
00066
00067 };
00068
00081 template <class T> class TokenDelay : public Processing
00082 {
00083
00084 private:
00086 TokenDelayConfig mConfig;
00087
00088 InPort<T> mInput;
00089 OutPort<T> mOutput;
00090 InControl mDelayControl;
00091
00092 public:
00093 TokenDelay(const TokenDelayConfig& cfg = TokenDelayConfig() ) :
00094 mInput ("In", this),
00095 mOutput ("Out", this),
00096 mDelayControl("Delay Control", this),
00097 mCapacity(0)
00098 {
00099 Configure(cfg);
00100 }
00101 virtual ~TokenDelay<T>() {};
00102
00108 bool ConcreteConfigure(const ProcessingConfig& c);
00109
00113 virtual const ProcessingConfig &GetConfig() const { return mConfig;}
00118 virtual bool Do(void);
00119
00129 virtual bool Do(const T & in, T& out);
00130
00131
00132
00135 void Debug() const;
00139 void FulfillsInvariant() const;
00140
00141 const char *GetClassName() const {return "TokenDelay";}
00142
00146 TSize RealDelay() const {
00147 return mTokenQueue.size();
00148 }
00149
00150 unsigned MaxDelay() const {
00151 return mCapacity;
00152 }
00153
00154 unsigned GivenDelay() {
00155
00156 return CastDelayControlValue(mDelayControl.GetLastValue());
00157 }
00158
00159 private:
00165 virtual void Discard(T* toDiscard);
00166
00170 unsigned CastDelayControlValue(TControlData readControlValue);
00175 void UpdateBuffersToDelay();
00176 void WriteNewSample(const T& in);
00177 void ReadCurrentSample(T& out);
00178
00179
00180
00181 std::vector<T> mTokenQueue;
00182 unsigned mReadPointer;
00183 unsigned mWritePointer;
00185 unsigned mCapacity;
00187 unsigned mGivenDelay;
00189 unsigned mLastDelay;
00190
00191 };
00192
00193
00194
00196
00197
00198
00199 #include "Err.hxx"
00200
00201 template <class T>
00202 void TokenDelay<T>::Discard(T* toDiscard) {
00203 CLAM_ASSERT(toDiscard, "TokenDelay: Discarding a null pointer");
00204 delete toDiscard;
00205 }
00206
00207 template <class T>
00208 bool TokenDelay<T>::ConcreteConfigure(const ProcessingConfig& c)
00209 {
00210 CopyAsConcreteConfig(mConfig, c);
00211 mCapacity = mConfig.GetMaxDelay();
00212 mDelayControl.DoControl(TControlData(mConfig.GetDelay()));
00213 mGivenDelay = CastDelayControlValue(mDelayControl.GetLastValue());
00214 mTokenQueue.resize(mCapacity);
00215 mWritePointer = 0;
00216 mReadPointer = -mGivenDelay;
00217 return true;
00218 }
00219
00220
00221 template <class T>
00222 bool TokenDelay<T>::Do(void)
00223 {
00224 Do(mInput.GetData(), mOutput.GetData());
00225 mInput.Consume();
00226 mOutput.Produce();
00227 return false;
00228 }
00229
00230 template <class T>
00231 unsigned TokenDelay<T>::CastDelayControlValue(TControlData readControlValue) {
00232 if (readControlValue > mCapacity) return mCapacity;
00233 if (readControlValue < 0) return 0;
00234 return unsigned(readControlValue);
00235 }
00236
00237 template <class T>
00238 bool TokenDelay<T>::Do(const T& in, T& out)
00239
00240 {
00241
00242 mLastDelay = mGivenDelay;
00243 mGivenDelay = CastDelayControlValue(mDelayControl.GetLastValue());
00244
00245 if (mLastDelay != mGivenDelay)
00246 UpdateBuffersToDelay();
00247 WriteNewSample(in);
00248 ReadCurrentSample(out);
00249 return true;
00250 }
00251
00252 template <class T>
00253 void TokenDelay<T>::WriteNewSample(const T& in)
00254 {
00255 mTokenQueue[mWritePointer] = in;
00256 mWritePointer++;
00257 if(mWritePointer==mCapacity) mWritePointer=0;
00258
00259 }
00260
00261
00262 template <class T>
00263 void TokenDelay<T>::ReadCurrentSample(T& out)
00264 {
00265 CLAM_DEBUG_ASSERT(mReadPointer>0, "Trying to read outside buffer");
00266 int oldReadPointer = mReadPointer;
00267 mReadPointer++;
00268 if(mReadPointer==mCapacity) mReadPointer=0;
00269 out = mTokenQueue[oldReadPointer];
00270 }
00271
00272
00273
00274
00275 template <class T>
00276 void TokenDelay<T>::UpdateBuffersToDelay()
00277 {
00278 mWritePointer = mReadPointer + CastDelayControlValue(mGivenDelay);
00279 if(mWritePointer>=mCapacity) mWritePointer-=mCapacity;
00280 return;
00281 }
00282
00283
00284 template <class T>
00285 void TokenDelay<T>::Debug() const
00286 {
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 }
00299
00300 template <class T>
00301 void TokenDelay<T>::FulfillsInvariant() const
00302 {
00303
00304
00305
00306
00307
00308
00309
00310
00311 }
00312
00313
00314
00315 class ETokenDelayControls
00316 : public Enum
00317 {
00318
00319 public:
00320 ETokenDelayControls() : Enum( ValueTable(), delay ) { }
00321 ETokenDelayControls( tValue v ) : Enum( ValueTable(), v ) { }
00322 ETokenDelayControls( std::string s ) : Enum( ValueTable(), s ) { }
00323 ~ETokenDelayControls() { }
00324 Component* Species() const
00325 {
00326 return new ETokenDelayControls;
00327 }
00328
00329 typedef enum
00330 {
00331 delay = 0
00332 } tEnum;
00333 static tEnumValue * ValueTable()
00334 {
00335 static tEnumValue sEnumValues[] =
00336 {
00337 { delay, "delay" },
00338 { 0, NULL }
00339 };
00340 return sEnumValues;
00341 }
00342
00343 };
00344
00345 };
00346
00347
00348
00349 #endif //_TokenDelay_