00001 #ifndef rgrl_object_h_ 00002 #define rgrl_object_h_ 00003 //: 00004 // \file 00005 // \brief Base class for most rgrl classes 00006 // \author Charlene Tsai 00007 // \date April 2004 00008 00009 #include <vbl/vbl_ref_count.h> 00010 00011 #include <vcl_map.h> 00012 00013 #include "rgrl_command_sptr.h" 00014 #include "rgrl_event_sptr.h" 00015 #include "rgrl_macros.h" 00016 #include "rgrl_command.h" 00017 #include "rgrl_event.h" 00018 00019 //: Observer class to bind a command with an event 00020 class rgrl_object_observer 00021 { 00022 public: 00023 rgrl_object_observer() {} 00024 rgrl_object_observer(rgrl_command_sptr c, 00025 rgrl_event_sptr event ) 00026 :command_(c), 00027 event_(event) 00028 {} 00029 ~rgrl_object_observer(){} 00030 rgrl_command_sptr command_; 00031 rgrl_event_sptr event_; 00032 }; 00033 00034 //: rgrl_object implements callbacks (via object/observer), and debug flags. 00035 // Most rgrl classes should be a subclass of rgrl_object. 00036 class rgrl_object 00037 : public vbl_ref_count 00038 { 00039 public: 00040 //: 00041 rgrl_object(); 00042 00043 //: copy constructor 00044 rgrl_object( const rgrl_object& that ) 00045 : vbl_ref_count(), debug_flag_(that.debug_flag_), warning_(that.warning_), 00046 observers_(that.observers_), observer_count_(that.observer_count_) 00047 { } //suppress copying of reference count between objects 00048 00049 00050 //: assignment operator 00051 const rgrl_object& operator=( const rgrl_object& rhs ) 00052 { 00053 //suppress copying of reference count between objects 00054 debug_flag_ = rhs.debug_flag_; 00055 warning_ = rhs.warning_; 00056 observers_ = rhs.observers_; 00057 observer_count_ = rhs.observer_count_; 00058 return *this; 00059 } 00060 //: 00061 virtual ~rgrl_object(); 00062 00063 static const vcl_type_info& type_id() 00064 { return typeid(rgrl_object); } 00065 00066 virtual bool is_type( const vcl_type_info& type ) const 00067 { return (typeid(rgrl_object) == type)!=0; } 00068 00069 //: Set the value of the debug flag. A non-zero value turns debugging on. 00070 void set_debug_flag( unsigned int debugFlag ) const; 00071 00072 //: Get the value of the debug flag. 00073 unsigned int debug_flag() const; 00074 00075 //: Set the flag for warning messages 00076 void set_warning(bool) const; 00077 00078 //: Get the warning flag 00079 bool warning() const; 00080 00081 //: Allow people to add/remove/invoke observers (callbacks) to any rgrl object. 00082 // 00083 // This is an implementation of the subject/observer design 00084 // pattern. An observer is added by specifying an event to respond 00085 // to and an rgrl_command to execute. It returns an unsigned long tag 00086 // which can be used later to remove the event or retrieve the 00087 // command. 00088 unsigned int add_observer( rgrl_event_sptr event, rgrl_command_sptr ); 00089 00090 //: Get the command associated with the given tag. 00091 rgrl_command_sptr get_command(unsigned int tag); 00092 00093 //: Call \a execute(.) on all the rgrl_commands observing this event id. 00094 void invoke_event( const rgrl_event & ); 00095 00096 //: Call \a execute(.) on all the rgrl_commands observing this event id. 00097 // 00098 // The actions triggered by this call doesn't modify this object. 00099 void invoke_event( const rgrl_event & ) const; 00100 00101 //: Remove the observer with this tag value. 00102 void remove_observer(unsigned int tag); 00103 00104 //: Return true if an observer is registered for this event. 00105 bool has_observer( const rgrl_event & event ) const; 00106 00107 private: 00108 #if 0 00109 //: copy constructor and =operator are disabled on purpose 00110 rgrl_object( const rgrl_object& ); 00111 void operator=( const rgrl_object& ); 00112 #endif 00113 00114 // For debugging 00115 mutable unsigned int debug_flag_; 00116 mutable bool warning_; 00117 00118 // For event handling 00119 typedef vcl_map< unsigned, rgrl_object_observer > observer_map; 00120 observer_map observers_; 00121 unsigned int observer_count_; 00122 }; 00123 00124 #endif