Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef tools_sg_holder 5 #define tools_sg_holder 6 7 // class to manage an object. 8 // Only one holder owns the object. In case 9 // of holder copy(), the new holder receives a null object. 10 11 #include "node" 12 13 #include "sf_string" 14 15 namespace tools { 16 namespace sg { 17 18 class base_holder : public node { 19 TOOLS_NODE(base_holder,tools::sg::base_holder,node) 20 public: 21 base_holder(const std::string& a_name):parent(),m_name(a_name) {} 22 virtual ~base_holder(){} 23 public: 24 base_holder(const base_holder& a_from):parent(a_from),m_name(a_from.m_name) {} 25 base_holder& operator=(const base_holder& a_from){ 26 parent::operator=(a_from); 27 m_name = a_from.m_name; 28 return *this; 29 } 30 public: 31 const std::string& name() const {return m_name;} 32 protected: 33 std::string m_name; 34 }; 35 36 template <class T> 37 class holder : public base_holder { 38 typedef base_holder parent; 39 public: 40 //WARNING : we do not put the T class name in the name of this class. 41 // We put it in the class_name field. 42 // We do that because of the bsg file format in order to be able 43 // to read back the object without having the T class around. 44 TOOLS_T_SCLASS(T,tools::sg::holder) 45 public: 46 virtual void* cast(const std::string& a_class) const { 47 if(void* p = cmp_cast< holder<T> >(this,a_class)) {return p;} 48 return parent::cast(a_class); 49 } 50 virtual node* copy() const {return new holder(*this);} 51 virtual const std::string& s_cls() const {return s_class();} 52 public: 53 sf_string class_name; 54 public: 55 virtual const desc_fields& node_desc_fields() const { 56 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::holder) 57 static const desc_fields s_v(parent::node_desc_fields(),1, //WARNING : take care of count. 58 TOOLS_ARG_FIELD_DESC(class_name) 59 ); 60 return s_v; 61 } 62 private: 63 void add_fields(){ 64 add_field(&class_name); 65 } 66 public: 67 holder(T* a_obj = 0,const std::string& a_name = "",bool a_own=true) 68 :parent(a_name) 69 ,class_name(T::s_class()) 70 ,m_obj(a_obj) //it takes a_obj ownership. 71 ,m_own(a_own) 72 { 73 add_fields(); 74 } 75 76 virtual ~holder(){if(m_own) delete m_obj;} 77 public: 78 //any copy of a holder does NOT own any object (and we empty the name). 79 holder(const holder& a_from) 80 :parent(a_from) 81 ,class_name(std::string()) 82 ,m_obj(0) 83 ,m_own(false) 84 { 85 parent::m_name.clear(); 86 add_fields(); 87 } 88 holder& operator=(const holder& a_from){ 89 parent::operator=(a_from); 90 class_name.value().clear(); 91 m_obj = 0; 92 m_own = false; 93 parent::m_name.clear(); 94 return *this; 95 } 96 public: 97 const T* object() const {return m_obj;} 98 T* object() {return m_obj;} 99 protected: 100 T* m_obj; 101 bool m_own; 102 }; 103 104 template <class T> 105 inline holder<T>* cast_holder(node& a_node) { 106 typedef holder<T> h_t; 107 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 108 if(!_h) return 0; 109 return (_h->class_name.value()==T::s_class()?_h:0); 110 } 111 112 template <class T> 113 inline const holder<T>* cast_holder(const node& a_node) { 114 typedef holder<T> h_t; 115 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 116 if(!_h) return 0; 117 return (_h->class_name.value()==T::s_class()?_h:0); 118 } 119 120 template <class T> 121 inline const T* cast_holder_object(const node& a_node) { 122 typedef holder<T> h_t; 123 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 124 if(!_h) return 0; 125 return (_h->class_name.value()==T::s_class()?_h->object():0); 126 } 127 template <class T> 128 inline T* cast_holder_object(node& a_node) { 129 typedef holder<T> h_t; 130 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 131 if(!_h) return 0; 132 return (_h->class_name.value()==T::s_class()?_h->object():0); 133 } 134 135 template <class T> 136 inline void remove_holders(std::vector<node*>& a_vec){ 137 typedef holder<T> h_t; 138 139 std::vector<node*>::iterator it; 140 for(it=a_vec.begin();it!=a_vec.end();) { 141 if(h_t* h = cast_holder<T>(*(*it))){ 142 it = a_vec.erase(it); 143 delete h; 144 continue; 145 } 146 147 ++it; 148 } 149 } 150 151 template <class T> 152 inline void remove_holders(std::vector<node*>& a_vec,const std::string& a_name){ 153 typedef holder<T> h_t; 154 155 std::vector<node*>::iterator it; 156 for(it=a_vec.begin();it!=a_vec.end();) { 157 if(h_t* h = cast_holder<T>(*(*it))){ 158 if(h->name()==a_name) { 159 it = a_vec.erase(it); 160 delete h; 161 continue; 162 } 163 } 164 165 ++it; 166 } 167 } 168 169 template <class T> 170 inline T* find_holder(std::vector<node*>& a_vec,const std::string& a_name) { 171 //return the first named found. 172 173 typedef holder<T> h_t; 174 std::vector<node*>::iterator it; 175 for(it=a_vec.begin();it!=a_vec.end();++it) { 176 if(h_t* h = cast_holder<T>(*(*it))){ 177 if(h->name()==a_name) return h->object(); 178 } 179 } 180 return 0; 181 } 182 183 template <class T> 184 inline T* find_first_holder(std::vector<node*>& a_vec){ 185 //return the first T found. 186 187 typedef holder<T> h_t; 188 std::vector<node*>::iterator it; 189 for(it=a_vec.begin();it!=a_vec.end();++it) { 190 if(h_t* h = cast_holder<T>(*(*it))) return h->object(); 191 } 192 193 194 return 0; 195 } 196 197 }} 198 199 #endif