inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/sg/ui
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_sg_ui
00005 #define inlib_sg_ui
00006 
00007 #include "cbk"
00008 
00009 #include <vector>
00010 
00011 namespace inlib {
00012 namespace sg {
00013 
00014 class ui {
00015 public:
00016   virtual void win_render() = 0;
00017   virtual bool stop_works() {return false;}
00018 public:
00019   ui():m_to_exit(false){}
00020   virtual ~ui(){clear();}
00021 protected:
00022   ui(const ui& a_from):m_to_exit(a_from.m_to_exit){
00023     copy_cbks(a_from);
00024   }
00025   ui& operator=(const ui& a_from){
00026     m_to_exit = a_from.m_to_exit;
00027     copy_cbks(a_from);
00028     return *this;
00029   }
00030 public:
00031   bool to_exit() const {return m_to_exit;}
00032   void set_to_exit() {m_to_exit = true;}
00033 public:
00034   void add_work(inlib::sg::cbk* a_work) {
00035     m_cbks.push_back(a_work); //we take ownership of a_work.
00036   }
00037   bool remove_works(const std::string& a_class) {
00038     std::vector<inlib::sg::cbk*>::iterator it;
00039     for(it=m_cbks.begin();it!=m_cbks.end();) {
00040       inlib::sg::cbk* cbk = *it;
00041       if(cbk->cast(a_class)) {
00042         it = m_cbks.erase(it);        
00043         delete cbk;
00044       } else {
00045         ++it;
00046       }
00047     }
00048     return true;
00049   }
00050   bool has_work(const std::string& a_class) const {
00051     std::vector<inlib::sg::cbk*>::const_iterator it;
00052     for(it=m_cbks.begin();it!=m_cbks.end();++it) {
00053       if((*it)->cast(a_class)) {
00054         return true;
00055       }
00056     }
00057     return false;
00058   }
00059 
00060   void do_works() {
00061     //WARNING : the below (*it)->action() may touch m_cbks.
00062 
00063     //bool to_dump = false;
00064     //if(m_cbks.size()) to_dump = true;
00065     //if(to_dump) 
00066     //  std::cout << "debug : zzzz : begin " << m_cbks.size() << std::endl;
00067 
00068     std::vector<inlib::sg::cbk*> to_do = m_cbks;
00069    {std::vector<inlib::sg::cbk*>::iterator it;
00070     for(it=to_do.begin();it!=to_do.end();++it) {
00071       if(is_in_m_cbks(*it)) {
00072         //do a copy in case (*it)->action() indirectly deletes (*it) !
00073         inlib::sg::cbk* cbk = (*it)->copy();
00074         bool to_render = (cbk->action()==cbk::return_to_render?true:false);
00075         if(cbk->is_single_shoot()) {
00076           //NOTE : cbk->action() may raise "single_shoot" on cbk. We have
00077           //       to report that to the original (*it) callback.
00078           //       This happens with gui_viewer::jpeg_read_work.
00079           (*it)->set_single_shoot(true);
00080         }
00081         delete cbk;
00082         if(to_render) win_render();
00083       }
00084     }}
00085 
00086    {std::vector<inlib::sg::cbk*>::iterator it;
00087     for(it=to_do.begin();it!=to_do.end();++it) {
00088       if(is_in_m_cbks(*it)) {
00089         inlib::sg::cbk* cbk = *it;
00090         if(cbk->is_single_shoot()) {
00091           delete cbk;
00092           std::vector<inlib::sg::cbk*>::iterator it2;
00093           for(it2=m_cbks.begin();it2!=m_cbks.end();) {
00094             if(cbk==(*it2)) {
00095               it2 = m_cbks.erase(it2);
00096             } else {
00097               it2++;
00098             }
00099           }
00100         }
00101       }
00102     }}
00103 
00104     //if(to_dump) 
00105     //  std::cout << "debug : zzzz : end " << m_cbks.size() << std::endl;
00106   }
00107 
00108 /*
00109   void do_works() {
00110     start_do_works();
00111     bool to_render;
00112     while(it_do_work(to_render)) {
00113       if(to_render) win_render();
00114     }
00115     end_do_works();
00116   }
00117 
00118   void start_do_works() {
00119     m_to_do = m_cbks;
00120     m_to_do_it = m_to_do.begin();
00121   }
00122   bool it_do_work(bool& a_render) {
00123     //return false = no more work.
00124     if(m_to_do_it==m_to_do.end()) {
00125       a_render = false;
00126       return false;
00127     }
00128     if(!is_in_m_cbks(*m_to_do_it)) {
00129       a_render = false;
00130     } else {
00131       inlib::sg::cbk* cbk = (*m_to_do_it)->copy();
00132       a_render = (cbk->action()==cbk::return_to_render?true:false);
00133       if(cbk->is_single_shoot()) {
00134         //NOTE : cbk->action() may raise "single_shoot" on cbk. We have
00135         //       to report that to the original (*it) callback.
00136        //       This happens with gui_viewer::jpeg_read_work.
00137        (*m_to_do_it)->set_single_shoot(true);
00138       }
00139       delete cbk;
00140     }
00141     m_to_do_it++;
00142     return true;
00143   }
00144 
00145   void end_do_works() {
00146     std::vector<inlib::sg::cbk*>::iterator it;
00147     for(it=m_to_do.begin();it!=m_to_do.end();++it) {
00148       if(is_in_m_cbks(*it)) {
00149         inlib::sg::cbk* cbk = *it;
00150         if(cbk->is_single_shoot()) {
00151           delete cbk;
00152           std::vector<inlib::sg::cbk*>::iterator it2;
00153           for(it2=m_cbks.begin();it2!=m_cbks.end();) {
00154             if(cbk==(*it2)) {
00155               it2 = m_cbks.erase(it2);
00156             } else {
00157               it2++;
00158             }
00159           }
00160         }
00161       }
00162     }
00163     m_to_do.clear();
00164   }
00165 */
00166 
00167   //bool has_work() const {return m_cbks.size()?true:false;}
00168   unsigned int num_cbks() const {return m_cbks.size();}
00169   const std::vector<inlib::sg::cbk*>& cbks() const {return m_cbks;}
00170 private:
00171   void clear() {
00172     std::vector<inlib::sg::cbk*>::iterator it;
00173     for(it=m_cbks.begin();it!=m_cbks.end();) {
00174       inlib::sg::cbk* cbk = *it;
00175       it = m_cbks.erase(it);        
00176       delete cbk;
00177     }    
00178     m_cbks.clear();
00179   }
00180   void copy_cbks(const ui& a_from) {
00181     clear();
00182     std::vector<inlib::sg::cbk*>::const_iterator it;
00183     for(it=a_from.m_cbks.begin();it!=a_from.m_cbks.end();++it) {
00184       m_cbks.push_back((*it)->copy());
00185     }
00186   }
00187   bool is_in_m_cbks(inlib::sg::cbk* a_cbk) {
00188     std::vector<inlib::sg::cbk*>::const_iterator it;
00189     for(it=m_cbks.begin();it!=m_cbks.end();++it) {
00190       if((*it)==a_cbk) return true;
00191     }
00192     return false;
00193   }
00194 private:
00195   bool m_to_exit;
00196   std::vector<inlib::sg::cbk*> m_cbks;
00197   //for Android :
00198   //std::vector<inlib::sg::cbk*> m_to_do;
00199   //std::vector<inlib::sg::cbk*>::iterator m_to_do_it;
00200 };
00201 
00202 }}
00203 
00204 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines