casa
$Rev:20696$
|
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