g4tools  5.4.0
node
Go to the documentation of this file.
1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
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:
31 //public:
32 // static bool is_a(const std::string& a_class) {return rcmp(a_class,s_class());}
33 // in a derived class:
34 // static bool is_a(const std::string& a_class) {
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_class) const {
39  if(void* p = cmp_cast<node>(this,a_class)) return p;
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 {return 1;}
47 
48  virtual const desc_fields& node_desc_fields() const {
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) {
58  if(void* p = cast(a_action.sclass())) {
59  a_action.add_obj(p);
60  if(a_action.stop_at_first()) a_action.set_done(true);
61  }
62  } else if(a_action.what()==search_action::search_path_to_node) {
63  if(this==a_action.node()){
64  a_action.path_push(this); //ending node in the path.
65  a_action.set_done(true);
66  }
67  } else if(a_action.what()==search_action::search_path_to_node_of_class) {
68  if(cast(a_action.sclass())) {
69  search_action::path_t path = a_action.path();
70  path.push_back(this);
71  a_action.add_path(path);
72  if(a_action.stop_at_first()) a_action.set_done(true);
73  }
74  }
75  }
76  virtual void get_matrix(get_matrix_action& a_action) {
77  if(this==a_action.node()){
78  a_action.set_found_model(a_action.model_matrix());
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) {return read_fields(a_action);}
90  virtual void is_visible(visible_action&) {}
91 
92  virtual void protocol_one_fields(std::vector<field*>& a_fields) const {a_fields = m_fields;}
93 
94  virtual bool draw_in_frame_buffer() const {return false;} // marker nodes return true.
95 public:
96  virtual bool touched() { //virtual for plotter.
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)->reset_touched();
104  }
105 public:
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 take ownerhship.
130  }
131  //TOOLS_CLASS_STRING(fields_end) //for write_bsg, sg::rbsg
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 " << index
142  << " and field class " << (*it)->s_cls()
143  << " of node class " << s_cls()
144  << " : field.write() failed" << "."
145  << std::endl;
146  return false;
147  }
148  index++;
149  }
150  return true;
151  }
152 
153  bool read_fields(read_action& a_action) { //used in protocol-2.
154  node_desc rndesc;
155  if(!a_action.get_node_desc(s_cls(),rndesc)) {
156  a_action.out() << "tools::node::read_fields :"
157  << " for node class " << s_cls()
158  << " : read_action.get_node_desc() failed."
159  << std::endl;
160  return false;
161  }
162  //Whatever the current node fields, we must read all rndesc.fields() :
163  tools_vforcit(field_desc,rndesc.fields(),it) {
164  const field_desc& fdesc = *it;
165 
166  field* fd = find_field(fdesc);
167  if(!fd) {
168  a_action.out() << "tools::node::read_fields :"
169  << " for node class " << s_cls()
170  << " : field desc name " << fdesc.name()
171  << " : field desc class " << fdesc.cls()
172  << " : field desc offset " << fdesc.offset()
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 node class " << s_cls() << " :" << std::endl;
181  tools_vforcit(field_desc,rndesc.fields(),itr) {
182  a_action.out() << "name " << (*itr).name()
183  << ", class " << (*itr).cls()
184  << ", offset " << (*itr).offset()
185  << std::endl;
186  }}
187  {a_action.out() << "m_fields of node class " << s_cls() << " :" << std::endl;
188  tools_vforcit(field*,m_fields,itm) {
189  a_action.out() << "field class " << (*itm)->s_cls()
190  << ", found offset " << field_offset(*itm)
191  << std::endl;
192  }}
193  ::exit(0);
194 #endif
195  fd = a_action.field_factory().create(fdesc.cls());
196  if(!fd) {
197  a_action.out() << "tools::node::read_fields :"
198  << " for node class " << s_cls()
199  << " : field desc class " << fdesc.cls()
200  << " : can't create generic field."
201  << "."
202  << std::endl;
203  return false;
204  }
205  } /*else {
206  a_action.out() << "debug : inlib::node::read_fields :"
207  << " for node class " << s_cls()
208  << " : field desc class " << fdesc.cls()
209  << " : field desc offset " << fdesc.offset()
210  << " : field found."
211  << "."
212  << std::endl;
213  }*/
214 
215  if(!fd->read(a_action.buffer())) {
216  a_action.out() << "tools::node::read_fields :"
217  << " for node class " << s_cls()
218  << " : and field class " << fd->s_cls()
219  << " : field read() failed."
220  << std::endl;
221  return false;
222  }
223  //fd->dump(a_action.out());
224  }
225 
226  //NOTE : if some current node fields had not been found
227  // in rndesc.fields(), they catch the default value
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()) return false;
240  std::vector<field*>::iterator it = m_fields.begin();
241  std::vector<field*>::iterator ait = a_node.m_fields.begin();
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_desc) const {
250  //WARNING : touchy.
251  return *((field*)((char*)this+a_desc.offset()));
252  }
253  void dump_field_descs(std::ostream& a_out) const {
254  a_out << "field descs of node class " << s_cls() << " :" << std::endl;
255  const std::vector<field_desc>& fds = node_desc_fields();
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& a_name) const {
264  // a_name is of the form <class>.<field>. For example for color on sg::text, there are :
265  // tools::sg::back_area.color
266  // tools::sg::text.color
267  const std::vector<field_desc>& fds = node_desc_fields();
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()) return (*itf);
272  }
273  }
274  }
275  return 0;
276  }
277 protected:
278  field_desc::offset_t field_offset(const field* a_field) const {
279  //WARNING : touchy.
280  return ((char*)(a_field)-(char*)(this));
281  }
282 
283  field* find_field(const field_desc& a_rdesc) const {
284  const std::vector<field_desc>& fds = node_desc_fields();
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 : look : %s\n",field_name(*(*it)).c_str());
289  if(field_offset(*itf)==(*it).offset()) return (*itf);
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_desc_fields();
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_fields :"
310  << " WARNING : node of class " << s_cls()
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__parent)\
325  TOOLS_HEADER(a__class,a__sclass,a__parent)\
326  virtual tools::sg::node* copy() const {return new a__class(*this);}
327 
328 #define TOOLS_NODE_NO_CAST(a__class,a__sclass,a__parent)\
329 private:\
330  typedef a__parent parent;\
331 public:\
332  TOOLS_SCLASS(a__sclass)\
333 public:\
334  virtual const std::string& s_cls() const {return s_class();}\
335  virtual tools::sg::node* copy() const {return new a__class(*this);}
336 
337 #define TOOLS_NODE_T(a__T,a__class,a__sclass,a__parent)\
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(#a__class)+"<"+a__T::s_class()+">");\
343  return s_v;\
344  }\
345  static void check_class_name() {a__class<a__T>::s_class();}\
346 public:\
347  virtual const std::string& s_cls() const {return s_class();}\
348  virtual tools::sg::node* copy() const {return new a__class(*this);}\
349 public:\
350  virtual void* cast(const std::string& a_class) const {\
351  if(void* p = tools::cmp_cast<a__class>(this,a_class)) return p;\
352  return parent::cast(a_class);\
353  }
354 
355 #define TOOLS_NODE_VT2(a__T1,a__T2,a__class,a__sclass,a__parent)\
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(#a__class)+"<"+a__T1::s_class()+","+a__T2::s_class()+">");\
361  return s_v;\
362  }\
363  static void check_class_name() {a__class<a__T1,a__T2>::s_class();}\
364 public:\
365  virtual const std::string& s_cls() const {return s_class();}\
366  /*virtual tools::sg::node* copy() const {return new a__class(*this);}*/\
367 public:\
368  virtual void* cast(const std::string& a_class) const {\
369  if(void* p = tools::cmp_cast<a__class>(this,a_class)) return p;\
370  return parent::cast(a_class);\
371  }
372 
373 #endif
tools::sg::node::write
virtual bool write(write_action &a_action)
Definition: node:82
tools::sg::field::s_cls
virtual const std::string & s_cls() const =0
read_action
tools::sg::node::check_fields
void check_fields(std::ostream &a_out) const
Definition: node:296
node_desc
tools::sg::node_desc
Definition: node_desc:13
tools::sg::node::field_offset
field_desc::offset_t field_offset(const field *a_field) const
Definition: node:278
tools::sg::node::s_cls
virtual const std::string & s_cls() const =0
tools::sg::search_action::stop_at_first
bool stop_at_first() const
Definition: search_action:70
field
tools::sg::search_action::search_path_to_node
@ search_path_to_node
Definition: search_action:61
tools::sg::node::event
virtual void event(event_action &)
Definition: node:88
tools::sg::matrix_action::model_matrix
mat4f & model_matrix()
Definition: matrix_action:73
tools::sg::node_desc::fields
const std::vector< field_desc > & fields() const
Definition: node_desc:42
tools::sg::event_action
Definition: event_action:14
tools::sg::write_action::end_node
virtual bool end_node(const node &)=0
tools::sg::node::copy
virtual node * copy() const =0
get_matrix_action
tools::sg::write_action::buffer
virtual io::iwbuf & buffer()=0
tools::sg::node::dump_field_descs
void dump_field_descs(std::ostream &a_out) const
Definition: node:253
tools::sg::node::protocol_one_fields
virtual void protocol_one_fields(std::vector< field * > &a_fields) const
Definition: node:92
tools::sg::node
Definition: node:28
tools::sg::bbox_action
Definition: bbox_action:15
tools::sg::write_action
Definition: write_action:21
tools::sg::search_action::sclass
const std::string & sclass() const
Definition: search_action:82
tools::sg::node::render
virtual void render(render_action &)
Definition: node:53
tools::sg::read_action
Definition: read_action:23
tools::sg::read_action::get_node_desc
virtual bool get_node_desc(const std::string &, node_desc &) const =0
tools::sg::search_action::path
const path_t & path() const
Definition: search_action:94
tools::sg::search_action::set_done
void set_done(bool a_value)
Definition: search_action:67
tools::sg::field
Definition: field:25
tools::sg::node::bbox
virtual void bbox(bbox_action &)
Definition: node:55
tools::sg::search_action::search_node_of_class
@ search_node_of_class
Definition: search_action:60
tools::sg::search_action::path_push
void path_push(sg::node *a_v)
Definition: search_action:90
write_action
tools::sg::field_desc::name
const std::string & name() const
Definition: field_desc:71
tools::sg::node::node
node(const node &)
Definition: node:118
tools::sg::desc_fields
Definition: field_desc:148
tools::sg::node::operator=
node & operator=(const node &)
Definition: node:124
TOOLS_SCLASS
#define TOOLS_SCLASS(a_name)
Definition: S_STRING:41
tools::sg::search_action::add_path
void add_path(const path_t &a_p)
search_path_to_node_of_class : ///////////////////////
Definition: search_action:107
tools::sg::search_action::what
search_what what() const
Definition: search_action:64
tools::sg::pick_action
Definition: pick_action:59
tools::sg::read_action::field_factory
virtual const ifield_factory & field_factory() const =0
tools::sg::get_matrix_action::set_found_model
void set_found_model(const mat4f &a_m)
Definition: get_matrix_action:44
tools::sg::node::get_matrix
virtual void get_matrix(get_matrix_action &a_action)
Definition: node:76
tools::sg::node::find_field_by_name
field * find_field_by_name(const std::string &a_name) const
Definition: node:263
tools::sg::node::cast
virtual void * cast(const std::string &a_class) const
Definition: node:38
tools_vforcrit
#define tools_vforcrit(a__T, a__v, a__it)
Definition: forit:16
tools::sg::search_action::search_path_to_node_of_class
@ search_path_to_node_of_class
Definition: search_action:62
tools::sg::ifield_factory::create
virtual field * create(const std::string &) const =0
tools::sg::get_matrix_action::set_done
void set_done(bool a_value)
Definition: get_matrix_action:47
tools::sg::field::read
virtual bool read(io::irbuf &)=0
tools::sg::node::is_visible
virtual void is_visible(visible_action &)
Definition: node:90
tools::sg::search_action::path_t
std::vector< sg::node * > path_t
Definition: search_action:93
tools::sg::search_action
Definition: search_action:19
tools::sg::node::~node
virtual ~node()
Definition: node:112
tools::sg::write_action::beg_node
virtual bool beg_node(const node &)=0
tools::sg::node::search
virtual void search(search_action &a_action)
Definition: node:56
tools::sg::render_action
Definition: render_action:24
tools::sg::node::read_fields
bool read_fields(read_action &a_action)
Definition: node:153
tools::sg::get_matrix_action::node
sg::node * node() const
Definition: get_matrix_action:51
tools::sg::get_matrix_action
Definition: get_matrix_action:17
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::sg::node::node_desc_fields
virtual const desc_fields & node_desc_fields() const
Definition: node:48
tools::sg::field_desc
Definition: field_desc:21
tools::sg::node::cls_version
virtual unsigned int cls_version() const
Definition: node:46
tools::sg::node::pick
virtual void pick(pick_action &)
Definition: node:54
tools::sg::node::add_field
void add_field(field *a_field)
Definition: node:128
tools::sg::field_desc::offset
offset_t offset() const
Definition: field_desc:73
tools::sg::node::read
virtual bool read(read_action &a_action)
Definition: node:89
tools::sg::search_action::add_obj
void add_obj(void *a_obj)
search_node_of_class : ///////////////////////////////
Definition: search_action:78
tools::file::found
bool found(const std::string &a_file, const std::string &a_what, std::vector< std::string > &a_found)
Definition: file:507
search_action
tools::sg::node::field_from_desc
field & field_from_desc(const field_desc &a_desc) const
Definition: node:249
tools::sg::action::out
std::ostream & out() const
Definition: action:51
tools::sg::node::write_fields
bool write_fields(write_action &a_action)
Definition: node:132
tools::sg::node::find_field
field * find_field(const field_desc &a_rdesc) const
Definition: node:283
tools_vforcit
#define tools_vforcit(a__T, a__v, a__it)
Definition: forit:7
tools::sg::visible_action
Definition: visible_action:12
tools::sg::node::touched
virtual bool touched()
Definition: node:96
tools::sg::node::draw_in_frame_buffer
virtual bool draw_in_frame_buffer() const
Definition: node:94
tools::sg::field_desc::offset_t
ptrdiff_t offset_t
Definition: field_desc:27
tools::sg::search_action::node
sg::node * node() const
Definition: search_action:88
tools::sg::node::touch
void touch()
Definition: node:233
tools::sg::field_desc::cls
const std::string & cls() const
Definition: field_desc:72
tools::sg::node::reset_touched
virtual void reset_touched()
Definition: node:102
tools::sg::read_action::buffer
virtual io::irbuf & buffer()=0
tools::sg::node::node
node()
Definition: node:106