Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/sg/node

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/sg/node (Version 11.3.0) and /externals/g4tools/include/tools/sg/node (Version 11.0.p2)


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