00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef _GEDDEI_BUFFERDATA_H
00011 #define _GEDDEI_BUFFERDATA_H
00012
00013 #include <iostream>
00014 #include <cassert>
00015 using namespace std;
00016
00017 #include <qmap.h>
00018 #include <qmutex.h>
00019 #include <qvaluevector.h>
00020
00021 #ifdef __GEDDEI_BUILD
00022 #include "bufferinfo.h"
00023 #include "signaltype.h"
00024 #include "globals.h"
00025 #else
00026 #include <geddei/bufferinfo.h>
00027 #include <geddei/signaltype.h>
00028 #include <geddei/globals.h>
00029 #endif
00030 using namespace Geddei;
00031
00032 namespace Geddei
00033 {
00034
00035 class Buffer;
00036 class LRConnection;
00037 class Splitter;
00038 class BufferData;
00039 class Auxilliary;
00040
00041 typedef BufferInfo *BufferID;
00042
00055 class Auxilliary
00056 {
00057 public:
00064 virtual void forget(const BufferData &) = 0;
00065
00072 virtual void activate(const BufferData &) = 0;
00073
00077 virtual ~Auxilliary() {}
00078 };
00079
00092 class ScratchOwner: public Auxilliary
00093 {
00094 public:
00100 virtual void pushScratch(const BufferData &) = 0;
00101
00108 virtual void forgetScratch(const BufferData &) = 0;
00109
00110 void forget(const BufferData &i) { forgetScratch(i); }
00111 void activate(const BufferData &i) { pushScratch(i); }
00112
00116 virtual ~ScratchOwner() {}
00117 };
00118
00132 class ScreenOwner: public Auxilliary
00133 {
00134 public:
00141 virtual void haveRead(const BufferData &) = 0;
00142
00149 virtual void forgetRead(const BufferData &) = 0;
00150
00151 void forget(const BufferData &i) { forgetRead(i); }
00152 void activate(const BufferData &i) { haveRead(i); }
00153
00157 virtual ~ScreenOwner() {}
00158 };
00159
00187 class BufferData
00188 {
00189 static BufferData *theFake;
00190
00191
00192
00193
00194
00195 BufferInfo *theInfo;
00196
00197
00198
00199
00200
00201 uint theVisibleSize, theOffset;
00202
00203 float *theWritePointer;
00204
00205 friend class Buffer;
00206 friend class BufferReader;
00207 friend class RLConnection;
00208 friend class LxConnection;
00209 friend class LLConnection;
00210 friend class LRConnection;
00211 friend class DRCoupling;
00212 friend class RSCoupling;
00213 friend ostream &operator<<(ostream &out, const BufferData &me);
00214
00215 friend class Splitter;
00216 void adopt(ScratchOwner *aux) { theInfo->theAux = aux; }
00217
00223 const bool rollsOver() const { return theOffset + theVisibleSize - 1 > theInfo->theMask; }
00224 const uint sizeOnlyPart() const { return theVisibleSize; }
00225 const uint sizeFirstPart() const { return (theInfo->theMask + 1) - theOffset; }
00226 const uint sizeSecondPart() const { return theOffset + theVisibleSize - (theInfo->theMask + 1); }
00227 const float *firstPart() const { return theInfo->theData + theOffset; }
00228 float *firstPart() { return theInfo->theData + theOffset; }
00229 const float *secondPart() const { return theInfo->theData; }
00230 float *secondPart() { return theInfo->theData; }
00235 BufferData &dontRollOver(const bool makeCopy = false);
00236 const BufferData &dontRollOver(const bool makeCopy = true) const;
00237
00247 void invalidate() const { theInfo->theValid = false; }
00248
00256 void ignoreDeath() const { theInfo->theEndType = BufferInfo::Ignore; }
00257
00258 BufferData(uint size, uint scope, float *data, ScratchOwner *scratch = 0, BufferInfo::Legacy endType = BufferInfo::Ignore, uint offset = 0, uint mask = 0xffffffff);
00259 BufferData(uint size, uint scope, float *data, ScreenOwner *screen = 0, BufferInfo::Legacy endType = BufferInfo::Ignore, uint offset = 0, uint mask = 0xffffffff);
00260
00261 BufferData(BufferInfo *info, const uint offset);
00262
00263 public:
00267 void debugInfo() const;
00268
00272 static BufferData &fake();
00273
00278 const BufferID identity() const { return theInfo; }
00279
00287 BufferInfo *info() { return theInfo; }
00288
00296 const BufferInfo *info() const { return theInfo; }
00297
00309 void copyFrom(const BufferData &source);
00310
00317 void copyFrom(const float *source);
00318
00325 void copyTo(float *destination) const;
00326
00333 const bool plunger() const;
00334
00345 const uint elements() const { return theVisibleSize; }
00346
00352 const uint scope() const { return theInfo->theScope; }
00353
00359 const uint samples() const { return theVisibleSize / theInfo->theScope; }
00360
00380 const BufferData mid(const uint start, const uint length) const;
00381
00401 BufferData mid(const uint start, const uint length);
00402
00416 const BufferData sample(const uint index) const;
00417
00431 BufferData sample(const uint index);
00432
00449 const BufferData samples(const uint index, const uint amount) const;
00450
00467 BufferData samples(const uint index, const uint amount);
00468
00474 const bool isValid() const { return theInfo->theValid; }
00475
00483 void nullify() { *this = BufferData(true); }
00484
00491 const bool isNull() const { return theInfo->theValid && theInfo->theAccessibleSize == Undefined; }
00492
00506 const float &operator()(const uint i, const uint j) const
00507 {
00508 #ifdef EDEBUG
00509 assert(theInfo->theValid);
00510 assert(i * theInfo->theScope + j < theVisibleSize);
00511 assert(j < theInfo->theScope || !theInfo->theScope);
00512 #endif
00513 return theInfo->theData[(i * theInfo->theScope + j + theOffset) & theInfo->theMask];
00514 }
00515
00529 float &operator()(const uint i, const uint j)
00530 {
00531 #ifdef EDEBUG
00532 assert(theInfo->theValid);
00533 assert(i * theInfo->theScope + j < theVisibleSize);
00534 assert(j < theInfo->theScope || !theInfo->theScope);
00535 if(theInfo->theType == BufferInfo::Read)
00536 qWarning("*** WARNING: You should use a _const_ BufferData object for all reads, or you\n"
00537 " might accidentally taint the data.\n");
00538 if(theWritePointer)
00539 qWarning("*** WARNING: You still have a borrowed array active. Changing any data before\n"
00540 " that has been returned will not do anything.\n");
00541 #endif
00542 return theInfo->theData[(i * theInfo->theScope + j + theOffset) & theInfo->theMask];
00543 }
00544
00559 float &operator[](const uint i)
00560 {
00561 #ifdef EDEBUG
00562 assert(i < theVisibleSize);
00563 assert(theInfo->theValid);
00564 if(theInfo->theType == BufferInfo::Read)
00565 qWarning("*** WARNING: You should use a _const_ BufferData object for all reads, or you\n"
00566 " might accidentally taint the data.\n");
00567 if(theWritePointer)
00568 qWarning("*** WARNING: You still have a borrowed array active. Changing any data before\n"
00569 " that has been returned will not do anything.\n");
00570 #endif
00571 return theInfo->theData[(i + theOffset) & theInfo->theMask];
00572 }
00573
00588 const float &operator[](const uint i) const
00589 {
00590 #ifdef EDEBUG
00591 assert(i < theVisibleSize);
00592 assert(theInfo->theValid);
00593 #endif
00594 return theInfo->theData[(i + theOffset) & theInfo->theMask];
00595 }
00596
00620 const float *readPointer() const
00621 {
00622 #ifdef EDEBUG
00623 assert(theInfo->theValid);
00624 #endif
00625 if(theInfo->theAccessibleSize == Undefined) return 0;
00626 dontRollOver(true);
00627 return &(theInfo->theData[theOffset]);
00628 }
00629
00679 float *writePointer()
00680 {
00681 #ifdef EDEBUG
00682 assert(theInfo->theValid);
00683 if(theInfo->theType == BufferInfo::Read)
00684 qWarning("*** WARNING: You should use a _const_ BufferData object for all read, or you\n"
00685 " might accidentally taint the data.\n");
00686 #endif
00687 if(theInfo->theAccessibleSize == Undefined) return 0;
00688 if(!rollsOver()) return theInfo->theData + theOffset;
00689
00690 if(!theWritePointer)
00691 theWritePointer = new float[theVisibleSize];
00692 return theWritePointer;
00693 }
00694
00701 void endWritePointer()
00702 {
00703 if(theWritePointer)
00704 copyFrom(theWritePointer);
00705 delete theWritePointer;
00706 theWritePointer = 0;
00707 }
00708
00727 BufferData &operator=(const BufferData &source);
00728
00735 BufferData(const bool valid = false);
00736
00748 BufferData(const uint size, const uint scope = 1);
00749
00763 BufferData(const float *data, const uint size, const uint scope = 1);
00764
00777 BufferData(float *data, const uint size, const uint scope = 1);
00778
00787 BufferData(const BufferData &source);
00788
00792 ~BufferData();
00793 };
00794
00795 }
00796
00797 #endif