Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef tools_sg_node 5 #define tools_sg_node 6 7 #include "field" 8 #include "search_action" 9 #include "write_action" 10 #include "read_action" 11 #include "get_matrix_action" 12 #include "node_desc" 13 14 #include "../forit" 15 16 namespace tools { 17 namespace sg { 18 class render_action; 19 class pick_action; 20 class bbox_action; 21 class event_action; 22 class visible_action; 23 }} 24 25 namespace tools { 26 namespace sg { 27 28 class node { 29 public: 30 TOOLS_SCLASS(tools::sg::node) 31 //public: 32 // static bool is_a(const std::string& a_clas 33 // in a derived class: 34 // static bool is_a(const std::string& a_clas 35 // if(rcmp(a_class,s_class())) return true; 36 // return parent::is_a(a_class); 37 // } 38 virtual void* cast(const std::string& a_clas 39 if(void* p = cmp_cast<node>(this,a_class)) 40 return 0; 41 } 42 virtual const std::string& s_cls() const = 0 43 public: 44 virtual node* copy() const = 0; 45 46 virtual unsigned int cls_version() const {re 47 48 virtual const desc_fields& node_desc_fields( 49 static const desc_fields s_v; 50 return s_v; 51 } 52 53 virtual void render(render_action&) {} 54 virtual void pick(pick_action&) {} 55 virtual void bbox(bbox_action&) {} 56 virtual void search(search_action& a_action) 57 if(a_action.what()==search_action::search_ 58 if(void* p = cast(a_action.sclass())) { 59 a_action.add_obj(p); 60 if(a_action.stop_at_first()) a_action. 61 } 62 } else if(a_action.what()==search_action:: 63 if(this==a_action.node()){ 64 a_action.path_push(this); //ending nod 65 a_action.set_done(true); 66 } 67 } else if(a_action.what()==search_action:: 68 if(cast(a_action.sclass())) { 69 search_action::path_t path = a_action. 70 path.push_back(this); 71 a_action.add_path(path); 72 if(a_action.stop_at_first()) a_action. 73 } 74 } 75 } 76 virtual void get_matrix(get_matrix_action& a 77 if(this==a_action.node()){ 78 a_action.set_found_model(a_action.model_ 79 a_action.set_done(true); 80 } 81 } 82 virtual bool write(write_action& a_action) { 83 if(!a_action.beg_node(*this)) return false 84 if(!write_fields(a_action)) return false; 85 if(!a_action.end_node(*this)) return false 86 return true; 87 } 88 virtual void event(event_action&) {} 89 virtual bool read(read_action& a_action) {re 90 virtual void is_visible(visible_action&) {} 91 92 virtual void protocol_one_fields(std::vector 93 94 virtual bool draw_in_frame_buffer() const {r 95 public: 96 virtual bool touched() { //virtual for plott 97 tools_vforcit(field*,m_fields,it) { 98 if((*it)->touched()) return true; 99 } 100 return false; 101 } 102 virtual void reset_touched() { 103 tools_vforcit(field*,m_fields,it) (*it)->r 104 } 105 public: 106 node() 107 { 108 #ifdef TOOLS_MEM 109 mem::increment(s_class().c_str()); 110 #endif 111 } 112 virtual ~node(){ 113 #ifdef TOOLS_MEM 114 mem::decrement(s_class().c_str()); 115 #endif 116 } 117 protected: 118 node(const node&) 119 { 120 #ifdef TOOLS_MEM 121 mem::increment(s_class().c_str()); 122 #endif 123 } 124 node& operator=(const node&){ 125 return *this; 126 } 127 protected: 128 void add_field(field* a_field) { 129 m_fields.push_back(a_field); //it does not 130 } 131 //TOOLS_CLASS_STRING(fields_end) //for write 132 bool write_fields(write_action& a_action) { 133 134 check_fields(a_action.out()); //costly. 135 //dump_field_descs(a_action.out()); 136 137 unsigned int index = 0; 138 tools_vforcit(field*,m_fields,it) { 139 if(!(*it)->write(a_action.buffer())) { 140 a_action.out() << "node::write_fields 141 << " for field index " 142 << " and field class " 143 << " of node class " << 144 << " : field.write() fa 145 << std::endl; 146 return false; 147 } 148 index++; 149 } 150 return true; 151 } 152 153 bool read_fields(read_action& a_action) { // 154 node_desc rndesc; 155 if(!a_action.get_node_desc(s_cls(),rndesc) 156 a_action.out() << "tools::node::read_fie 157 << " for node class " << 158 << " : read_action.get_no 159 << std::endl; 160 return false; 161 } 162 //Whatever the current node fields, we mus 163 tools_vforcit(field_desc,rndesc.fields(),i 164 const field_desc& fdesc = *it; 165 166 field* fd = find_field(fdesc); 167 if(!fd) { 168 a_action.out() << "tools::node::read_f 169 << " for node class " < 170 << " : field desc name 171 << " : field desc class 172 << " : field desc offse 173 << " : field not found. 174 << "." 175 << std::endl; 176 //#define TOOLS_NODE_DEBUG_READ_FIELD 177 #ifdef TOOLS_NODE_DEBUG_READ_FIELD 178 check_fields(a_action.out()); //costly 179 dump_field_descs(a_action.out()); 180 {a_action.out() << "read field descs of 181 tools_vforcit(field_desc,rndesc.fields 182 a_action.out() << "name " << (*itr). 183 << ", class " << (*itr).cls() 184 << ", offset " << (*itr).offse 185 << std::endl; 186 }} 187 {a_action.out() << "m_fields of node cl 188 tools_vforcit(field*,m_fields,itm) { 189 a_action.out() << "field class " << 190 << ", found offset " << field_ 191 << std::endl; 192 }} 193 ::exit(0); 194 #endif 195 fd = a_action.field_factory().create(f 196 if(!fd) { 197 a_action.out() << "tools::node::read 198 << " for node class " 199 << " : field desc cla 200 << " : can't create g 201 << "." 202 << std::endl; 203 return false; 204 } 205 } /*else { 206 a_action.out() << "debug : tools::node 207 << " for node class " < 208 << " : field desc class 209 << " : field desc offse 210 << " : field found." 211 << "." 212 << std::endl; 213 }*/ 214 215 if(!fd->read(a_action.buffer())) { 216 a_action.out() << "tools::node::read_f 217 << " for node class " < 218 << " : and field class 219 << " : field read() fai 220 << std::endl; 221 return false; 222 } 223 //fd->dump(a_action.out()); 224 } 225 226 //NOTE : if some current node fields had n 227 // in rndesc.fields(), they catch th 228 // of the node fields. 229 230 return true; 231 } 232 public: 233 void touch() { 234 if(m_fields.empty()) return; 235 m_fields.front()->touch(); 236 } 237 /* 238 bool equal(const node& a_node) const { 239 if(m_fields.size()!=a_node.m_fields.size() 240 std::vector<field*>::iterator it = m_field 241 std::vector<field*>::iterator ait = a_node 242 for(;it!=m_fields.end();++it,++ait) { 243 if(!(*it)->equal(*(*ait))) return false; 244 } 245 return true; 246 } 247 */ 248 public: 249 field& field_from_desc(const field_desc& a_d 250 //WARNING : touchy. 251 return *((field*)((char*)this+a_desc.offse 252 } 253 void dump_field_descs(std::ostream& a_out) c 254 a_out << "field descs of node class " << s 255 const std::vector<field_desc>& fds = node_ 256 tools_vforcit(field_desc,fds,itd) { 257 a_out << "name " << (*itd).name() 258 << ", class " << (*itd).cls() 259 << ", offset " << (*itd).offset() 260 << std::endl; 261 } 262 } 263 field* find_field_by_name(const std::string& 264 // a_name is of the form <class>.<field>. 265 // tools::sg::back_area.color 266 // tools::sg::text.color 267 const std::vector<field_desc>& fds = node_ 268 tools_vforcrit(field_desc,fds,it) { 269 if((*it).name()==a_name) { 270 tools_vforcit(field*,m_fields,itf) { 271 if(field_offset(*itf)==(*it).offset( 272 } 273 } 274 } 275 return 0; 276 } 277 protected: 278 field_desc::offset_t field_offset(const fiel 279 //WARNING : touchy. 280 return ((char*)(a_field)-(char*)(this)); 281 } 282 283 field* find_field(const field_desc& a_rdesc) 284 const std::vector<field_desc>& fds = node_ 285 tools_vforcit(field_desc,fds,it) { 286 if((*it).name()==a_rdesc.name()) { 287 tools_vforcit(field*,m_fields,itf) { 288 //::printf("debug : find_field : l 289 if(field_offset(*itf)==(*it).offset( 290 } 291 } 292 } 293 return 0; 294 } 295 296 void check_fields(std::ostream& a_out) const 297 const std::vector<field_desc>& fds = node_ 298 tools_vforcit(field*,m_fields,it) { 299 bool found = false; 300 tools_vforcit(field_desc,fds,itd) { 301 if( ((*itd).offset()==field_offset(*it 302 ((*itd).cls()==(*it)->s_cls()) 303 ){ 304 found = true; 305 break; 306 } 307 } 308 if(!found) { 309 a_out << "tools::sg::node::check_field 310 << " WARNING : node of class " < 311 << " has bad fields description. 312 << std::endl; 313 } 314 } 315 } 316 private: 317 std::vector<field*> m_fields; 318 }; 319 320 }} 321 322 #include "../HEADER" 323 324 #define TOOLS_NODE(a__class,a__sclass,a__paren 325 TOOLS_HEADER(a__class,a__sclass,a__parent)\ 326 virtual tools::sg::node* copy() const {retur 327 328 #define TOOLS_NODE_NO_CAST(a__class,a__sclass, 329 private:\ 330 typedef a__parent parent;\ 331 public:\ 332 TOOLS_SCLASS(a__sclass)\ 333 public:\ 334 virtual const std::string& s_cls() const {re 335 virtual tools::sg::node* copy() const {retur 336 337 #define TOOLS_NODE_T(a__T,a__class,a__sclass,a 338 private:\ 339 typedef a__parent parent;\ 340 public:\ 341 static const std::string& s_class() {\ 342 static const std::string s_v(std::string(# 343 return s_v;\ 344 }\ 345 static void check_class_name() {a__class<a__ 346 public:\ 347 virtual const std::string& s_cls() const {re 348 virtual tools::sg::node* copy() const {retur 349 public:\ 350 virtual void* cast(const std::string& a_clas 351 if(void* p = tools::cmp_cast<a__class>(thi 352 return parent::cast(a_class);\ 353 } 354 355 #define TOOLS_NODE_VT2(a__T1,a__T2,a__class,a_ 356 private:\ 357 typedef a__parent parent;\ 358 public:\ 359 static const std::string& s_class() {\ 360 static const std::string s_v(std::string(# 361 return s_v;\ 362 }\ 363 static void check_class_name() {a__class<a__ 364 public:\ 365 virtual const std::string& s_cls() const {re 366 /*virtual tools::sg::node* copy() const {ret 367 public:\ 368 virtual void* cast(const std::string& a_clas 369 if(void* p = tools::cmp_cast<a__class>(thi 370 return parent::cast(a_class);\ 371 } 372 373 #endif