ConfirmController.h

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

Документация по UniWidgets. Последние изменения: Fri Oct 10 09:57:49 2014. Создано системой  doxygen 1.5.9