casa
$Rev:20696$
|
00001 //# Notice.h: Classes for manipulating notices 00002 //# Copyright (C) 1993,1994,1995,1999,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: Notice.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $ 00027 00028 #ifndef CASA_NOTICE_H 00029 #define CASA_NOTICE_H 00030 00031 #include <casa/Containers/Link.h> 00032 00033 namespace casa { //# NAMESPACE CASA - BEGIN 00034 00035 //# Forward Declaration 00036 class NoticeTarget; 00037 00038 // <summary>abstract base class for notices</summary> 00039 // <use visibility=export> 00040 // <reviewed reviewer="Friso Olnon" date="1995/03/16" tests="" demos=""> 00041 // </reviewed> 00042 00043 // <synopsis> 00044 // A <src>Notice</src> is the piece of information passed around 00045 // between a <src>NoticeSource</src> and a <src>NoticeTarget</src>. This 00046 // abstract base class is only a skeleton intended to be derived from. It 00047 // does not contain any relevant information -- that must be added by 00048 // the derived classes --, but it enforces derived classes to implement 00049 // the comparison operator <src>==</src> and the function 00050 // <src>type()</src>. 00051 // </synopsis> 00052 00053 // <example> 00054 // <linkto class=ListNotice>ListNotice</linkto>, derived from 00055 // <src>Notice</src>, is the notification which is passed between 00056 // <linkto class=List>List</linkto> and 00057 // <linkto class=ListIter>ListIter</linkto> 00058 // to keep cursors and container in sync. 00059 // </example> 00060 00061 class Notice { 00062 public: 00063 Notice() {} 00064 00065 virtual ~Notice(); 00066 00067 // Return the identification number of the <src>Notice</src> type. 00068 virtual uInt type() const = 0; 00069 00070 // Compare two <src>Notice</src>s. 00071 virtual int operator==(const Notice &) const = 0; 00072 }; 00073 00074 // <summary>base class for notice originators</summary> 00075 // <use visibility=export> 00076 // <reviewed reviewer="Friso Olnon" date="1995/03/16" tests="" demos=""> 00077 // </reviewed> 00078 00079 // <synopsis> 00080 // A <src>NoticeSource</src> maintains a list of all of the 00081 // <src>NoticeTarget</src>s which are interested in <src>Notice</src>s 00082 // from this <src>NoticeSource</src>. Its member function 00083 // <src>notify()</src> sends the specified <src>Notice</src> to all the 00084 // <src>NoticeTarget</src>s in the list. 00085 // 00086 // Classes which have many other dependent objects which need to be 00087 // updated, should derive from this class. 00088 // </synopsis> 00089 00090 // <example> 00091 // <linkto class=List>List</linkto>, the linked list class, is 00092 // derived from <src>NoticeSource</src>. It mainly contains status 00093 // information; all the manipulation functions are located in the 00094 // <linkto class=ListIter>ListIter</linkto> classes. The linked 00095 // list and its iterators communicate with each other via the notice 00096 // system. <src>List</src> does not provide any further notice 00097 // functionality; everything is taken care of by its base class 00098 // <src>NoticeSource</src>. 00099 // </example> 00100 00101 class NoticeSource { 00102 public: 00103 friend class NoticeTarget; 00104 00105 NoticeSource() : curIters(0) {} 00106 00107 virtual ~NoticeSource(); 00108 00109 // Sends the <src>note</src> to all <src>NoticeTarget</src>s in the 00110 // target list. 00111 void notify(const Notice & note); 00112 00113 private: 00114 Link<NoticeTarget*> *curIters; //# Do not Delete 00115 00116 Link<NoticeTarget*> *&head() { return curIters;} 00117 }; 00118 00119 // <summary>abstract base class for notice receptors</summary> 00120 // <use visibility=export> 00121 // <reviewed reviewer="Friso Olnon" date="1995/03/16" tests="" demos=""> 00122 // </reviewed> 00123 00124 // <synopsis> 00125 // A <src>NoticeTarget</src> receives the <src>Notice</src>s from the 00126 // <src>NoticeSource</src> to which it is linked. A target can only be 00127 // linked to one source. 00128 // 00129 // Classes which are dependent upon a particular 00130 // <src>NoticeSource</src> should derive from this class. 00131 // </synopsis> 00132 00133 // <example> 00134 // <linkto class=ListIter>ListIter</linkto> and its parent class 00135 // <linkto class=ConstListIter>ConstListIter</linkto> are the iterators or 00136 // "dynamic" cursors in the linked <linkto class=List>List</linkto>. They 00137 // are derived from <src>NoticeTarget</src>, and the notice system ensures 00138 // that multiple cursors are updated as elements are added and removed from 00139 // the list, according to the following scheme: 00140 // <ol> 00141 // <li> An iterator changes something to the underlying list. 00142 // <li> The iterator creates a <linkto class=ListNotice>ListNotice</linkto> 00143 // containing all the necessary information about the change. 00144 // <li> The iterator passes the notice to the <src>NoticeSource</src> 00145 // <linkto class=List>List</linkto>. 00146 // <li> The list relays the notice to all other iterators operating on the 00147 // list (kept in the "target list"). 00148 // <li> Every iterator catches the notice and changes its state accordingly. 00149 // </ol> 00150 // </example> 00151 00152 class NoticeTarget { 00153 public: 00154 friend class NoticeSource; 00155 00156 // Destructs this <src>NoticeTarget</src>. 00157 virtual ~NoticeTarget(); 00158 00159 // Returns a boolean value telling whether this <src>NoticeTarget</src> 00160 // is still "valid". 00161 Bool isValid() const {return valid;} 00162 00163 // Returns a boolean value telling whether this <src>NoticeTarget</src> 00164 // is still attached to a <src>NoticeSource</src> or not. 00165 Bool isAttached() const {return ilink ? True : False;} 00166 00167 // Makes the current <src>NoticeTarget</src> "invalid". 00168 void invalidate() {valid = False;} 00169 00170 // Hook through which <src>NoticeTarget</src>s are notified 00171 // (by <src>NoticeSource</src>s). 00172 virtual void notify(const Notice &) = 0; 00173 00174 protected: 00175 00176 Link<NoticeTarget*> *ilink; 00177 NoticeSource *container; 00178 Bool valid; 00179 00180 // Creates an unlinked, "invalid" <src>NoticeTarget</src>. An invalid 00181 // <src>NoticeTarget</src> does not occur in the target list of any 00182 // <src>NoticeSource</src>. 00183 NoticeTarget() : ilink(0), container(0), valid(False) {} 00184 00185 // Creates a "valid" <src>NoticeTarget</src> linked to the specified 00186 // <src>NoticeSource</src>. The <src>NoticeTarget</src> will be added 00187 // to the target list in that <src>NoticeSource</src>. 00188 // <group> 00189 NoticeTarget(NoticeSource *v) : ilink(0), container(0), valid(False) {attach(v);} 00190 NoticeTarget(NoticeSource &v) : ilink(0),container(0), valid(False) {attach(v);} 00191 // </group> 00192 00193 // Creates a "valid" <src>NoticeTarget</src> linked to the same 00194 // <src>NoticeSource</src> as the <src>other NoticeTarget</src>. 00195 // So, both <src>NoticeTarget</src>s will occur in the same target 00196 // list. 00197 // <group> 00198 NoticeTarget(NoticeTarget &other) : ilink(0), container(0), valid(False) 00199 { if (other.isValid()) attach(other.container);} 00200 NoticeTarget(NoticeTarget *other) : ilink(0), container(0), valid(False) 00201 { if (other && other->isValid()) attach( (*other).container );} 00202 00203 // </group> 00204 00205 // Unlinks this <src>NoticeTarget</src> from its <src>NoticeSource</src>. 00206 // The <src>NoticeTarget</src> will be removed from the target list. 00207 void unlink(); 00208 00209 // Links this <src>NoticeTarget</src> to the same <src>NoticeSource</src> 00210 // as the <src>other NoticeTarget</src>. Any previous link will be undone. 00211 // <group> 00212 void link(const NoticeTarget &other); 00213 void link(const NoticeTarget *other); 00214 // </group> 00215 00216 // Retrieves the next <src>NoticeTarget</src> in the target list 00217 // of the associated <src>NoticeSource</src>. 00218 // <group> 00219 Link<NoticeTarget*> *next() { 00220 return(ilink ? (*ilink).next() : 0); 00221 } 00222 const Link<NoticeTarget*> *next() const { 00223 return(ilink ? (*ilink).next() : 0); 00224 } 00225 // </group> 00226 00227 // Adds this <src>NoticeTarget</src> to the target list in the 00228 // specified <src>NoticeSource</src>, so that it will receive all 00229 // notices sent out by that <src>NoticeSource</src>. 00230 // <group> 00231 void attach(NoticeSource *v); 00232 void attach(NoticeSource &v); 00233 // </group> 00234 00235 }; 00236 00237 00238 } //# NAMESPACE CASA - END 00239 00240 #endif 00241 00242 00243 00244 00245