bufferdata.h

00001 /***************************************************************************
00002  *   Copyright (C) 2003 by Gav Wood                                        *
00003  *   gav@cs.york.ac.uk                                                     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Library General Public License as       *
00007  *   published by the Free Software Foundation; either version 2 of the    *
00008  *   License, or (at your option) any later version.                       *
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  // The attributes in here belong to the data we reference.
00192  // Changing them will change how all other references act upon the data, and
00193  // when the reference gets destroyed how the Buffer will react.
00194  // As such it should remain generally unchanged.
00195  BufferInfo *theInfo;
00196  
00197  // These are attributes specific to how we view the data.
00198  // Changing them will have no discourse beyond how it is viewed in this class.
00199  // In particular, if the data is written to a buffer, the original aperture
00200  // of the data will be used.
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

Generated on Fri Nov 10 21:58:26 2006 for Exscalibar by  doxygen 1.5.1