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