$search
00001 00008 /***************************************************************************** 00009 ** Ifdefs 00010 *****************************************************************************/ 00011 00012 #ifndef ECL_SIGSLOTS_LITE_MANAGERS_HPP_ 00013 #define ECL_SIGSLOTS_LITE_MANAGERS_HPP_ 00014 00015 /***************************************************************************** 00016 ** Includes 00017 *****************************************************************************/ 00018 00019 #include "slot.hpp" 00020 00021 /***************************************************************************** 00022 ** Namespaces 00023 *****************************************************************************/ 00024 00025 namespace ecl { 00026 namespace lite { 00027 00028 /***************************************************************************** 00029 ** Forward Declarations 00030 *****************************************************************************/ 00031 00032 template <typename Data, unsigned int Capacity> class Signal; 00033 00034 /***************************************************************************** 00035 ** Managers 00036 *****************************************************************************/ 00037 00038 namespace sigslots { 00042 template <typename Data, typename FunctionClass> 00043 class MemberSlotsBase { 00044 public: 00045 virtual unsigned int stored() const { return 0; } 00046 virtual unsigned int capacity() const { return 0; } 00047 virtual sigslots::MemberSlot<Data,FunctionClass>* addSlot(void (FunctionClass::*func)(Data), FunctionClass &instance) = 0; 00048 }; 00049 00053 template <typename FunctionClass> 00054 class MemberSlotsBase<void,FunctionClass> { 00055 public: 00056 virtual unsigned int stored() const { return 0; } 00057 virtual unsigned int capacity() const { return 0; } 00058 virtual sigslots::MemberSlot<void,FunctionClass>* addSlot(void (FunctionClass::*func)(), FunctionClass &instance) = 0; 00059 }; 00060 00061 } // namespace sigslots 00062 00063 /****************************************** 00064 ** Member Manager 00065 *******************************************/ 00090 template <typename Data, typename FunctionClass, unsigned int Capacity = 1> 00091 class MemberSlots : public sigslots::MemberSlotsBase<Data,FunctionClass> { 00092 public: 00093 /********************* 00094 ** Friends 00095 **********************/ 00096 // allow connect to use addSlot 00097 template <typename Data_, unsigned int Capacity_, typename FunctionClass_> 00098 friend sigslots::Error connect(Signal<Data_,Capacity_> &signal, void(FunctionClass_::*f)(Data_), FunctionClass_ &o); 00099 00100 // needs access to stored() 00101 template <typename Data_, typename FunctionClass_> 00102 friend unsigned int member_slots_stored(const FunctionClass_ &object); 00103 00104 // needs access to capacity() 00105 template <typename Data_, typename FunctionClass_> 00106 friend unsigned int member_slots_capacity(const FunctionClass_ &object); 00107 00108 00109 protected: 00110 MemberSlots() : size(0) {}; 00111 00112 private: 00118 unsigned int stored() const { return size; } 00124 unsigned int capacity() const { return Capacity; } 00125 00135 sigslots::MemberSlot<Data,FunctionClass>* addSlot(void (FunctionClass::*func)(Data), FunctionClass &instance) { 00136 for ( unsigned int i = 0; i < size; ++i ) { 00137 if ( func == slots[i].member_function ) { 00138 return &(slots[i]); 00139 } 00140 } 00141 if ( size < Capacity ) { 00142 slots[size] = sigslots::MemberSlot<Data,FunctionClass>(func,instance); 00143 ++size; 00144 return &(slots[size-1]); 00145 } else { 00146 return NULL; 00147 } 00148 } 00149 00150 unsigned int size; 00151 sigslots::MemberSlot<Data,FunctionClass> slots[Capacity]; 00152 }; 00153 00154 /****************************************** 00155 ** Global Manager 00156 *******************************************/ 00157 00190 template <typename Data, typename Dummy = int> 00191 class GlobalSlots { 00192 public: 00193 static const unsigned int capacity; 00195 /********************* 00196 ** Friends 00197 **********************/ 00198 // needs access to addSlot() 00199 template <typename Data_, unsigned int Capacity_> 00200 friend sigslots::Error connect(Signal<Data_, Capacity_> &signal, void (*function)(Data_)); 00201 00202 // needs access to stored() 00203 template <typename Data_> 00204 friend unsigned int global_slots_stored(); 00205 00206 private: 00218 static unsigned int stored(const bool increment = false) { 00219 static unsigned int stored_slots = 0; 00220 if ( increment ) { ++stored_slots; } 00221 return stored_slots; 00222 } 00231 static sigslots::GlobalSlot<Data>* addSlot(void (*func)(Data)) { 00232 unsigned int size = stored(); 00233 static sigslots::GlobalSlot<Data> slots[capacity]; 00234 for ( unsigned int i = 0; i < size; ++i ) { 00235 if ( func == slots[i].global_function ) { 00236 return &(slots[i]); 00237 } 00238 } 00239 if ( size < capacity ) { 00240 slots[size] = sigslots::GlobalSlot<Data>(func); 00241 bool inc = true; 00242 stored(inc); // increment the number of stored slots variable 00243 return &(slots[size]); 00244 } else { 00245 return NULL; 00246 } 00247 } 00248 }; 00249 00250 /***************************************************************************** 00251 ** Specialisations 00252 *****************************************************************************/ 00256 template <typename FunctionClass, unsigned int Capacity> 00257 class MemberSlots<void, FunctionClass, Capacity> : public sigslots::MemberSlotsBase<void,FunctionClass> { 00258 public: 00259 /********************* 00260 ** Friends 00261 **********************/ 00262 // allow connect to use addSlot 00263 template <unsigned int Capacity_, typename FunctionClass_> 00264 friend sigslots::Error connect(Signal<void,Capacity_> &signal, void(FunctionClass_::*f)(void), FunctionClass_ &o); 00265 // needs access to stored() 00266 template <typename Data_, typename FunctionClass_> 00267 friend unsigned int member_slots_stored(const FunctionClass_ &object); 00268 00269 // needs access to capacity() 00270 template <typename Data_, typename FunctionClass_> 00271 friend unsigned int member_slots_capacity(const FunctionClass_ &object); 00272 00273 protected: 00274 MemberSlots() : size(0) {}; 00275 00276 private: 00282 unsigned int stored() const { return size; } 00283 00289 unsigned int capacity() const { return Capacity; } 00290 00300 sigslots::MemberSlot<void,FunctionClass>* addSlot(void (FunctionClass::*func)(void), FunctionClass &instance) { 00301 for ( unsigned int i = 0; i < size; ++i ) { 00302 if ( func == slots[i].member_function ) { 00303 return &(slots[i]); 00304 } 00305 } 00306 if ( size < Capacity ) { 00307 slots[size] = sigslots::MemberSlot<void,FunctionClass>(func,instance); 00308 ++size; 00309 return &(slots[size-1]); 00310 } else { 00311 return NULL; 00312 } 00313 } 00314 00315 unsigned int size; 00316 sigslots::MemberSlot<void,FunctionClass> slots[Capacity]; 00317 }; 00318 00324 template <typename Dummy> 00325 class GlobalSlots<void, Dummy> { 00326 public: 00327 static const unsigned int capacity; 00330 /********************* 00331 ** Friends 00332 **********************/ 00333 // needs access to addSlot() 00334 template <unsigned int Capacity_> 00335 friend sigslots::Error connect(Signal<void,Capacity_> &signal, void (*function)(void)); 00336 00337 // needs access to stored() 00338 template <typename Data> friend unsigned int global_slots_stored(); 00339 00340 private: 00352 static unsigned int stored(const bool increment = false) { 00353 static unsigned int stored_slots = 0; 00354 if ( increment ) { ++stored_slots; } 00355 return stored_slots; 00356 } 00357 00366 static sigslots::GlobalSlot<void>* addSlot(void (*func)(void)) { 00367 unsigned int size = stored(); 00368 static sigslots::GlobalSlot<void> slots[capacity]; 00369 for ( unsigned int i = 0; i < size; ++i ) { 00370 if ( func == slots[i].global_function ) { 00371 return &(slots[i]); 00372 } 00373 } 00374 if ( size < capacity ) { 00375 slots[size] = sigslots::GlobalSlot<void>(func); 00376 bool inc = true; 00377 stored(inc); // increment the number of stored slots variable 00378 return &(slots[size]); 00379 } else { 00380 return NULL; 00381 } 00382 } 00383 }; 00384 00385 00386 } // namespace lite 00387 } // namespace ecl 00388 00389 #endif /* ECL_SIGSLOTS_LITE_MANAGERS_HPP_ */