casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
AttributeBuffer.h
Go to the documentation of this file.
00001 //# AttributeBuffer.h: Buffer to store Attributes 
00002 //# Copyright (C) 1996,1997,1999,2000,2001,2002
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id$
00027 
00028 #ifndef TRIALDISPLAY_ATTRIBUTEBUFFER_H
00029 #define TRIALDISPLAY_ATTRIBUTEBUFFER_H
00030 
00031 #include <casa/aips.h>
00032 #include <casa/Containers/Block.h>
00033 #include <casa/Arrays/Vector.h>
00034 #include <display/Display/AttValBase.h>
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038 class String;
00039 class AttValBase;
00040 class Attribute;
00041 
00042 
00043 // <summary> Buffer for storing Attributes </summary>
00044 // <use visibility=local>
00045 // 
00046 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00047 // </reviewed>
00048 // 
00049 // <prerequisite>
00050 //   <li> Attributes
00051 // </prerequisite>
00052 //
00053 // <etymology>
00054 //  <em>Buffer</em> for storing <em>Attributes</em>
00055 // </etymology>
00056 //
00057 // <synopsis>
00058 //
00059 // A number of classes in the Display Library have Attributes (ie. 'things'
00060 // that have a name and a value). An AttributeBuffer can be used to store
00061 // these Attributes internally and do some simple operations, like checking if
00062 // a certain Attribute exists etc. An AttributeBuffer has a 'fat' interface
00063 // for creating Attributes and getting the value of them that hides most of
00064 // the type issues and should make it less work for a programmer to handle
00065 // Attributes.
00066 //
00067 // AttributeBuffers can be used for a number of things. First, of course, they
00068 // can be used to store and organize information. For example, a class can
00069 // store its state parameters in an AttributeBuffer for its own
00070 // convenience. By creating a userinterface to its AttributeBuffer, a class
00071 // can create a standard interface to its state. One possibility here is that
00072 // by using Attributes that are constructed using a pointer (see
00073 // AttributeValuePoi or AttributeValuePoiTol) and by defining a userinterface
00074 // in the class to modify the Attributes of that class, one automatically
00075 // creates a <em>direct</em> userinterface to (some of) the internal variables
00076 // of that class. This is used for example in the WorldCanvas. Another point
00077 // is that Attributes can be defined with arbitrary name and on several types,
00078 // so if a class has a userinterface to its AttributeBuffer, a programmer who
00079 // uses that class can define what information is stored in the class at run
00080 // time. For example, if one can register an event handler in a class A, one
00081 // can store information in class A using the Attribute interface of class A.
00082 // The event handler knows where to look for the information (namely in the
00083 // object of class A it is registered in) so it can find it, while the
00084 // class  A does not have to know what kind (name, type,...) information
00085 // is needed by the event handler, but it can still store it.
00086 //
00087 // Another use of AttributeBuffer is that one can use it to store the state of
00088 // something. Later in the program the new state can be compared with the old
00089 // state using the <src>matches</src> member function of AttributeBuffer and
00090 // the appropriate action can be taken. This is for example used in the
00091 // ImageDDImage to decide whether a cache should be flushed or
00092 // not. AttributeBuffers match if all their Attributes match. For the logic of
00093 // matching Attributes, see Attributes. An example may make this clearer:
00094 //
00095 // <srcblock>
00096 //
00097 // // We have an AttributeBuffer to store the old state:
00098 // AttributeBuffer oldState;
00099 // // and store some state information
00100 // oldState.add("stateVar1", state1);
00101 // oldState.add("stateVar2", state2);
00102 // oldState.add("stateVar3", state3);
00103 //        .
00104 //        .
00105 //        .
00106 // // later in the program we want to check if the current state matches the
00107 // // old state
00108 //
00109 // // AttributeBuffer for the new state
00110 // AttributeBuffer newState;
00111 // // and store state (state1, state2 or state3 may have changed)
00112 // newState.add("stateVar1", state1);
00113 // newState.add("stateVar2", state2);
00114 // newState.add("stateVar3", state3);
00115 //
00116 // // now the new an old state can be compared
00117 // if { newState.matches(oldState) }
00118 //   use my cache
00119 // } else {
00120 //   delete the cache and make new one
00121 // }
00122 // </srcblock>
00123 //
00124 // A similar application of AttributeBuffers is the way they are used by the
00125 // WorldCanvasHolder and the DisplayData (and Animator) to define what data is
00126 // displayed on a canvas. To define what is displayed, one sets a number of
00127 // Attributes on the WorldCanvasHolder (where they are called restrictions and
00128 // they are stored in an AttributeBuffer) and possibly a number of Attributes
00129 // on the DisplayData (where they are also called restrictions and also stored
00130 // in an AttributeBuffer). Some DisplayData have already pre-defined
00131 // restrictions (like the ImageDisplayData), but the program can add to these
00132 // at run time. When a refresh of the WorldCanvas happens, only those data are
00133 // displayed for which the buffer of the DisplayData matches that of the
00134 // WorldCanvasHolder. This gives a very easy to use way of defining what is
00135 // displayed, and this is how for example the Animator works (one simply
00136 // changes some restrictions and do a refresh). See Animator for examples.
00137 //
00138 //
00139 // AttributeBuffers can also be used for passing information in a compact and
00140 // generic way. This is used eg. by the WorldCanvasHolder in the sizeControl
00141 // event handling. The WorldCanvasHolder does not have to know what
00142 // information is passed and eg. what type it is. The code there looks like:
00143 //
00144 // <srcblock>
00145 // Bool WorldCanvasHolder::sizeControlEH(WorldCanvas *wCanvas) 
00146 //
00147 //   AttributeBuffer sizeControlAtts; 
00148 //
00149 //    // rewind the List of DisplayDatas registered withe this WorldCanvasHolder
00150 //    displayListIter->toStart();
00151 //  
00152 //    // temp
00153 //    DisplayData *dData;
00154 //
00155 //    // loop over DisplayDatas that are registered
00156 //    while ( !displayListIter->atEnd() ) {
00157 //      // get DisplayData from List and let this displaydata do its sizeControl
00158 //      dData = (DisplayData *) displayListIter->getRight();
00159 //      if ( !dData->sizeControl(*this, sizeControlAtts)) {
00160 //        // something is very wrong so abort refresh
00161 //        return False;
00162 //      }
00163 //      // next DisplayData
00164 //      displayListIter++;
00165 //    }
00166 //
00167 //    // copy the Attributes set by the DisplayData to the WorldCanvas
00168 //    // We don't know what is being set, but we can still set it....
00169 //    wCanvas->setAttributes(sizeControlAtts);
00170 //
00171 //    // things went ok
00172 //    return True;
00173 //  }  
00174 // </srcblock>
00175 // </synopsis>
00176 //
00177 // <example>
00178 // <srcBlock>
00179 // </srcBlock>
00180 // </example>
00181 //
00182 // <motivation> 
00183 //
00184 // For efficient handling of all the Attributes that a class in the Display
00185 // Library can have, a buffer is needed, with an interface that makes handling
00186 // of Attributes relatively easy.
00187 //
00188 // </motivation>
00189 //
00190  
00191 
00192 class AttributeBuffer {
00193 
00194  public:
00195 
00196   // Constructor of empty buffer
00197   AttributeBuffer();
00198 
00199   // Copy constructor. Copy semantics.
00200   AttributeBuffer(const AttributeBuffer& other);
00201 
00202   // Assignement operator
00203   const AttributeBuffer& operator=(const AttributeBuffer& other);
00204   
00205   // Destructor
00206   ~AttributeBuffer();
00207 
00208   // Return number of Attributes in the buffer
00209   Int  nelements() const;
00210   
00211   // Define  new Attributes. If an Attribute of the same name exists, nothing
00212   // happens. If <src>permanent == True</src>, the Attribute cannot be deleted
00213   // from the Buffer.
00214   // <group>
00215   void add(const AttributeBuffer& otherBuf);
00216   void add(const Attribute& newAttribute, const Bool permanent = False);
00217   //</group>
00218 
00219   // Add new Attributes. For type uInt, Int, Float and Double, the Attribute
00220   // has tolerance (see AttributeValueTol), for Bool and String it has not
00221   // (obviously). <src>strict</src> defines how Attribute match. See
00222   // AttributeValue for the explanation of <src>strict</src> <group>
00223   void add(const String& name, const uInt newValue, 
00224            const uInt tolerance = 0, const Bool strict = False, 
00225            const Bool permanent = False);
00226 
00227   void add(const String& name, const Int newValue, 
00228            const Int tolerance = 0, const Bool strict = False, 
00229            const Bool permanent = False);
00230 
00231   void add(const String& name, const Float newValue, 
00232            const Float tolerance = 0.0, const Bool strict = False, 
00233            const Bool permanent = False);
00234 
00235   void add(const String& name, const Double newValue, 
00236            const Double tolerance = 0.0, const Bool strict = False, 
00237            const Bool permanent = False);
00238 
00239   void add(const String& name, const Bool newValue, 
00240            const Bool strict = False, const Bool permanent = False);
00241 
00242   void add(const String& name, const String& newValue, 
00243            const Bool strict = False, const Bool permanent = False);
00244 
00245   void add(const String& name, const Quantity newValue,
00246            const Bool strict = False, const Bool permanent = False);
00247 
00248 
00249   void add(const String& name, const Vector<uInt>& newValue, 
00250            const uInt tolerance = 0, const Bool strict = False, 
00251            const Bool permanent = False);
00252 
00253   void add(const String& name, const Vector<Int>& newValue, 
00254            const Int tolerance = 0, const Bool strict = False, 
00255            const Bool permanent = False);
00256 
00257   void add(const String& name, const Vector<Float>& newValue, 
00258            const Float tolerance = 0.0, const Bool strict = False, 
00259            const Bool permanent = False);
00260 
00261   void add(const String& name, const Vector<Double>& newValue, 
00262            const Double tolerance = 0.0, const Bool strict = False, 
00263            const Bool permanent = False);
00264 
00265   void add(const String& name, const Vector<Bool>& newValue,
00266            const Bool strict = False, const Bool permanent = False);
00267 
00268   void add(const String& name, const Vector<String>& newValue,
00269            const Bool strict = False, const Bool permanent = False);
00270 
00271   void add(const String& name, const Vector<Quantity>& newValue,
00272            const Bool strict = False, const Bool permanent = False);
00273 
00274   // </group>
00275 
00276   // Add new Attributes. These are the pointer versions. Using these members
00277   // will create Attributes based on AttributeValueTol or
00278   // AttributeValuePoiTol. This means that if the Attribute is modified, the
00279   // variable used to define the Attribute also changes and vice versa.
00280   // <group>
00281   void add(const String& name,  uInt *newValue, 
00282            const uInt tolerance = 0, const Bool strict = False, 
00283            const Bool permanent = False);
00284 
00285   void add(const String& name,  Int *newValue, 
00286            const Int tolerance = 0, const Bool strict = False, 
00287            const Bool permanent = False);
00288 
00289   void add(const String& name, Float *newValue, 
00290            const Float tolerance = 0.0, const Bool strict = False, 
00291            const Bool permanent = False);
00292 
00293   void add(const String& name, Double  *newValue, 
00294            const Double tolerance = 0.0, const Bool strict = False, 
00295            const Bool permanent = False);
00296 
00297   void add(const String& name, Bool *newValue, 
00298            const Bool strict = False, const Bool permanent = False);
00299 
00300   void add(const String& name, String *newValue, 
00301            const Bool strict = False, const Bool permanent = False);
00302 
00303   void add(const String& name, Quantity *newValue,
00304            const Bool strict = False, const Bool permanent = False);
00305   
00306 
00307   void add(const String& name, Vector<uInt> *newValue, 
00308            const uInt tolerance = 0, const Bool strict = False, 
00309            const Bool permanent = False);
00310 
00311   void add(const String& name, Vector<Int> *newValue, 
00312            const Int tolerance = 0, const Bool strict = False, 
00313            const Bool permanent = False);
00314 
00315   void add(const String& name,  Vector<Float> *newValue, 
00316            const Float tolerance = 0.0, const Bool strict = False, 
00317            const Bool permanent = False);
00318 
00319   void add(const String& name,  Vector<Double> *newValue, 
00320            const Double tolerance = 0.0, const Bool strict = False, 
00321            const Bool permanent = False);
00322 
00323   void add(const String& name,  Vector<Bool> *newValue, 
00324            const Bool strict = False, const Bool permanent = False);
00325 
00326   void add(const String& name, Vector<String> *newValue,
00327            const Bool strict = False, const Bool permanent = False);
00328   
00329   void add(const String& name, Vector<Quantity> *newValue,
00330            const Bool strict = False, const Bool permanent = False);
00331 
00332   // </group>
00333 
00334 
00335   // Set the value of an Attribute. If the Attribute does not exist, it is
00336   // created (using the corresponding add function with permanent set to
00337   // False), otherwise the value of the existing Attribute, if it is of the
00338   // correct type) will be changed. If the Attribute has a different type than
00339   // the variable used in the set function, nothing happens (but I may change
00340   // my mind and  throw an exception).
00341   // <group>
00342   void set(const AttributeBuffer& otherBuf);
00343   void set(const Attribute& newAttribute);
00344 
00345   void set(const String& name, const uInt newValue, 
00346            const uInt tolerance = 0, const Bool strict = False);
00347 
00348   void set(const String& name, const Int newValue, 
00349            const Int tolerance = 0, const Bool strict = False);
00350 
00351   void set(const String& name, const Float newValue, 
00352            const Float tolerance = 0.0, const Bool strict = False);
00353 
00354   void set(const String& name, const Double newValue, 
00355            const Double tolerance = 0.0, const Bool strict = False);
00356 
00357   void set(const String& name, const Bool newValue, 
00358            const Bool strict = False);
00359 
00360   void set(const String& name, const String& newValue, 
00361            const Bool strict = False);
00362 
00363   void set(const String& name, const Quantity newValue,
00364            const Bool strict = False);
00365 
00366 
00367   void set(const String& name, const Vector<uInt>& newValue, 
00368            const uInt tolerance = 0, const Bool strict = False);
00369 
00370   void set(const String& name, const Vector<Int>& newValue, 
00371            const Int tolerance = 0, const Bool strict = False);
00372 
00373   void set(const String& name, const Vector<Float>& newValue, 
00374            const Float tolerance = 0.0, const Bool strict = False);
00375 
00376   void set(const String& name, const Vector<Double>& newValue, 
00377            const Double tolerance = 0.0, const Bool strict = False);
00378 
00379   void set(const String& name, const Vector<Bool>& newValue,
00380            const Bool strict = False);
00381 
00382   void set(const String& name, const Vector<String>& newValue,
00383            const Bool strict = False);
00384 
00385   void set(const String& name, const Vector<Quantity>& newValue,
00386            const Bool strict = False);
00387 
00388   // </group>
00389 
00390   // Get tha value of the named Attribute.  Returns <src>True</src> for
00391   // success, and <src>False</src> for failure.  This can happen if the
00392   // caller asked for the wrong type.
00393   template <class T> Bool getValue(const String &name, Vector<T> &value) const;
00394   template <class T> Bool getValue(const String &name, T &value) const;
00395 
00396   // Get the pointer to the Attribute if it exists, else get 0
00397   Attribute *getAttribute(const String& name) const;
00398   
00399   // Get pointer to the AttributeValue if it exists, else get 0
00400   AttributeValueBase *getAttributeValue(const String& name) const;
00401   
00402   // Get the data type of the Attribute
00403   AttValue::ValueType getDataType(const String& name) const;
00404   
00405   // Function to see if Attribute res matches any Attribute in the
00406   // AttributeBuffer *this. 
00407   Bool matches(const Attribute& res) const;
00408 
00409   // Function to see if  every Attribute in the AttributeBuffer resBuf
00410   // matches every Attribute in the AttributeBuffer *this. Returns
00411   // True if this is the case, returns False if for at least one Attribute
00412   // in resBuf there is a mismatch.
00413   Bool matches(const AttributeBuffer& resBuf) const;
00414 
00415   // AttributeBuffer addition arithmetic.  Go through <src>*this</src>
00416   // buffer, and for those Attributes who have equivalents in
00417   // <src>other</src>, sum the values.
00418   void operator+=(const AttributeBuffer &other);
00419 
00420   // Remove Attributes from the AttributeBuffer. Only works on Attributes that
00421   // are not permanent
00422   // <group>
00423   void remove(const String& name);
00424   void clear();
00425   // </group>
00426 
00427   // Check if an Attribute with name name exists
00428   Bool exists(const String& name) const;
00429 
00430   // Add the Attributes of *this to other
00431   void addBuff(AttributeBuffer& other) const;
00432 
00433   // Set the Attributes of *this to other
00434   void setBuff(AttributeBuffer& other) const;
00435 
00436  private:
00437 
00438   friend ostream &operator<<(ostream &, AttributeBuffer &);
00439 
00440   // PtrBlock for the Attributes. Should change this to a list
00441   PtrBlock<Attribute *> attributes;
00442 
00443   // Store if an Attribute is permamnent or not
00444   Block<Bool> nonDeletable;
00445   
00446   // Internal routine to add an Attribute to the Buffer
00447   void addAttributeToBuffer(Attribute *newAttribute, const Bool permanent);
00448 
00449   // Check if an Attribute exists and return the index in the PtrBlock
00450   Bool exists(const String& name, Int& found) const;
00451 
00452   // Remove Attributes from the AttributeBuffer. Also erases  Attributes that
00453   // are permanent. Only used in operator=.
00454   void erase();
00455   
00456 };
00457 
00458 ostream &operator<<(ostream &os, AttributeBuffer &ab);
00459 
00460 
00461 } //# NAMESPACE CASA - END
00462 
00463 #ifndef AIPS_NO_TEMPLATE_SRC
00464 #include <display/Display/AttBufferTemplates.tcc>
00465 #endif
00466 
00467 #endif