home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue51 / Observer / FObserver_Abstract.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-10-08  |  5.3 KB  |  182 lines

  1. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2.   (c) TechInsite Pty. Ltd.
  3.   PO Box 429, Abbotsford, Melbourne. 3067 Australia
  4.   Phone: +61 3 9419 6456
  5.   Fax:   +61 3 9419 1682
  6.   Web:   www.techinsite.com.au
  7.   EMail: peter_hinrichsen@techinsite.com.au
  8.  
  9.   Created: October 1999
  10.  
  11.   Notes: The SubjectAbstract and ObserverAbstract classes
  12.  
  13. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  14. unit FObserver_Abstract;
  15.  
  16. interface
  17.  
  18. uses
  19.   Windows, Messages, SysUtils, Classes, Graphics, Controls,
  20.   Forms, Dialogs, StdCtrls
  21.   ;
  22.  
  23. type
  24.  
  25.   // Forward dec of ObserverAbstract
  26.   //--------------------------------------------------------
  27.   TFormObserverAbstract = class ;
  28.  
  29.   // SubjectAbstract - Knows about interested observers
  30.   //--------------------------------------------------------
  31.   TSubjectAbstract = class( TObject )
  32.   private
  33.     // A TList of pointers into the interested observers
  34.     FObservers : TList ;
  35.   protected
  36.   public
  37.     Constructor Create ;
  38.     Destructor  Destroy ; override ;
  39.     // Attach an observer to the subject
  40.     procedure AttachObserver(Sender :TFormObserverAbstract);
  41.     // Detach an observer from the subject
  42.     Procedure DetachObserver(Sender :TFormObserverAbstract);
  43.     // Update all attache observers
  44.     Procedure UpdateObservers ;
  45.   end ;
  46.  
  47.   // ObserverAbstract - Knows about a subject
  48.   //--------------------------------------------------------
  49.   TFormObserverAbstract = class(TForm)
  50.     // Free the observer when closed
  51.     procedure FormClose(Sender: TObject;
  52.                                   var Action: TCloseAction);
  53.     // Detach from the subject when destroyed
  54.     procedure FormDestroy(Sender: TObject);
  55.     // Read the subject when the form shows
  56.     procedure FormShow(Sender: TObject);
  57.   private
  58.     // A pointer into the shared subject
  59.     FSubject : TSubjectAbstract ;
  60.     // Set FSubject, and attach the observer
  61.     procedure SetSubject(const Value: TSubjectAbstract);
  62.   protected
  63.   public
  64.     // Virtual Abstract read data - must be implemented in
  65.     // descendants
  66.     procedure DataToObserver ; virtual ; abstract ;
  67.     // A pointer into the shared subject
  68.     property  Subject : TSubjectAbstract read FSubject
  69.                                           write SetSubject ;
  70.   end;
  71.  
  72. implementation
  73.  
  74. {$R *.DFM}
  75.  
  76. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  77. // *
  78. // * TSubjectAbstract
  79. // *
  80. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  81. constructor TSubjectAbstract.Create;
  82. begin
  83.   inherited ;
  84.   // Create a TList to hold pointers to the
  85.   // interested observers
  86.   FObservers := TList.Create ;
  87. end;
  88.  
  89. //----------------------------------------------------------
  90. destructor TSubjectAbstract.Destroy;
  91. begin
  92.   // Free the list of observers
  93.   FObservers.Free ;
  94.   inherited ;
  95. end;
  96.  
  97. // Attach an observer to this subject
  98. //----------------------------------------------------------
  99. procedure TSubjectAbstract.AttachObserver(Sender:
  100.                                      TFormObserverAbstract);
  101. var
  102.   i : integer ;
  103. begin
  104.   // Scan the list of observers to confirm this one is not
  105.   // already attached.
  106.   i := FObservers.IndexOf( Sender ) ;
  107.   Assert( i = -1, 'Observer already attached' ) ;
  108.  
  109.   // Add the observer to the list
  110.   FObservers.Add( Sender ) ;
  111.  
  112. end;
  113.  
  114. // Detach an observer
  115. //----------------------------------------------------------
  116. procedure TSubjectAbstract.DetachObserver(Sender:
  117.                                      TFormObserverAbstract);
  118. var
  119.   i : integer ;
  120. begin
  121.   // Locate the observer in the list
  122.   i := FObservers.IndexOf( Sender ) ;
  123.   Assert( i <> -1, 'Observer not attached' ) ;
  124.   // Delete it from the list
  125.   FObservers.Delete( i ) ;
  126. end;
  127.  
  128. // Update all the observers that are attached to
  129. // this subject
  130. //----------------------------------------------------------
  131. procedure TSubjectAbstract.UpdateObservers;
  132. var
  133.   i : integer ;
  134. begin
  135.   // Scan the list of observers and call the UpdateObserver
  136.   // method on each one
  137.   for i := 0 to FObservers.Count - 1 do
  138.     if Assigned( FObservers[i] ) then
  139.       TFormObserverAbstract( FObservers[i] ).DataToObserver ;
  140. end;
  141.  
  142. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  143. // *
  144. // * TFormObserverAbstract
  145. // *
  146. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  147. procedure TFormObserverAbstract.FormShow(Sender: TObject);
  148. begin
  149.   // Read from subject to observer when the form is shown
  150.   DataToObserver ;
  151. end;
  152.  
  153. //----------------------------------------------------------
  154. procedure TFormObserverAbstract.FormClose(Sender: TObject;
  155.                                   var Action: TCloseAction);
  156. begin
  157.   // Free the form on close
  158.   Action := caFree ;
  159. end;
  160.  
  161. //----------------------------------------------------------
  162. procedure TFormObserverAbstract.FormDestroy(Sender: TObject);
  163. begin
  164.   // Detach the observer from the subject
  165.   // (if the subject has not been destroyed first)
  166.   if subject <> nil then
  167.     Subject.DetachObserver( self ) ;
  168. end;
  169.  
  170. //----------------------------------------------------------
  171. procedure TFormObserverAbstract.SetSubject(const Value:
  172.                                           TSubjectAbstract);
  173. begin
  174.   // Save a pointer to the subject for later use
  175.   FSubject := Value;
  176.   // Attach this observer to the subject
  177.   Subject.AttachObserver( self ) ;
  178. end;
  179.  
  180. end.
  181.  
  182.