Basic concepts of events
- Something happens inside the operating system or application, and a component of the program needs to respond to the event and perform specific processing
In object-oriented architecture, event response functions are most likely to be member functions
- Issue: A pointer to a class member function cannot be converted to a dummy pointer void *, nor can it be arbitrarily converted to a pointer to a member function of another class
- Solution: Use a pointer to a pointer to a class member function
Implementation policy: Event delegate model
- Event class Template: Manage Event responder objects to implement events multicast
- Eventresponsor class Template: The Responder object is paired with the responder behavior
- Empty class: Delegate model and pointer conversion
#include <iostream>#include<vector>using namespacestd;//empty class, used to refer to the responder objectclassempty{};//Event Responder class template, which saves the responder and response behavior of a specific eventTemplate<typename eventaction>classeventresponsor{ Public: Eventresponsor (): Actor (null), action (null) {} eventresponsor (Empty*actor,eventaction *action): Actor (actor), action (action) {} friendBOOL operator==(ConstEventresponsor &LHS,ConstEventresponsor &RHS) { returnLhs.actor = = Rhs.actor && *lhs.action = = *rhs.action; } Public://Open data members to facilitate usersEmpty *actor; Eventaction*action;};//template<typename eventaction> class Eventresponsor//event class template for managing all responders for a specific eventTemplate<typename eventaction>classevent{ Public: typedef vector<EventResponsor<EventAction> >eventresponsors; Typeder TypeName Vector<EventResponsor<EventAction> >:: iterator eventiterator; Public: Virtual~Event () { for(Eventiterator it = This->_ers.begin (); It! = This->_ers.end (); ++it) { DeleteIt->action, it->action =NULL; }} eventresponsors& Getresponsors () {return This-_ers;}//event bindings to attach the actual responder and response behavior to the Event responder objectTemplate<typename Responsor, TypeName action>voidBind (Responsor *actor, action action) {Action*act =NewAction (action); Eventresponsor<EventAction> er ((empty*) actor, (eventaction*) Act); BOOLunbound =true; for(Eventiterator it = This->_ers.begin (); It! = This->_ers.end (); ++it) { if(*it = = er)//Duplicate Event responder found, description bound{unbound=false; Break; } } if(unbound) { This-_ers.push_back (er); } Else { DeleteEr.action, er.action =NULL; }}//Unbind event, delete event Responder ObjectTemplate<typename Responsor,typename action>voidUnbind (Responsor *actor, action action) {Action*act =NewAction (action); Eventresponsor<EventAction> er ((empty*) actor, (Eventaction *) Act); for(Eventiterator it = This->_ers.begin (); It! = This->_ers.end (); ++it) { if(*it = = er)//Find the Event responder object to delete { DeleteIt->action, This->_ers.erase (IT); Break; } } DeleteEr.action, er.action =NULL;}Private: Eventresponsor _ers;};//template<typename eventaction> class Event
//defines the event delegate model, which points to a pointer to a class member functiontypedef Empty EVENTDELEGATOR;TYPEDEFvoid(eventdelegator::* valuechanged) (intValuevoid*tag);//triggered byclasstrigger{ Public: Trigger (): _value (0) {} voidSetValue (intValuevoid*tag); intGetValue () {return_value;} Public: //value change events, exposing properties, easy to set outside the classEvent<valuechanged>value_changed;Private: int_value;};//set values, traverse the list of response objects for a particular event, trigger a value change event individuallyvoidTrigger::setvalue (intValuevoid*tag) { if(_value = =value) { return; } _value=value; Event<ValueChanged>:: Eventresponsors ers; ERs= This-value_changed. Getresponsors (); if(!Ers.empty ()) {Event<ValueChanged>:: Eventiterator it; for(it = Ers.begin (); It! = Ers.end (); + +it) {(It->actor)->* (* (it->action))) (value, tag);//Responding to Events } }}//Action Personclassactor{ Public: //listens for events, binds the object's event response function to the listening event voidListen (Trigger *Trigger) {Trigger->value_changed. Bind ( This, &actor::onvaluechanged); } //stops listening, cancels the event response activity for this object from the listening event voidUnlisten (Trigger *Trigger) {Trigger->value_changed. Unbind ( This, &actor::onvaluechanged); } //response function for value change events voidOnValueChanged (intValue, Viod *tag) {cout<< reinterpret_cast<Char*> (tag) << value <<"."<<Endl; }};intMain () {Const Char*s ="Now the value is"; Trigger T; Actor A1, A2; A1. Listen (&t); A2. Listen (&t); cout<<"Listening ..."<<Endl; T.setvalue (Ten, reinterpret_cast<void*> (const_cast<Char*>(s))); A2. Unlisten (&t); cout<<"Listening again ..."<<Endl; T.setvalue ( -, reinterpret_cast<void*> (const_cast<Char*>(s))); return 0;}
C + + Learning Note 38: Event mechanism