- Timestamp:
- 01/17/17 19:15:37 (8 years ago)
- Location:
- trunk/nv
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/ecs/ecs.hh
r530 r536 182 182 } 183 183 184 virtual void attach( handle_type parent, handle_type child ) 185 { 186 m_handles.detach( child ); 187 m_handles.attach( parent, child ); 188 } 189 190 handle_type get_parent( handle_type h ) const 191 { 192 return h ? m_handles.get_parent( h ) : handle_type(); 193 } 194 195 handle_type next( handle_type h ) const 196 { 197 return h ? m_handles.next( h ) : handle_type(); 198 } 199 200 handle_type first( handle_type h ) const 201 { 202 return h ? m_handles.first( h ) : handle_type(); 203 } 204 184 205 void remove( handle_type h ) 185 206 { 207 handle_type ch = m_handles.first( h ); 208 while ( handle_type r = ch ) 209 { 210 ch = m_handles.next( ch ); 211 remove( r ); 212 } 186 213 for ( auto c : m_components ) 187 214 c->remove( h ); … … 208 235 protected: 209 236 210 handle_ manager< handle_type >m_handles;237 handle_tree_manager< handle_type > m_handles; 211 238 vector< component_interface* > m_components; 212 239 vector< receiver_interface* > m_receivers; … … 246 273 value_type& insert( handle_type h ) 247 274 { 248 /*index_type i = */m_index.insert( h ); 249 //NV_ASSERT( i == m_data.size(), "Fail!" ); 275 index_type i = m_index.insert( h ); 276 NV_ASSERT( i == index_type( m_data.size() ), "Fail!" ); 277 NV_UNUSED( i ); 250 278 m_data.emplace_back(); 251 279 return m_data.back(); … … 255 283 value_type& insert( handle_type h, Args&&... args ) 256 284 { 257 /*index_type i = */m_index.insert( h ); 258 //NV_ASSERT( i == m_data.size(), "Fail!" ); 285 index_type i = m_index.insert( h ); 286 NV_ASSERT( i == index_type( m_data.size() ), "Fail!" ); 287 NV_UNUSED( i ); 259 288 m_data.emplace_back( nv::forward<Args>( args )... ); 260 289 return m_data.back(); … … 302 331 return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr; 303 332 } 304 305 333 306 334 virtual void remove( handle_type h ) -
trunk/nv/stl/handle_manager.hh
r530 r536 95 95 value_type counter; 96 96 index_type next_free; 97 97 98 98 index_entry() : counter( 0 ), next_free( NONE ) {} 99 99 }; … … 118 118 }; 119 119 120 template < typename Handle, typename Index = sint32 > 121 class handle_tree_manager 122 { 123 typedef Index index_type; 124 static const index_type NONE = index_type( -1 ); 125 static const index_type USED = index_type( -2 ); 126 public: 127 128 typedef Handle handle_type; 129 typedef typename handle_type::value_type value_type; 130 131 handle_tree_manager() 132 : m_first_free( NONE ), m_last_free( NONE ) {} 133 134 handle_type create_handle() 135 { 136 typedef handle_operator<handle_type> hop; 137 value_type i = get_free_entry(); 138 m_entries[i].counter++; 139 NV_ASSERT( m_entries[i].counter != 0, "Out of handles!" ); 140 m_entries[i].next_free = USED; 141 return hop::create( i, m_entries[i].counter ); 142 } 143 144 void free_handle( handle_type h ) 145 { 146 remove( h ); 147 value_type index = h.index(); 148 NV_ASSERT( m_entries[index].next_free == USED, "Unused handle freed!" ); 149 NV_ASSERT( m_entries[index].counter == handle_operator<handle_type>::get_counter( h ), "Handle corruption!" ); 150 m_entries[index].next_free = NONE; 151 if ( m_last_free == NONE ) 152 { 153 m_first_free = m_last_free = static_cast<index_type>( index ); 154 return; 155 } 156 m_entries[static_cast<value_type>( m_last_free )].next_free = static_cast<index_type>( index ); 157 m_last_free = static_cast<index_type>( index ); 158 } 159 160 void attach( handle_type parent, handle_type child ) 161 { 162 value_type pindex = parent.index(); 163 value_type cindex = child.index(); 164 NV_ASSERT( m_entries[cindex].parent == NONE, "Attach called on handle with parent!" ); 165 m_entries[cindex].parent = pindex; 166 m_entries[cindex].next_sibling = m_entries[pindex].first_child; 167 m_entries[cindex].prev_sibling = NONE; 168 m_entries[pindex].first_child = cindex; 169 } 170 171 handle_type get_parent( handle_type h ) const 172 { 173 NV_ASSERT( is_valid( h ), "INVALID HANDLE" ); 174 value_type pindex = m_entries[h.index()].parent; 175 typedef handle_operator<handle_type> hop; 176 return pindex == NONE ? handle_type() : hop::create( pindex, m_entries[pindex].counter ); 177 } 178 179 handle_type next( handle_type h ) const 180 { 181 NV_ASSERT( is_valid( h ), "INVALID HANDLE" ); 182 value_type nindex = m_entries[ h.index() ].next_sibling; 183 typedef handle_operator<handle_type> hop; 184 return nindex == NONE ? handle_type() : hop::create( nindex, m_entries[nindex].counter ); 185 } 186 187 handle_type first( handle_type h ) const 188 { 189 NV_ASSERT( is_valid( h ), "INVALID HANDLE" ); 190 value_type nindex = m_entries[h.index()].first_child; 191 typedef handle_operator<handle_type> hop; 192 return nindex == NONE ? handle_type() : hop::create( nindex, m_entries[nindex].counter ); 193 } 194 195 196 void remove( handle_type h ) 197 { 198 NV_ASSERT( m_entries[h.index()].first_child == NONE, "Remove called on handle with children!" ); 199 detach( h ); 200 } 201 202 void remove_and_orphan( handle_type h ) 203 { 204 detach( h ); 205 value_type index = h.index(); 206 while ( m_entries[index].first_child != NONE ) 207 { 208 value_type child = m_entries[index].first_child; 209 m_entries[index].first_child = m_entries[child].next_sibling; 210 m_entries[child].parent = NONE; 211 m_entries[child].next_sibling = NONE; 212 m_entries[child].prev_sibling = NONE; 213 } 214 } 215 216 void detach( handle_type h ) 217 { 218 value_type index = h.index(); 219 value_type pindex = m_entries[index].parent; 220 value_type next_index = m_entries[index].next_sibling; 221 value_type prev_index = m_entries[index].prev_sibling; 222 223 m_entries[index].parent = NONE; 224 m_entries[index].next_sibling = NONE; 225 m_entries[index].prev_sibling = NONE; 226 227 if ( pindex == NONE ) 228 { 229 NV_ASSERT( next_index == NONE, "Hierarchy fail! next_index" ); 230 NV_ASSERT( prev_index == NONE, "Hierarchy fail! prev_index" ); 231 return; 232 } 233 if ( value_type( m_entries[pindex].first_child ) == index ) 234 { 235 NV_ASSERT( prev_index == NONE, "Hierarchy fail! prev_index" ); 236 m_entries[pindex].first_child = next_index; 237 if ( next_index == NONE ) // only child 238 return; 239 m_entries[next_index].prev_sibling = NONE; 240 } 241 else 242 { 243 NV_ASSERT( prev_index != NONE, "Hierarchy fail! prev_index" ); 244 if ( next_index != NONE ) 245 m_entries[next_index].prev_sibling = prev_index; 246 if ( prev_index != NONE ) 247 m_entries[prev_index].next_sibling = next_index; 248 } 249 } 250 251 bool is_valid( handle_type h ) const 252 { 253 typedef handle_operator<handle_type> hop; 254 if ( h.is_nil() ) return false; 255 if ( h.index() >= m_entries.size() ) return false; 256 const index_entry& entry = m_entries[h.index()]; 257 return entry.next_free == USED && entry.counter == hop::get_counter( h ); 258 } 259 260 void clear() 261 { 262 m_first_free = NONE; 263 m_last_free = NONE; 264 m_entries.clear(); 265 } 266 267 private: 268 struct index_entry 269 { 270 value_type counter; 271 index_type next_free; 272 273 index_type parent; 274 index_type first_child; 275 index_type next_sibling; 276 index_type prev_sibling; 277 278 index_entry() 279 : counter( 0 ) 280 , next_free( NONE ) 281 , parent( NONE ) 282 , first_child( NONE ) 283 , next_sibling( NONE ) 284 , prev_sibling( NONE ) 285 {} 286 }; 287 288 value_type get_free_entry() 289 { 290 if ( m_first_free != NONE ) 291 { 292 value_type result = static_cast<value_type>( m_first_free ); 293 m_first_free = m_entries[result].next_free; 294 m_entries[result].next_free = USED; 295 if ( m_first_free == NONE ) m_last_free = NONE; 296 return result; 297 } 298 m_entries.emplace_back(); 299 return value_type( m_entries.size() - 1 ); 300 } 301 302 index_type m_first_free; 303 index_type m_last_free; 304 vector< index_entry > m_entries; 305 }; 306 307 120 308 } 121 309
Note: See TracChangeset
for help on using the changeset viewer.