Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/sg/node is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_sg_node
0005 #define tools_sg_node
0006 
0007 #include "field"
0008 #include "search_action"
0009 #include "write_action"
0010 #include "read_action"
0011 #include "get_matrix_action"
0012 #include "node_desc"
0013 
0014 #include "../forit"
0015 
0016 namespace tools {
0017 namespace sg {
0018   class render_action;
0019   class pick_action;
0020   class bbox_action;
0021   class event_action;
0022   class visible_action;
0023 }}
0024 
0025 namespace tools {
0026 namespace sg {
0027 
0028 class node {
0029 public:
0030   TOOLS_SCLASS(tools::sg::node)
0031 //public:
0032 //  static bool is_a(const std::string& a_class) {return rcmp(a_class,s_class());}
0033 // in a derived class:
0034 //  static bool is_a(const std::string& a_class) {
0035 //    if(rcmp(a_class,s_class())) return true;
0036 //    return parent::is_a(a_class);
0037 //  }
0038   virtual void* cast(const std::string& a_class) const {
0039     if(void* p = cmp_cast<node>(this,a_class)) return p;
0040     return 0;
0041   }
0042   virtual const std::string& s_cls() const = 0;
0043 public:
0044   virtual node* copy() const = 0;
0045 
0046   virtual unsigned int cls_version() const {return 1;}
0047 
0048   virtual const desc_fields& node_desc_fields() const {
0049     static const desc_fields s_v;
0050     return s_v;
0051   }
0052 
0053   virtual void render(render_action&) {}
0054   virtual void pick(pick_action&) {}
0055   virtual void bbox(bbox_action&) {}
0056   virtual void search(search_action& a_action) {
0057     if(a_action.what()==search_action::search_node_of_class) {
0058       if(void* p = cast(a_action.sclass())) {
0059         a_action.add_obj(p);
0060         if(a_action.stop_at_first()) a_action.set_done(true);
0061       }
0062     } else if(a_action.what()==search_action::search_path_to_node) {
0063       if(this==a_action.node()){
0064         a_action.path_push(this); //ending node in the path.
0065         a_action.set_done(true);
0066       }
0067     } else if(a_action.what()==search_action::search_path_to_node_of_class) {
0068       if(cast(a_action.sclass())) {
0069         search_action::path_t path = a_action.path();
0070         path.push_back(this);
0071         a_action.add_path(path);
0072         if(a_action.stop_at_first()) a_action.set_done(true);
0073       }
0074     }
0075   }
0076   virtual void get_matrix(get_matrix_action& a_action) {
0077     if(this==a_action.node()){
0078       a_action.set_found_model(a_action.model_matrix());
0079       a_action.set_done(true);
0080     }
0081   }
0082   virtual bool write(write_action& a_action) {
0083     if(!a_action.beg_node(*this)) return false;
0084     if(!write_fields(a_action)) return false;
0085     if(!a_action.end_node(*this)) return false;
0086     return true;
0087   }
0088   virtual void event(event_action&) {}
0089   virtual bool read(read_action& a_action) {return read_fields(a_action);}
0090   virtual void is_visible(visible_action&) {}
0091 
0092   virtual void protocol_one_fields(std::vector<field*>& a_fields) const {a_fields = m_fields;}
0093 
0094   virtual bool draw_in_frame_buffer() const {return false;}  // marker nodes return true.
0095 public:
0096   virtual bool touched() { //virtual for plotter.
0097     tools_vforcit(field*,m_fields,it) {
0098       if((*it)->touched()) return true;
0099     }
0100     return false;
0101   }
0102   virtual void reset_touched() {
0103     tools_vforcit(field*,m_fields,it) (*it)->reset_touched();
0104   }
0105 public:
0106   node()
0107   {
0108 #ifdef TOOLS_MEM
0109     mem::increment(s_class().c_str());
0110 #endif
0111   }
0112   virtual ~node(){
0113 #ifdef TOOLS_MEM
0114     mem::decrement(s_class().c_str());
0115 #endif
0116   }
0117 protected:
0118   node(const node&)
0119   {
0120 #ifdef TOOLS_MEM
0121     mem::increment(s_class().c_str());
0122 #endif
0123   }
0124   node& operator=(const node&){
0125     return *this;
0126   }
0127 protected:
0128   void add_field(field* a_field) {
0129     m_fields.push_back(a_field); //it does not take ownerhship.
0130   }
0131   //TOOLS_CLASS_STRING(fields_end) //for write_bsg, sg::rbsg
0132   bool write_fields(write_action& a_action) {
0133 
0134     check_fields(a_action.out()); //costly.
0135   //dump_field_descs(a_action.out());
0136 
0137     unsigned int index = 0;
0138     tools_vforcit(field*,m_fields,it) {
0139       if(!(*it)->write(a_action.buffer())) {
0140         a_action.out() << "node::write_fields :"
0141                        << " for field index " << index
0142                        << " and field class " << (*it)->s_cls()
0143                        << " of node class " << s_cls()
0144                        << " : field.write() failed" << "."
0145                        << std::endl;
0146         return false;
0147       }
0148       index++;
0149     }
0150     return true;
0151   }
0152 
0153   bool read_fields(read_action& a_action) { //used in protocol-2.
0154     node_desc rndesc;
0155     if(!a_action.get_node_desc(s_cls(),rndesc)) {
0156       a_action.out() << "tools::node::read_fields :"
0157                      << " for node class " << s_cls()
0158                      << " : read_action.get_node_desc() failed."
0159                      << std::endl;
0160       return false;
0161     }
0162     //Whatever the current node fields, we must read all rndesc.fields() :
0163     tools_vforcit(field_desc,rndesc.fields(),it) {
0164       const field_desc& fdesc = *it;
0165 
0166       field* fd = find_field(fdesc);
0167       if(!fd) {
0168         a_action.out() << "tools::node::read_fields :"
0169                        << " for node class " << s_cls()
0170                        << " : field desc name " << fdesc.name()
0171                        << " : field desc class " << fdesc.cls()
0172                        << " : field desc offset " << fdesc.offset()
0173                        << " : field not found."
0174                        << "."
0175                        << std::endl;
0176 //#define TOOLS_NODE_DEBUG_READ_FIELD
0177 #ifdef TOOLS_NODE_DEBUG_READ_FIELD
0178         check_fields(a_action.out()); //costly.
0179         dump_field_descs(a_action.out());
0180        {a_action.out() << "read field descs of node class " << s_cls() << " :" << std::endl;
0181         tools_vforcit(field_desc,rndesc.fields(),itr) {
0182           a_action.out() << "name " << (*itr).name()
0183                 << ", class " << (*itr).cls()
0184                 << ", offset " << (*itr).offset()
0185                 << std::endl;
0186         }}
0187        {a_action.out() << "m_fields of node class " << s_cls() << " :" << std::endl;
0188         tools_vforcit(field*,m_fields,itm) {
0189           a_action.out() << "field class " << (*itm)->s_cls()
0190                 << ", found offset " << field_offset(*itm)
0191                 << std::endl;
0192         }}
0193         ::exit(0);
0194 #endif
0195         fd = a_action.field_factory().create(fdesc.cls());
0196         if(!fd) {
0197           a_action.out() << "tools::node::read_fields :"
0198                          << " for node class " << s_cls()
0199                          << " : field desc class " << fdesc.cls()
0200                          << " : can't create generic field."
0201                          << "."
0202                          << std::endl;
0203           return false;
0204         }
0205       } /*else {
0206         a_action.out() << "debug : tools::node::read_fields :"
0207                        << " for node class " << s_cls()
0208                        << " : field desc class " << fdesc.cls()
0209                        << " : field desc offset " << fdesc.offset()
0210                        << " : field found."
0211                        << "."
0212                        << std::endl;
0213       }*/
0214 
0215       if(!fd->read(a_action.buffer())) {
0216         a_action.out() << "tools::node::read_fields :"
0217                        << " for node class " << s_cls()
0218                        << " : and field class " << fd->s_cls()
0219                        << " : field read() failed."
0220                        << std::endl;
0221         return false;
0222       }
0223       //fd->dump(a_action.out());
0224     }
0225 
0226     //NOTE : if some current node fields had not been found
0227     //       in rndesc.fields(), they catch the default value
0228     //       of the node fields.
0229 
0230     return true;
0231   }
0232 public:
0233   void touch() {
0234     if(m_fields.empty()) return;
0235     m_fields.front()->touch();
0236   }
0237 /*
0238   bool equal(const node& a_node) const {
0239     if(m_fields.size()!=a_node.m_fields.size()) return false;
0240     std::vector<field*>::iterator it = m_fields.begin();
0241     std::vector<field*>::iterator ait = a_node.m_fields.begin();
0242     for(;it!=m_fields.end();++it,++ait) {
0243       if(!(*it)->equal(*(*ait))) return false;
0244     }
0245     return true;
0246   }
0247 */
0248 public:
0249   field& field_from_desc(const field_desc& a_desc) const {
0250     //WARNING : touchy.
0251     return *((field*)((char*)this+a_desc.offset()));
0252   }
0253   void dump_field_descs(std::ostream& a_out) const {
0254     a_out << "field descs of node class " << s_cls() << " :" << std::endl;
0255     const std::vector<field_desc>& fds = node_desc_fields();
0256     tools_vforcit(field_desc,fds,itd) {
0257       a_out << "name " << (*itd).name()
0258             << ", class " << (*itd).cls()
0259             << ", offset " << (*itd).offset()
0260             << std::endl;
0261     }
0262   }
0263   field* find_field_by_name(const std::string& a_name) const {
0264     // a_name is of the form <class>.<field>. For example for color on sg::text, there are :
0265     //   tools::sg::back_area.color
0266     //   tools::sg::text.color
0267     const std::vector<field_desc>& fds = node_desc_fields();
0268     tools_vforcrit(field_desc,fds,it) {
0269       if((*it).name()==a_name) {
0270         tools_vforcit(field*,m_fields,itf) {
0271           if(field_offset(*itf)==(*it).offset()) return (*itf);
0272         }
0273       }
0274     }
0275     return 0;
0276   }
0277 protected:
0278   field_desc::offset_t field_offset(const field* a_field) const {
0279     //WARNING : touchy.
0280     return ((char*)(a_field)-(char*)(this));
0281   }
0282 
0283   field* find_field(const field_desc& a_rdesc) const {
0284     const std::vector<field_desc>& fds = node_desc_fields();
0285     tools_vforcit(field_desc,fds,it) {
0286       if((*it).name()==a_rdesc.name()) {
0287         tools_vforcit(field*,m_fields,itf) {
0288           //::printf("debug : find_field :   look : %s\n",field_name(*(*it)).c_str());
0289           if(field_offset(*itf)==(*it).offset()) return (*itf);
0290         }
0291       }
0292     }
0293     return 0;
0294   }
0295 
0296   void check_fields(std::ostream& a_out) const {
0297     const std::vector<field_desc>& fds = node_desc_fields();
0298     tools_vforcit(field*,m_fields,it) {
0299       bool found = false;
0300       tools_vforcit(field_desc,fds,itd) {
0301         if( ((*itd).offset()==field_offset(*it)) &&
0302             ((*itd).cls()==(*it)->s_cls())
0303         ){
0304           found = true;
0305           break;
0306         }
0307       }
0308       if(!found) {
0309         a_out << "tools::sg::node::check_fields :"
0310               << " WARNING : node of class " << s_cls()
0311               << " has bad fields description."
0312               << std::endl;
0313       }
0314     }
0315   }
0316 private:
0317   std::vector<field*> m_fields;
0318 };
0319 
0320 }}
0321 
0322 #include "../HEADER"
0323 
0324 #define TOOLS_NODE(a__class,a__sclass,a__parent)\
0325   TOOLS_HEADER(a__class,a__sclass,a__parent)\
0326   virtual tools::sg::node* copy() const {return new a__class(*this);}
0327 
0328 #define TOOLS_NODE_NO_CAST(a__class,a__sclass,a__parent)\
0329 private:\
0330   typedef a__parent parent;\
0331 public:\
0332   TOOLS_SCLASS(a__sclass)\
0333 public:\
0334   virtual const std::string& s_cls() const {return s_class();}\
0335   virtual tools::sg::node* copy() const {return new a__class(*this);}
0336 
0337 #define TOOLS_NODE_T(a__T,a__class,a__sclass,a__parent)\
0338 private:\
0339   typedef a__parent parent;\
0340 public:\
0341   static const std::string& s_class() {\
0342     static const std::string s_v(std::string(#a__class)+"<"+a__T::s_class()+">");\
0343     return s_v;\
0344   }\
0345   static void check_class_name() {a__class<a__T>::s_class();}\
0346 public:\
0347   virtual const std::string& s_cls() const {return s_class();}\
0348   virtual tools::sg::node* copy() const {return new a__class(*this);}\
0349 public:\
0350   virtual void* cast(const std::string& a_class) const {\
0351     if(void* p = tools::cmp_cast<a__class>(this,a_class)) return p;\
0352     return parent::cast(a_class);\
0353   }
0354 
0355 #define TOOLS_NODE_VT2(a__T1,a__T2,a__class,a__sclass,a__parent)\
0356 private:\
0357   typedef a__parent parent;\
0358 public:\
0359   static const std::string& s_class() {\
0360     static const std::string s_v(std::string(#a__class)+"<"+a__T1::s_class()+","+a__T2::s_class()+">");\
0361     return s_v;\
0362   }\
0363   static void check_class_name() {a__class<a__T1,a__T2>::s_class();}\
0364 public:\
0365   virtual const std::string& s_cls() const {return s_class();}\
0366   /*virtual tools::sg::node* copy() const {return new a__class(*this);}*/\
0367 public:\
0368   virtual void* cast(const std::string& a_class) const {\
0369     if(void* p = tools::cmp_cast<a__class>(this,a_class)) return p;\
0370     return parent::cast(a_class);\
0371   }
0372 
0373 #endif