Propagating update events

The Model-View or Observer pattern  [GOF] provides a general way to deal with information updates that may affect multiple dependent objects. Similar functionality can be obtained by employing events. An event class can be defined as follows:


slide: Propagating update events


The event class

    class event {
    public:
    	virtual void operator()() {}      
activate

void dependent(event* e); void update();
to process dependent events

private: set<event*> _dep;
initially empty

};
The event class must provide for a function to activate the event, and in addition it must allow for defining dependent events, that may in turn be activated by calling update.

In the example below, which is adapted from  [Henderson], events are used to maintain and display the value of a collection of thermometers in a consistent fashion. An abstract thermometer may be defined as:

The thermometer class

    class thermometer {
    friend class Reset;
    public:
    	virtual void set(float v);
    	virtual float get();
    protected:
    	float _temp;                 
absolute temperature

};
The thermometer keeps its value in degrees Kelvin, and may be refined into a Centigrade and Fahrenheit thermometer using standard conversion rules.

For realizing a user interface, that allows us to set and display the value of a thermometer, we need classes like prompter and displayer:

The promper class

    class prompter : public widget {
    public:
    	prompter(char* msg);
    	float get();
    };
    
    class displayer : public widget {
    public:
    	displayer(char* msg);
    	void put( float v);
    };
  
These classes may be refined to allow for textual as well as graphical input and display.

To manage temperature updates, we introduce the Get, Reset and Show events:

    class Get : public event {
    public:
      Get(thermometer* th, prompter* p ) : _th(th), _p(p) {} 
      void operator()() {
    	_th->set ( _p->get() );
    	event::update();
    	}
    private:
      thermometer* _th; prompter* _p;
    };
  
Activating the Get event results in displaying a prompter and setting the thermometer's value with the value obtained from it. Then its dependent events are activated.

Reset events are needed to update the value of other thermometers. To allow the Reset event access to the stored temperature value, the class Reset has been made a friend of thermometer. Alternatively, the _temp instance variable could have been made a static (class) variable.

The Show event simply puts the value of the thermometer in a displayer. In it defined in a similar way as the Get events.

When a Get event occurs for a particular thermometer, first the other thermometers must be reset, and then the displays for the various thermometers must be changed accordingly. That means that we must create at least one Get event for each thermometer, and sufficient Reset events to update the value of every other thermometer. Also, we must have one or more Show events for each thermometer. Both the appropriate Reset and Show events must be declared to be dependent upon the occurrence of a Get event. Both Get and Show events may be made available as entries in a menu. When defining dependencies take care not to create cycles. Alternatively you may check dynamically for cycles.