casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Notice.h
Go to the documentation of this file.
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