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   virtual void* cast(const std::string& a_class) const {
0032     if(void* p = cmp_cast<node>(this,a_class)) return p;
0033     return 0;
0034   }
0035   virtual const std::string& s_cls() const = 0;
0036 public:
0037   virtual node* copy() const = 0;
0038 
0039   virtual unsigned int cls_version() const {return 1;}
0040 
0041   virtual const desc_fields& node_desc_fields() const {
0042     static const desc_fields s_v;
0043     return s_v;
0044   }
0045 
0046   virtual void render(render_action&) {}
0047   virtual void pick(pick_action&) {}
0048   virtual void bbox(bbox_action&) {}
0049   virtual void search(search_action& a_action) {
0050     if(a_action.what()==search_action::search_node_of_class) {
0051       if(void* p = cast(a_action.sclass())) {
0052         a_action.add_obj(p);
0053         if(a_action.stop_at_first()) a_action.set_done(true);
0054       }
0055     } else if(a_action.what()==search_action::search_path_to_node) {
0056       if(this==a_action.node()){
0057         a_action.path_push(this); //ending node in the path.
0058         a_action.set_done(true);
0059       }
0060     } else if(a_action.what()==search_action::search_path_to_node_of_class) {
0061       if(cast(a_action.sclass())) {
0062         search_action::path_t path = a_action.path();
0063         path.push_back(this);
0064         a_action.add_path(path);
0065         if(a_action.stop_at_first()) a_action.set_done(true);
0066       }
0067     }
0068   }
0069   virtual void get_matrix(get_matrix_action& a_action) {
0070     if(this==a_action.node()){
0071       a_action.set_found_model(a_action.model_matrix());
0072       a_action.set_done(true);
0073     }
0074   }
0075   virtual bool write(write_action& a_action) {
0076     if(!a_action.beg_node(*this)) return false;
0077     if(!write_fields(a_action)) return false;
0078     if(!a_action.end_node(*this)) return false;
0079     return true;
0080   }
0081   virtual void event(event_action&) {}
0082   virtual bool read(read_action& a_action) {return read_fields(a_action);}
0083   virtual void is_visible(visible_action&) {}
0084 
0085   virtual void protocol_one_fields(std::vector<field*>& a_fields) const {a_fields = m_fields;}
0086 
0087   virtual bool draw_in_frame_buffer() const {return false;}  // marker nodes return true.
0088 public:
0089   virtual bool touched() { //virtual for plotter.
0090     tools_vforcit(field*,m_fields,it) {
0091       if((*it)->touched()) return true;
0092     }
0093     return false;
0094   }
0095   virtual void reset_touched() {
0096     tools_vforcit(field*,m_fields,it) (*it)->reset_touched();
0097   }
0098 public:
0099   node()
0100   {
0101   }
0102   virtual ~node(){
0103   }
0104 protected:
0105   node(const node&)
0106   {
0107   }
0108   node& operator=(const node&){
0109     return *this;
0110   }
0111 protected:
0112   void add_field(field* a_field) {
0113     m_fields.push_back(a_field); //it does not take ownerhship.
0114   }
0115   bool write_fields(write_action& a_action) {
0116 
0117     check_fields(a_action.out()); //costly.
0118 
0119     unsigned int index = 0;
0120     tools_vforcit(field*,m_fields,it) {
0121       if(!(*it)->write(a_action.buffer())) {
0122         a_action.out() << "node::write_fields :"
0123                        << " for field index " << index
0124                        << " and field class " << (*it)->s_cls()
0125                        << " of node class " << s_cls()
0126                        << " : field.write() failed" << "."
0127                        << std::endl;
0128         return false;
0129       }
0130       index++;
0131     }
0132     return true;
0133   }
0134 
0135   bool read_fields(read_action& a_action) { //used in protocol-2.
0136     node_desc rndesc;
0137     if(!a_action.get_node_desc(s_cls(),rndesc)) {
0138       a_action.out() << "tools::node::read_fields :"
0139                      << " for node class " << s_cls()
0140                      << " : read_action.get_node_desc() failed."
0141                      << std::endl;
0142       return false;
0143     }
0144     //Whatever the current node fields, we must read all rndesc.fields() :
0145     tools_vforcit(field_desc,rndesc.fields(),it) {
0146       const field_desc& fdesc = *it;
0147 
0148       field* fd = find_field(fdesc);
0149       if(!fd) {
0150         a_action.out() << "tools::node::read_fields :"
0151                        << " for node class " << s_cls()
0152                        << " : field desc name " << fdesc.name()
0153                        << " : field desc class " << fdesc.cls()
0154                        << " : field desc offset " << fdesc.offset()
0155                        << " : field not found."
0156                        << "."
0157                        << std::endl;
0158         fd = a_action.field_factory().create(fdesc.cls());
0159         if(!fd) {
0160           a_action.out() << "tools::node::read_fields :"
0161                          << " for node class " << s_cls()
0162                          << " : field desc class " << fdesc.cls()
0163                          << " : can't create generic field."
0164                          << "."
0165                          << std::endl;
0166           return false;
0167         }
0168       } 
0169 
0170       if(!fd->read(a_action.buffer())) {
0171         a_action.out() << "tools::node::read_fields :"
0172                        << " for node class " << s_cls()
0173                        << " : and field class " << fd->s_cls()
0174                        << " : field read() failed."
0175                        << std::endl;
0176         return false;
0177       }
0178     }
0179 
0180     //NOTE : if some current node fields had not been found
0181     //       in rndesc.fields(), they catch the default value
0182     //       of the node fields.
0183 
0184     return true;
0185   }
0186 public:
0187   void touch() {
0188     if(m_fields.empty()) return;
0189     m_fields.front()->touch();
0190   }
0191 
0192 public:
0193   field& field_from_desc(const field_desc& a_desc) const {
0194     //WARNING : touchy.
0195     return *((field*)((char*)this+a_desc.offset()));
0196   }
0197   void dump_field_descs(std::ostream& a_out) const {
0198     a_out << "field descs of node class " << s_cls() << " :" << std::endl;
0199     const std::vector<field_desc>& fds = node_desc_fields();
0200     tools_vforcit(field_desc,fds,itd) {
0201       a_out << "name " << (*itd).name()
0202             << ", class " << (*itd).cls()
0203             << ", offset " << (*itd).offset()
0204             << std::endl;
0205     }
0206   }
0207   field* find_field_by_name(const std::string& a_name) const {
0208     // a_name is of the form <class>.<field>. For example for color on sg::text, there are :
0209     //   tools::sg::back_area.color
0210     //   tools::sg::text.color
0211     const std::vector<field_desc>& fds = node_desc_fields();
0212     for(auto it = fds.crbegin(); it != fds.crend(); ++it) {
0213       if((*it).name()==a_name) {
0214         tools_vforcit(field*,m_fields,itf) {
0215           if(field_offset(*itf)==(*it).offset()) return (*itf);
0216         }
0217       }
0218     }
0219     return 0;
0220   }
0221 protected:
0222   field_desc::offset_t field_offset(const field* a_field) const {
0223     //WARNING : touchy.
0224     return ((char*)(a_field)-(char*)(this));
0225   }
0226 
0227   field* find_field(const field_desc& a_rdesc) const {
0228     const std::vector<field_desc>& fds = node_desc_fields();
0229     tools_vforcit(field_desc,fds,it) {
0230       if((*it).name()==a_rdesc.name()) {
0231         tools_vforcit(field*,m_fields,itf) {
0232           if(field_offset(*itf)==(*it).offset()) return (*itf);
0233         }
0234       }
0235     }
0236     return 0;
0237   }
0238 
0239   void check_fields(std::ostream& a_out) const {
0240     const std::vector<field_desc>& fds = node_desc_fields();
0241     tools_vforcit(field*,m_fields,it) {
0242       bool found = false;
0243       tools_vforcit(field_desc,fds,itd) {
0244         if( ((*itd).offset()==field_offset(*it)) &&
0245             ((*itd).cls()==(*it)->s_cls())
0246         ){
0247           found = true;
0248           break;
0249         }
0250       }
0251       if(!found) {
0252         a_out << "tools::sg::node::check_fields :"
0253               << " WARNING : node of class " << s_cls()
0254               << " has bad fields description."
0255               << std::endl;
0256       }
0257     }
0258   }
0259 private:
0260   std::vector<field*> m_fields;
0261 };
0262 
0263 }}
0264 
0265 #include "../HEADER"
0266 
0267 #define TOOLS_NODE(a__class,a__sclass,a__parent)\
0268   TOOLS_HEADER(a__class,a__sclass,a__parent)\
0269   virtual tools::sg::node* copy() const {return new a__class(*this);}
0270 
0271 #define TOOLS_NODE_NO_CAST(a__class,a__sclass,a__parent)\
0272 private:\
0273   typedef a__parent parent;\
0274 public:\
0275   TOOLS_SCLASS(a__sclass)\
0276 public:\
0277   virtual const std::string& s_cls() const {return s_class();}\
0278   virtual tools::sg::node* copy() const {return new a__class(*this);}
0279 
0280 #define TOOLS_NODE_T(a__T,a__class,a__sclass,a__parent)\
0281 private:\
0282   typedef a__parent parent;\
0283 public:\
0284   static const std::string& s_class() {\
0285     static const std::string s_v(std::string(#a__class)+"<"+a__T::s_class()+">");\
0286     return s_v;\
0287   }\
0288   static void check_class_name() {a__class<a__T>::s_class();}\
0289 public:\
0290   virtual const std::string& s_cls() const {return s_class();}\
0291   virtual tools::sg::node* copy() const {return new a__class(*this);}\
0292 public:\
0293   virtual void* cast(const std::string& a_class) const {\
0294     if(void* p = tools::cmp_cast<a__class>(this,a_class)) return p;\
0295     return parent::cast(a_class);\
0296   }
0297 
0298 #define TOOLS_NODE_VT2(a__T1,a__T2,a__class,a__sclass,a__parent)\
0299 private:\
0300   typedef a__parent parent;\
0301 public:\
0302   static const std::string& s_class() {\
0303     static const std::string s_v(std::string(#a__class)+"<"+a__T1::s_class()+","+a__T2::s_class()+">");\
0304     return s_v;\
0305   }\
0306   static void check_class_name() {a__class<a__T1,a__T2>::s_class();}\
0307 public:\
0308   virtual const std::string& s_cls() const {return s_class();}\
0309   /*virtual tools::sg::node* copy() const {return new a__class(*this);}*/\
0310 public:\
0311   virtual void* cast(const std::string& a_class) const {\
0312     if(void* p = tools::cmp_cast<a__class>(this,a_class)) return p;\
0313     return parent::cast(a_class);\
0314   }
0315 
0316 #endif