|
UniWidgets
1.0.0
|
00001 #ifndef CONFIRM_CONTROLLER_H 00002 #define CONFIRM_CONTROLLER_H 00003 // ------------------------------------------------------------------------- 00004 #include <iostream> 00005 #include <UniSetTypes.h> 00006 #include <sigc++/sigc++.h> 00007 #include <map> 00008 #include <cassert> 00009 // ------------------------------------------------------------------------- 00010 namespace ConfirmCtl 00011 { 00012 00013 struct def_StateKey 00014 { 00015 UniSetTypes::ObjectId id; 00016 long value; 00017 00018 bool operator<(const def_StateKey& y) const 00019 { return (id < y.id || (id == y.id && value < y.value)); } 00020 }; 00021 // ------------------------------------------------------------------------- 00022 struct StateInfo 00023 { 00024 StateInfo () : on(false), confirmed(true), priority(0), 00025 need_confirm(false), blinkable(false) {} 00026 00027 bool on; 00028 bool confirmed; 00029 00030 int priority; 00031 bool need_confirm; 00032 bool blinkable; 00033 00034 sigc::slot<void> start_blink; 00035 sigc::slot<void> stop_blink; 00036 sigc::slot<void> switch_on; 00037 sigc::slot<void, sigc::slot<void> > connect_confirm; 00038 }; 00039 // ------------------------------------------------------------------------- 00046 template <class T = def_StateKey, class Compare = std::less<T> > 00047 class ConfirmController 00048 { 00049 public: 00050 typedef T StateKey; 00051 typedef std::map<StateKey, StateInfo, Compare> StatesMap; 00052 00053 ConfirmController() : current_it_(states_map_.end()), undefined_(false) {} 00054 ~ConfirmController() {} 00055 00056 void update(StateKey state_key, bool on); 00057 void confirm(StateKey state_key); 00058 void add(StateKey state_key, StateInfo& state_info); 00059 void remove(const StateKey& state_key); 00060 void reset(); 00061 00062 void setBlinkable(const StateKey& state_key, bool blinkable); 00063 void setPriority(const StateKey& state_key, int priority); 00064 void setNeedConfirm(const StateKey& state_key, bool need_confirm); 00065 00066 StateInfo copyStateInfo(const StateKey& state_key) const; 00067 bool hasState(const StateKey& state_key) const; 00068 const StatesMap& getStatesMap() const { return states_map_; } 00069 const StateInfo* getStateInfo(const StateKey& state_key) const; 00070 bool undefined() const; 00071 00072 sigc::signal<void> signal_switch_to_undefined; 00073 00074 protected: 00075 void Error(const char* message) {} 00076 00077 private: 00078 StatesMap states_map_; 00079 //StateKey current_; 00080 typename StatesMap::iterator current_it_; 00081 00082 bool undefined_; 00083 00084 void switch_to_next(); 00085 void switch_to(StateKey new_state); 00086 bool is_state_to_show(const StateInfo& si) const; 00087 }; 00088 // ------------------------------------------------------------------------- 00089 template<class T,class C> 00090 void ConfirmController<T,C>::update(StateKey sk, bool on) 00091 { 00092 typename StatesMap::iterator it = states_map_.find(sk); 00093 if (it == states_map_.end()) { 00094 Error("State not found. Can't update\n"); 00095 return; 00096 } 00097 00098 StateInfo* si = &it->second; 00099 00100 //TODO: confirm processing 00101 if (on == true && si->on == false) { 00102 // if ( !state_i->on && state_i->need_confirm && state_i->confirmed ) { 00103 // sigc::slot<void, StateKey> tmp_slot; 00104 // tmp_slot = sigc::mem_fun(*this, 00105 // &ConfirmController::confirm); 00106 // state_i->connect_confirm(sigc::bind(tmp_slot, state_k)); 00107 // if ( state_k == current_ ) state_i->start_blink(); state_i->confirmed = false; 00108 // } 00109 si->on = true; 00110 if (current_it_ == states_map_.end() || si->priority > current_it_->second.priority) 00111 switch_to(sk); 00112 } 00113 else if (on == false && si->on == true) { 00114 si->on = false; 00115 if (it == current_it_)// && si->confirmed ) 00116 switch_to_next(); 00117 } 00118 } 00119 // ------------------------------------------------------------------------- 00120 template<class T, class C> 00121 void ConfirmController<T,C>::switch_to(StateKey sk) 00122 { 00123 typename StatesMap::iterator it = states_map_.find(sk); 00124 00125 if (it == states_map_.end()) { 00126 Error("(!INTERNAL ERROR!): Trying to switch to unknown state.\n"); 00127 return; 00128 } 00129 00130 //TODO: what is better to use?: 00131 // current_it_ != states_map.end() 00132 // or 00133 // undefined() {return undefined_;} 00134 00135 if (current_it_ != states_map_.end() && 00136 current_it_->second.blinkable) 00137 current_it_->second.stop_blink(); 00138 00139 current_it_ = it; 00140 it->second.switch_on(); 00141 00142 if (it->second.blinkable) 00143 it->second.start_blink(); 00144 00145 //TODO: process confirming 00146 //const bool not_confirmed = 00147 // !current_it_->second.confirmed || !current_it_->second.need_confirm; 00148 //if ( not_confirmed && current_it_->second.blinkable ) 00149 // current_it_->second.start_blink(); 00150 } 00151 // ------------------------------------------------------------------------- 00152 template<class T, class C> 00153 void ConfirmController<T,C>::switch_to_next() 00154 { 00155 int max_priority = INT_MIN; 00156 StateKey next_state; 00157 for (typename StatesMap::iterator it = states_map_.begin(); 00158 it != states_map_.end(); ++it) 00159 { 00160 StateInfo* si= &(*it).second; 00161 assert( si->priority != INT_MIN ); 00162 //TODO: decide < or <= and write in documentation 00163 //TODO: process confiming 00164 //if ( (si->on || !si->confirmed) && max_priority <= si->priority) { 00165 if ( si->on && max_priority <= si->priority) { 00166 max_priority = si->priority; 00167 next_state = (*it).first; 00168 } 00169 } 00170 if ( max_priority != INT_MIN ) 00171 switch_to( next_state ); 00172 else if ( current_it_ != states_map_.end() ) { 00173 if ( current_it_->second.blinkable ) 00174 current_it_->second.stop_blink(); 00175 current_it_ = states_map_.end(); 00176 undefined_ = true; 00177 signal_switch_to_undefined.emit(); 00178 } 00179 } 00180 // ------------------------------------------------------------------------- 00181 template<class T, class C> 00182 void ConfirmController<T,C>::confirm(StateKey sk) 00183 { 00184 //TODO: process confirming 00185 // assert( states_map_.count(sk) > 0 ); 00186 // states_map_[sk].confirmed = true; 00187 // if ( sk != current_ ) 00188 // return; 00189 // if ( states_map_[sk].on && states_map_[sk].blinkable ) 00190 // states_map_[sk].stop_blink(); 00191 // else 00192 // switch_to_next(); 00193 } 00194 // ------------------------------------------------------------------------- 00195 template<class T, class C> 00196 void ConfirmController<T,C>::add(StateKey sk, StateInfo& si) 00197 { 00198 if (states_map_.count(sk) > 0) { 00199 Error("Trying to add existing state.\n"); 00200 return; 00201 } 00202 00203 states_map_[sk] = si; 00204 00205 //TODO: confirming 00206 if (si.on && is_state_to_show(si)) 00207 switch_to(sk); 00208 } 00209 // ------------------------------------------------------------------------- 00210 template<class T, class C> 00211 void ConfirmController<T,C>::remove(const StateKey& sk) 00212 { 00213 typename StatesMap::iterator it = states_map_.find(sk); 00214 if (it == states_map_.end()) { 00215 Error("Trying to remove unknown state.\n"); 00216 return; 00217 } 00218 00219 if (current_it_ == it) 00220 update(sk, false); 00221 00222 states_map_.erase(it); 00223 } 00224 // ------------------------------------------------------------------------- 00225 template<class T, class C> 00226 StateInfo ConfirmController<T,C>::copyStateInfo( const StateKey& sk) const 00227 { 00228 if (states_map_.count(sk) <= 0) { 00229 Error("Trying to get information from unknown state.\n"); 00230 throw std::exception(); 00231 } 00232 00233 return states_map_[sk]; 00234 } 00235 // ------------------------------------------------------------------------- 00236 template<class T, class C> 00237 const StateInfo* ConfirmController<T,C>::getStateInfo( const StateKey& sk ) const 00238 { 00239 typename StatesMap::iterator it = states_map_.find(sk); 00240 if (it == states_map_.end()) 00241 return NULL; 00242 00243 return &(*it).second; 00244 } 00245 // ------------------------------------------------------------------------- 00246 template<class T, class C> 00247 void ConfirmController<T,C>::setPriority( const StateKey& sk, int priority ) 00248 { 00249 typename StatesMap::iterator it = states_map_.find(sk); 00250 assert( it != states_map_.end() ); 00251 00252 it->second.priority = priority; 00253 switch_to_next(); 00254 } 00255 // ------------------------------------------------------------------------- 00256 template<class T, class C> 00257 void ConfirmController<T,C>::setBlinkable( const StateKey& sk, bool blinkable ) 00258 { 00259 typename StatesMap::iterator it = states_map_.find(sk); 00260 assert(it != states_map_.end()); 00261 00262 std::swap(it->second.blinkable, blinkable); 00263 if (it == current_it_) { 00264 if (!it->second.blinkable && blinkable) // values were swapped! 00265 it->second.stop_blink(); 00266 else if (it->second.blinkable && !blinkable) // values were swapped! 00267 it->second.start_blink(); 00268 } 00269 return; 00270 } 00271 // ------------------------------------------------------------------------- 00272 template<class T, class C> 00273 void ConfirmController<T,C>::setNeedConfirm( const StateKey& sk, bool need_confirm ) 00274 { 00275 typename StatesMap::iterator it = states_map_.find(sk); 00276 assert( it != states_map_.end() ); 00277 00278 std::swap(it->second.need_confirm, need_confirm); 00279 if (it != current_it_) 00280 return; 00281 //wait confirm if need_confirm enabled on curent state 00282 if (it->second.need_confirm && !need_confirm) 00283 update( it->first, true ); 00284 return; 00285 } 00286 // ------------------------------------------------------------------------- 00287 template<class T, class C> 00288 bool ConfirmController<T,C>::hasState(const StateKey& sk) const 00289 { 00290 return states_map_.count(sk); 00291 } 00292 // ------------------------------------------------------------------------- 00293 template<class T, class C> 00294 bool ConfirmController<T,C>::undefined() const 00295 { 00296 return current_it_ == states_map_.end(); 00297 } 00298 // ------------------------------------------------------------------------- 00299 template<class T, class C> 00300 bool ConfirmController<T,C>::is_state_to_show(const StateInfo& si) const 00301 { 00302 return current_it_ == states_map_.end() || current_it_->second.priority < si.priority; 00303 } 00304 // ------------------------------------------------------------------------- 00305 template<class T, class C> 00306 void ConfirmController<T,C>::reset() 00307 { 00308 for (typename StatesMap::iterator it = states_map_.begin(); 00309 it != states_map_.end(); ++it) 00310 { 00311 it->second.on = false; 00312 it->second.confirmed = true; 00313 } 00314 00315 current_it_ = states_map_.end(); 00316 signal_switch_to_undefined.emit(); 00317 } 00318 00319 } //namespace ConfirmCtl 00320 #endif
1.7.6.1