//
MObserver.h
/*
 *
 * Copyright (c) 1996
 * Knowledge Science Institute, University of Calgary
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  The Knowledge Science Institute makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 */

/* A simple implementation of a slight variation to the Observer pattern
   as per Gamma et al, 1995.

   Note that an object inheriting from Subject need do nothing, but an
   object inheriting form Observer must override update() and
   subjectDestroyed(), and must take care to detach form the Subject
   in its destructor,
*/

#ifndef MOBSERVER_H
#define MOBSERVER_H

#ifndef LIST_H
#include 
#endif

class Subject;

//
//an Observer must take care to detach from the Subject upon destruction!
class Observer {
  public:
    virtual int update(Subject*)=0;
	// Called when subject's state has changed; should take whatever
	// action is necessary.
    virtual int subjectDestroyed(const Subject*)=0;
	// Called when the subject has been destroyed.
  };

void destroy(Observer**) {};

//implementation
class Subject {
  public:
    Subject();
    Subject(const Subject&);
    virtual ~Subject();
    virtual Subject& operator=(Subject& s) {}
	//Assignment does NOT copy Observers.
    void attachObserver(Observer*);
	//Register an observer, normally called by the observer.
    void detachObserver(Observer*); 
	//Unregister an observer, normally called by the observer.
    void notify();
	//Notify all observers of a state change, normally called by a subclass.
    void notifyDestruction();
	//Calls subjectDestroyed() for all obs's and then clearObservers().
    void clearObservers(); 
	//Wipes the Observer list without informing them -- use
	//for special circumstances.
  protected:
    list Observers;
  };

#endif

//