Changeset 530
- Timestamp:
- 01/09/17 17:47:23 (8 years ago)
- Location:
- trunk/nv
- Files:
-
- 3 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/ecs/ecs.hh
r520 r530 17 17 #include <nv/stl/string.hh> 18 18 #include <nv/stl/handle.hh> 19 #include <nv/stl/index_table.hh> 20 #include <nv/stl/priority_queue.hh> 21 #include <nv/stl/handle_manager.hh> 19 22 #include <nv/core/types.hh> 20 23 … … 25 28 { 26 29 27 template < 28 typename Handle = handle<>, 29 typename Index = sint32 30 > 31 class index_table 32 { 33 public: 34 typedef Handle handle_type; 35 typedef Index index_type; 36 37 index_table() {} 38 index_table( uint32 reserve ) 39 { 40 m_indexes.reserve( reserve ); 41 } 42 43 index_type insert( handle_type h ) 44 { 45 NV_ASSERT( !exists( h ), "Reinserting handle!" ); 46 resize_indexes_to( index_type( h.index() ) ); 47 index_type lindex = m_handles.size(); 48 m_indexes[h.index()] = index_type( lindex ); 49 m_handles.push_back( h ); 50 return lindex; 51 } 52 53 bool exists( handle_type h ) const 54 { 55 if ( h.is_nil() || h.index() >= m_indexes.size() ) return false; 56 return m_indexes[h.index()] >= 0; 57 } 58 59 index_type get( handle_type h ) const 60 { 61 if ( h.is_nil() || h.index() >= m_indexes.size() ) return -1; 62 return m_indexes[h.index()]; 63 } 64 65 index_type remove_swap( handle_type h ) 66 { 67 if ( h.is_nil() || h.index() >= m_indexes.size() || m_indexes[h.index()] == -1 ) 68 return -1; 69 handle_type swap_handle = m_handles.back(); 70 index_type dead_eindex = m_indexes[h.index()]; 71 if ( dead_eindex != static_cast<index_type>( m_handles.size() - 1 ) ) 72 { 73 m_handles[unsigned( dead_eindex )] = swap_handle; 74 m_indexes[swap_handle.index()] = dead_eindex; 75 } 76 m_handles.pop_back(); 77 m_indexes[h.index()] = -1; 78 return dead_eindex; 79 } 80 81 index_type remove_swap( index_type dead_eindex ) 82 { 83 if ( size_t( dead_eindex ) >= m_handles.size() ) return -1; 84 handle_type h = m_handles[ dead_eindex ]; 85 handle_type swap_handle = m_handles.back(); 86 if ( dead_eindex != static_cast<index_type>( m_handles.size() - 1 ) ) 87 { 88 m_handles[unsigned( dead_eindex )] = swap_handle; 89 m_indexes[swap_handle.index()] = dead_eindex; 90 } 91 m_handles.pop_back(); 92 m_indexes[ h.index() ] = -1; 93 return dead_eindex; 94 } 95 96 97 void clear() 98 { 99 m_handles.clear(); 100 m_indexes.clear(); 101 } 102 103 handle_type get_handle( index_type i ) const { return m_handles[unsigned( i )]; } 104 105 size_t size() const { return m_handles.size(); } 106 107 private: 108 void resize_indexes_to( index_type i ) 109 { 110 index_type size = index_type( m_indexes.size() ); 111 if ( i >= size ) 112 { 113 if ( size == 0 ) size = 1; 114 while ( i >= size ) size = size * 2; 115 m_indexes.resize( static_cast<size_t>( size ), -1 ); 116 } 117 } 118 119 vector< handle_type > m_handles; 120 vector< index_type > m_indexes; 121 }; 122 123 124 125 template < typename Handle = handle<>, typename Time = f32 > 30 31 template < typename Handle, typename Time = f32 > 126 32 class ecs 127 33 { … … 202 108 bool queue( const message& m ) 203 109 { 204 push_event( m );110 m_pqueue.push( m ); 205 111 return true; 206 112 } … … 214 120 } 215 121 216 217 122 handle_type create() 218 123 { … … 224 129 if ( dtime == time_type(0) ) return; 225 130 m_time += dtime; 226 while ( !m_ queue.empty() && m_queue.front().time <= m_time )227 { 228 message msg = m_ queue.front();229 pop_event();131 while ( !m_pqueue.empty() && m_pqueue.top().time <= m_time ) 132 { 133 message msg = m_pqueue.top(); 134 m_pqueue.pop(); 230 135 dispatch( msg ); 231 136 } … … 238 143 { 239 144 time_type before = m_time; 240 if ( !m_ queue.empty() )241 { 242 message msg = m_ queue.front();145 if ( !m_pqueue.empty() ) 146 { 147 message msg = m_pqueue.top(); 243 148 m_time = msg.time; 244 pop_event();149 m_pqueue.pop(); 245 150 dispatch( msg ); 246 151 if ( before != m_time ) … … 255 160 bool events_pending() const 256 161 { 257 return !m_ queue.empty();162 return !m_pqueue.empty(); 258 163 } 259 164 260 165 const message& top_event() const 261 166 { 262 return m_ queue.front();167 return m_pqueue.top(); 263 168 } 264 169 265 170 void reset_events() 266 171 { 267 m_ queue.clear();172 m_pqueue.clear(); 268 173 m_time = time_type(0); 269 174 } … … 302 207 303 208 protected: 304 void push_event( const message& msg )305 {306 m_queue.push_back( msg );307 push_heap( m_queue.begin(), m_queue.end(), m_compare );308 }309 310 void pop_event()311 {312 pop_heap( m_queue.begin(), m_queue.end(), m_compare );313 m_queue.pop_back();314 }315 209 316 210 handle_manager< handle_type > m_handles; … … 319 213 hash_store< thash64, component_interface* > m_component_map; 320 214 time_type m_time = time_type(0); 321 vector< message > m_queue; 322 message_compare_type m_compare; 215 priority_queue< message, vector< message >, message_compare_type > m_pqueue; 323 216 }; 324 217 325 template < typename E CS, typename COMPONENT>326 class component : public E CS::component_interface218 template < typename Ecs, typename Component > 219 class component : public Ecs::component_interface 327 220 { 328 221 public: 329 typedef E CSecs_type;222 typedef Ecs ecs_type; 330 223 typedef typename ecs_type::message message_type; 331 224 typedef typename ecs_type::handle_type handle_type; 332 225 typedef typename ecs_type::time_type time_type; 333 226 typedef index_table< handle_type > index_table_type; 334 typedef C OMPONENTvalue_type;335 typedef C OMPONENTcomponent_type;227 typedef Component value_type; 228 typedef Component component_type; 336 229 typedef vector< value_type > storage_type; 337 230 typedef typename index_table_type::index_type index_type; … … 461 354 }; 462 355 463 template < typename E CS>464 class receiver : public E CS::receiver_interface356 template < typename Ecs > 357 class receiver : public Ecs::receiver_interface 465 358 { 466 359 public: 467 typedef E CSecs_type;360 typedef Ecs ecs_type; 468 361 typedef typename ecs_type::message message_type; 469 362 typedef typename ecs_type::handle_type handle_type; -
trunk/nv/engine/particle_group.hh
r520 r530 12 12 #include <nv/stl/vector.hh> 13 13 #include <nv/stl/handle.hh> 14 #include <nv/stl/handle_store.hh> 14 15 #include <nv/interface/context.hh> 15 16 -
trunk/nv/fmod/fmod_audio.hh
r399 r530 1 // Copyright (C) 2012-201 5ChaosForge Ltd1 // Copyright (C) 2012-2017 ChaosForge Ltd 2 2 // http://chaosforge.org/ 3 3 // … … 16 16 #include <nv/common.hh> 17 17 #include <nv/interface/audio.hh> 18 #include <nv/stl/handle_store.hh> 18 19 19 20 namespace nv -
trunk/nv/gl/gl_context.hh
r523 r530 15 15 16 16 #include <nv/interface/context.hh> 17 #include <nv/stl/handle_store.hh> 17 18 18 19 namespace nv -
trunk/nv/gl/gl_device.hh
r506 r530 1 // Copyright (C) 2012-201 5ChaosForge Ltd1 // Copyright (C) 2012-2017 ChaosForge Ltd 2 2 // http://chaosforge.org/ 3 3 // … … 15 15 16 16 #include <nv/interface/device.hh> 17 #include <nv/stl/handle_store.hh> 17 18 18 19 namespace nv -
trunk/nv/gui/gui_environment.hh
r492 r530 1 // Copyright (C) 2012-201 5ChaosForge Ltd1 // Copyright (C) 2012-2017 ChaosForge Ltd 2 2 // http://chaosforge.org/ 3 3 // … … 14 14 #define NV_GUI_ENVIRONMENT_HH 15 15 16 #include <nv/stl/handle_store.hh> 16 17 #include <nv/gui/gui_element.hh> 17 18 #include <nv/gui/gui_style.hh> -
trunk/nv/sdl/sdl_audio.hh
r399 r530 16 16 #include <nv/common.hh> 17 17 #include <nv/interface/audio.hh> 18 #include <nv/stl/handle_store.hh> 18 19 19 20 namespace nv -
trunk/nv/stl/handle.hh
r498 r530 1 // Copyright (C) 2014-201 5ChaosForge Ltd1 // Copyright (C) 2014-2017 ChaosForge Ltd 2 2 // http://chaosforge.org/ 3 3 // … … 15 15 #include <nv/common.hh> 16 16 #include <nv/stl/vector.hh> 17 #include <nv/stl/index_table.hh> 17 18 18 19 namespace nv … … 56 57 }; 57 58 58 template < typename HANDLE >59 class handle_operator60 {61 public:62 typedef typename HANDLE::value_type value_type;63 59 64 static HANDLE create( value_type index, value_type counter )65 {66 return HANDLE( index, counter );67 }68 static value_type get_counter( const HANDLE& h ) { return h.m_counter; }69 static value_type get_index( const HANDLE& h ) { return h.m_index; }70 };71 72 template < typename HANDLE, typename INDEX = sint32 >73 class handle_manager74 {75 typedef INDEX index_type;76 static const index_type NONE = index_type(-1);77 static const index_type USED = index_type(-2);78 public:79 80 typedef HANDLE handle_type;81 typedef typename HANDLE::value_type value_type;82 83 handle_manager() : m_first_free( NONE ), m_last_free( NONE ) {}84 85 handle_type create_handle()86 {87 typedef handle_operator<HANDLE> hop;88 value_type i = get_free_entry();89 m_entries[i].counter++;90 NV_ASSERT( m_entries[i].counter != 0, "Out of handles!" );91 m_entries[i].next_free = USED;92 return hop::create( i, m_entries[i].counter );93 }94 95 void free_handle( handle_type h )96 {97 value_type index = h.index();98 NV_ASSERT( m_entries[index].next_free == USED, "Unused handle freed!" );99 NV_ASSERT( m_entries[index].counter == handle_operator<HANDLE>::get_counter( h ), "Handle corruption!" );100 m_entries[index].next_free = NONE;101 if ( m_last_free == NONE )102 {103 m_first_free = m_last_free = static_cast<index_type>( index );104 return;105 }106 m_entries[static_cast<value_type>( m_last_free ) ].next_free = static_cast<index_type>( index );107 m_last_free = static_cast<index_type>( index );108 }109 110 bool is_valid( handle_type h ) const111 {112 typedef handle_operator<HANDLE> hop;113 if ( h.is_nil() ) return false;114 if ( h.index() >= m_entries.size() ) return false;115 const index_entry& entry = m_entries[h.index()];116 return entry.next_free == USED && entry.counter == hop::get_counter( h );117 }118 119 void clear()120 {121 m_first_free = NONE;122 m_last_free = NONE;123 m_entries.clear();124 }125 126 private:127 struct index_entry128 {129 value_type counter;130 index_type next_free;131 132 index_entry() : counter( 0 ), next_free( NONE ) {}133 };134 135 value_type get_free_entry()136 {137 if ( m_first_free != NONE )138 {139 value_type result = static_cast<value_type>( m_first_free );140 m_first_free = m_entries[result].next_free;141 m_entries[result].next_free = USED;142 if ( m_first_free == NONE ) m_last_free = NONE;143 return result;144 }145 m_entries.emplace_back();146 return value_type( m_entries.size() - 1 );147 }148 149 index_type m_first_free;150 index_type m_last_free;151 vector< index_entry > m_entries;152 };153 154 template < typename HANDLE = handle<>, typename TINDEX = sint32 >155 class packed_index_table156 {157 public:158 typedef HANDLE handle_type;159 typedef TINDEX index_type;160 packed_index_table() {}161 packed_index_table( uint32 reserve )162 {163 m_indexes.reserve( reserve );164 }165 166 index_type insert( handle_type h )167 {168 NV_ASSERT( !exists( h ), "Reinserting handle!" );169 resize_indexes_to( index_type( h.index() ) );170 index_type lindex = m_handles.size();171 m_indexes[h.index()] = index_type( lindex );172 m_handles.push_back( h );173 return lindex;174 }175 176 bool exists( handle_type h )177 {178 if ( h.is_nil() || h.index() >= m_indexes.size() ) return false;179 return m_indexes[h.index()] >= 0;180 }181 182 index_type get( handle_type h )183 {184 if ( h.is_nil() || h.index() >= m_indexes.size() ) return -1;185 return m_indexes[h.index()];186 }187 188 index_type get( handle_type h ) const189 {190 if ( h.is_nil() || h.index() >= m_indexes.size() ) return -1;191 return m_indexes[h.index()];192 }193 194 index_type remove_swap( handle_type h )195 {196 if ( h.is_nil() || h.index() >= m_indexes.size() || m_indexes[h.index()] == -1 )197 return -1;198 handle_type swap_handle = m_handles.back();199 index_type dead_eindex = m_indexes[h.index()];200 if ( dead_eindex != static_cast<index_type>( m_handles.size() - 1 ) )201 {202 // m_data[unsigned( dead_eindex )] = move( m_data.back() );203 m_handles[unsigned( dead_eindex )] = swap_handle;204 m_indexes[swap_handle.index()] = dead_eindex;205 }206 // m_data.pop_back();207 m_handles.pop_back();208 m_indexes[h.index()] = -1;209 return dead_eindex;210 }211 212 void clear()213 {214 m_handles.clear();215 m_indexes.clear();216 }217 218 handle_type get_handle( index_type i ) const { return m_handles[unsigned( i )]; }219 220 size_t size() const { return m_handles.size(); }221 222 private:223 void resize_indexes_to( index_type i )224 {225 index_type size = index_type( m_indexes.size() );226 if ( i >= size )227 {228 if ( size == 0 ) size = 1;229 while ( i >= size ) size = size * 2;230 m_indexes.resize( static_cast<size_t>( size ), -1 );231 }232 }233 234 vector< handle_type > m_handles;235 vector< index_type > m_indexes;236 };237 238 template < typename T, typename HANDLE = handle<>, typename TINDEX = sint32 >239 class packed_indexed_array240 {241 public:242 typedef HANDLE handle;243 typedef TINDEX index_type;244 typedef vector< T > storage;245 typedef T value_type;246 typedef typename storage::iterator iterator;247 typedef typename storage::const_iterator const_iterator;248 typedef typename storage::reference reference;249 typedef typename storage::const_reference const_reference;250 251 packed_indexed_array() {}252 packed_indexed_array( uint32 reserve )253 {254 m_data.reserve( reserve );255 m_indexes.reserve( reserve );256 }257 258 T* insert( handle h )259 {260 /*index_type i = */m_index.insert( h );261 //NV_ASSERT( i == m_data.size(), "Fail!" );262 m_data.emplace_back();263 return &( m_data.back() );264 }265 266 bool exists( handle h )267 {268 return m_index.exists( h );269 }270 271 T* get( handle h )272 {273 index_type i = m_index.get(h);274 return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr;275 }276 277 const T* get( handle h ) const278 {279 index_type i = m_index.get( h );280 return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr;281 }282 283 void remove( handle h )284 {285 index_type dead_eindex = m_index.remove_swap( h );286 if ( dead_eindex == -1 ) return;287 if ( dead_eindex != static_cast<index_type>( m_data.size() - 1 ) )288 {289 m_data[unsigned( dead_eindex )] = move( m_data.back() );290 }291 m_data.pop_back();292 }293 294 void clear()295 {296 m_index.clear();297 m_data.clear();298 }299 300 handle get_handle( index_type i ) const { return m_index.get_handle( i ); }301 302 const value_type& operator[] ( index_type i ) const { return m_data[i]; }303 value_type& operator[] ( index_type i ) { return m_data[i]; }304 size_t size() const { return m_data.size(); }305 306 iterator begin() { return m_data.begin(); }307 const_iterator begin() const { return m_data.cbegin(); }308 const_iterator cbegin() const { return m_data.cbegin(); }309 310 iterator end() { return m_data.end(); }311 const_iterator end() const { return m_data.cend(); }312 const_iterator cend() const { return m_data.cend(); }313 314 private:315 vector< T > m_data;316 packed_index_table< HANDLE, TINDEX > m_index;317 };318 319 template < typename T, typename HANDLE = handle<>, typename TINDEX = sint32 >320 class unpacked_indexed_array321 {322 public:323 typedef HANDLE handle;324 typedef TINDEX index_type;325 typedef vector< T > storage;326 typedef T value_type;327 typedef typename storage::iterator iterator;328 typedef typename storage::const_iterator const_iterator;329 typedef typename storage::reference reference;330 typedef typename storage::const_reference const_reference;331 332 unpacked_indexed_array() {}333 unpacked_indexed_array( uint32 reserve )334 {335 m_data.reserve( reserve );336 }337 338 T* insert( handle h )339 {340 NV_ASSERT( !exists( h ), "Reinserting handle!" );341 resize_to( index_type( h.index() ) );342 m_handles[ h.index() ] = h;343 return &( m_data[h.index()] );344 }345 346 bool exists( handle h )347 {348 if ( h.is_nil() || h.index() >= m_data.size() ) return false;349 return m_handles[h.index()].is_valid();350 }351 352 T* get( handle h )353 {354 if ( h.is_nil() || h.index() >= m_data.size() ) return nullptr;355 index_type i = h.index();356 return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr;357 }358 359 const T* get( handle h ) const360 {361 if ( h.is_nil() || h.index() >= m_data.size() ) return nullptr;362 index_type i = h.index();363 return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr;364 }365 366 void remove( handle h )367 {368 m_handles[ h.index() ] = handle();369 }370 371 void clear()372 {373 m_data.clear();374 m_handles.clear();375 }376 377 handle get_handle( index_type i ) const { return m_handles[unsigned( i )]; }378 379 const value_type& operator[] ( index_type i ) const { return m_data[i]; }380 value_type& operator[] ( index_type i ) { return m_data[i]; }381 size_t size() const { return m_data.size(); }382 383 iterator begin() { return m_data.begin(); }384 const_iterator begin() const { return m_data.cbegin(); }385 const_iterator cbegin() const { return m_data.cbegin(); }386 387 iterator end() { return m_data.end(); }388 const_iterator end() const { return m_data.cend(); }389 const_iterator cend() const { return m_data.cend(); }390 391 private:392 void resize_to( index_type i )393 {394 index_type size = index_type( m_handles.size() );395 if ( i >= size )396 {397 if ( size == 0 ) size = 1;398 while ( i >= size ) size = size * 2;399 m_data.resize( static_cast<size_t>( size ) );400 m_handles.resize( static_cast<size_t>( size ) );401 }402 }403 404 vector< T > m_data;405 vector< handle > m_handles;406 };407 408 409 template < typename T, typename HANDLE = handle<>, typename TINDEX = sint32 >410 class handle_store411 {412 public:413 typedef HANDLE handle;414 typedef TINDEX index_type;415 typedef vector< T > storage;416 typedef T value_type;417 typedef typename storage::iterator iterator;418 typedef typename storage::const_iterator const_iterator;419 typedef typename storage::reference reference;420 typedef typename storage::const_reference const_reference;421 422 handle_store() {}423 424 explicit handle_store( uint32 reserve )425 {426 m_data.reserve( reserve );427 }428 429 handle create()430 {431 handle h = m_indexes.create_handle();432 m_data.insert( h );433 return h;434 }435 436 bool is_valid( handle h )437 {438 return m_indexes.is_valid( h );439 }440 441 const value_type* get( handle h ) const442 {443 return m_data.get( h );444 }445 446 value_type* get( handle h )447 {448 return m_data.get( h );449 }450 451 void destroy( handle e )452 {453 m_data.remove( e );454 m_indexes.free_handle( e );455 }456 457 handle get_handle( index_type i ) const { return m_data.get_handle(i); }458 const value_type& operator[] ( index_type i ) const { return m_data[unsigned(i)]; }459 value_type& operator[] ( index_type i ) { return m_data[unsigned(i)]; }460 size_t size() const { return m_data.size(); }461 462 iterator begin() { return m_data.begin(); }463 const_iterator begin() const { return m_data.cbegin(); }464 const_iterator cbegin() const { return m_data.cbegin(); }465 466 iterator end() { return m_data.end(); }467 const_iterator end() const { return m_data.cend(); }468 const_iterator cend() const { return m_data.cend(); }469 470 private:471 packed_indexed_array< T, handle, TINDEX > m_data;472 handle_manager< handle > m_indexes;473 };474 475 60 } 476 61 -
trunk/nv/stl/hash_store.hh
r487 r530 1 // Copyright (C) 2015 ChaosForge Ltd1 // Copyright (C) 2015-2017 ChaosForge Ltd 2 2 // http://chaosforge.org/ 3 3 // -
trunk/nv/stl/priority_queue.hh
r487 r530 14 14 #define NV_STL_PRIORITY_QUEUE_HH 15 15 16 #include <nv/common.hh> 16 17 #include <nv/stl/vector.hh> 17 18 … … 111 112 } 112 113 114 void clear() 115 { 116 m_data.clear(); 117 } 118 113 119 void swap( this_type& rhs ) 114 120 {
Note: See TracChangeset
for help on using the changeset viewer.