inlib
1.2.0
|
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