Go to the documentation of this file.00001
00002
00003
00004
00005
00010
00011
00012 #ifndef signalSlot_H_
00013 #define signalSlot_H_
00014
00015 #include <vlutil/vlSmartPointers.h>
00016 #include <list>
00017
00018 namespace MAKLogger
00019 {
00020
00021 template <typename SignalType>
00022 class DtSlot
00023 {
00024 public:
00025
00026 DtSlot(){}
00027 virtual ~DtSlot(){}
00028
00029 virtual void operator()(const SignalType&) = 0;
00031 virtual void* id() = 0;
00032 virtual int idSize() = 0;
00033
00034 bool operator==(DtSlot<SignalType>& slot2)
00035 {
00037 if(this->idSize() != slot2.idSize()) return false;
00039 return memcmp(this->id(),slot2.id(),this->idSize()) == 0;
00040 }
00041
00042 };
00043
00044 template <typename SignalType>
00045 class DtFunctionSlot : public DtSlot<SignalType>
00046 {
00047 public:
00048 typedef void (*SlotFunction)(const SignalType&);
00049
00050 DtFunctionSlot(SlotFunction function) :
00051 myFunction(function)
00052 {
00053 }
00054
00056 virtual void operator()(const SignalType& value)
00057 {
00058 myFunction(value);
00059 }
00060
00061 virtual int idSize()
00062 {
00063 return sizeof(myFunction);
00064 }
00065
00066 virtual void* id()
00067 {
00068 return &myFunction;
00069 }
00070
00071 protected:
00072 SlotFunction myFunction;
00073 };
00074
00075 template <typename ClassType,typename SignalType>
00076 class DtMemberSlot : public DtSlot<SignalType>
00077 {
00078 public:
00079
00080 typedef void (ClassType::*SlotMemberFunction)(const SignalType&);
00081
00082 DtMemberSlot(ClassType* obj,SlotMemberFunction memberFunction) :
00083 myObject(obj),
00084 myMemberFunction(memberFunction)
00085 {}
00086
00087 virtual ~DtMemberSlot()
00088 {
00089
00090 }
00091
00092 virtual void operator()(const SignalType& value)
00093 {
00094 (myObject->*myMemberFunction)(value);
00095 }
00096
00097 virtual int idSize()
00098 {
00099
00100 return sizeof(DtMemberSlot<ClassType,SignalType>);
00101 }
00102
00103 virtual void* id()
00104 {
00105 return &myObject;
00106 }
00107
00108 protected:
00109 ClassType* myObject;
00110 SlotMemberFunction myMemberFunction;
00111 };
00112
00113
00114 template <typename SignalType>
00115 class DtSignal
00116 {
00117 public:
00118 typedef void (*DtSlotFunction)(const SignalType&);
00119
00120 typedef DtSlot<SignalType> SlotType;
00121 typedef DtBoost::shared_ptr<SlotType> SlotTypeSP;
00122 typedef std::list<SlotTypeSP> SlotList;
00123
00124 void connect(SlotTypeSP slot)
00125 {
00126 mySlots.push_back(slot);
00127 }
00128
00129 void disconnect(SlotTypeSP slot)
00130 {
00131 typename SlotList::iterator newEnd = std::remove_if(mySlots.begin(),mySlots.end(),
00132 std::bind2nd(std::ptr_fun(compare),slot));
00133 mySlots.erase(newEnd);
00134 }
00135
00136 void operator()(const SignalType& value)
00137 {
00138 typename SlotList::iterator func = mySlots.begin();
00139 typename SlotList::iterator end = mySlots.end();
00140 for(;func != end;++func)
00141 {
00142 SlotTypeSP& s = *func;
00143 s->operator()(value);
00144 }
00145 }
00146
00147 protected:
00148
00149 static bool compare(SlotTypeSP slot1,SlotTypeSP slot2)
00150 {
00151 return *(slot1.get()) == *(slot2.get());
00152 }
00153
00154 SlotList mySlots;
00155 };
00156
00157 template <typename SignalType>
00158 class DtValueSignal : public DtSignal<SignalType>
00159 {
00160 public:
00161 DtValueSignal(SignalType& valueRef) :
00162 myRef(valueRef)
00163 {
00164 }
00165
00166 void setAndEmitOnNotEqual(const SignalType& newValue)
00167 {
00168 if(newValue != myRef)
00169 {
00170 myRef = newValue;
00171 (*this)(myRef);
00172 }
00173 }
00174
00175 void setAndEmitOnEqual(const SignalType& newValue)
00176 {
00177 if(newValue == myRef)
00178 {
00179 myRef = newValue;
00180 (*this)(myRef);
00181 }
00182 else
00183 {
00184 myRef = newValue;
00185 }
00186 }
00187
00188 void setAndEmit(const SignalType& newValue)
00189 {
00190 myRef = newValue;
00191 (*this)(myRef);
00192 }
00193
00194
00195 protected:
00196 SignalType& myRef;
00197 };
00198
00199
00200
00201 template<typename SignalType>
00202 void DtConnect(DtSignal<SignalType>& signal,void (*slot)(SignalType))
00203 {
00204 signal.connect(typename DtSignal<SignalType>::SlotTypeSP(new DtFunctionSlot<SignalType>(slot)));
00205 }
00206
00207 template <typename ClassType,typename SignalType>
00208 void DtConnect(DtSignal<SignalType>& signal,ClassType* member,void (ClassType::*slot)(const SignalType&))
00209 {
00210 #ifdef __solaris__
00211 signal.connect(DtSignal<SignalType>::SlotTypeSP(new DtMemberSlot<ClassType,SignalType>(member,slot)));
00212 #else
00213 signal.connect(typename DtSignal<SignalType>::SlotTypeSP(new DtMemberSlot<ClassType,SignalType>(member,slot)));
00214 #endif
00215 }
00216
00217 template<typename SignalType>
00218 void DtDisconnect(DtSignal<SignalType>& signal,void (*slot)(SignalType) )
00219 {
00220 signal.disconnect(typename DtSignal<SignalType>::SlotTypeSP(new DtFunctionSlot<SignalType>(slot)));
00221 }
00222
00223 template <typename ClassType,typename SignalType>
00224 void DtDisconnect(DtSignal<SignalType>& signal,ClassType* member,void (ClassType::*slot)(SignalType) )
00225 {
00226 signal.disconnect(typename DtSignal<SignalType>::SlotTypeSP(new DtMemberSlot<ClassType,SignalType>(member,slot)));
00227 }
00228
00229 }
00230
00231 #endif