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