medfall

A super great game engine
Log | Files | Refs

commit 566ae3528146390b19d4b7ccce3e97f386c322f8
parent 859c3a4b5713a91d2240bcdbc45eab0616a30943
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Fri Jun 16 00:16:33 +0300

Massively simpler and more efficient Pool implementation

Diffstat:
hm.cc | 16++++++++++------
mixer.cc | 11++++++-----
pool.h | 123++++++++++---------------------------------------------------------------------
3 files changed, 31 insertions(+), 119 deletions(-)
diff --git a/hm.cc b/hm.cc @@ -253,7 +253,8 @@ extern "C" GAME_FRAME( game_frame ) { { PROFILE_BLOCK( "Update fireballs" ); - for( Fireball * fireball : fireballs ) { + for( size_t i = 0; i < fireballs.elems.n; i++ ) { + Fireball * fireball = &fireballs.elems[ i ]; v3 new_pos = fireball->pos + fireball->velocity * dt; float t; @@ -263,6 +264,7 @@ extern "C" GAME_FRAME( game_frame ) { explosion->created_at = current_time; fireballs.release( fireball ); + i--; } else { const float gravity = 9.81f; @@ -280,13 +282,15 @@ extern "C" GAME_FRAME( game_frame ) { immediate_init( &imm, asdf, ARRAY_COUNT( asdf ) ); - for( Explosion * explosion : explosions ) { + for( size_t i = 0; i < explosions.elems.n; i++ ) { + Explosion * explosion = &explosions.elems[ i ]; float t = float( current_time - explosion->created_at ); if( t < 0.5f ) { immediate_sphere( &imm, explosion->pos, t * 32.0f, v4( 1, 0.5, 0, 1 ), 4 ); } else { explosions.release( explosion ); + i--; } } @@ -385,10 +389,10 @@ extern "C" GAME_FRAME( game_frame ) { ImmediateTriangle boxes[ 4096 ]; immediate_init( &imm, boxes, ARRAY_COUNT( boxes ) ); - for( const Player * player : players ) { - if( player->sid != sid ) { - v3 mins = player->pos - v3( 0.4f, 0.4f, 1.8f ); - v3 maxs = player->pos + v3( 0.4f, 0.4f, 0.1f ); + for( const Player & player : players.elems ) { + if( player.sid != sid ) { + v3 mins = player.pos - v3( 0.4f, 0.4f, 1.8f ); + v3 maxs = player.pos + v3( 0.4f, 0.4f, 0.1f ); immediate_aabb( &imm, mins, maxs, v4( 1, 1, 0, 1 ) ); } } diff --git a/mixer.cc b/mixer.cc @@ -37,10 +37,11 @@ static Pool< PlayingSound, MAX_CONCURRENT_SOUNDS > playing_sounds; static NonblockingFixedSPSCQueue< MixerCommand, COMMAND_QUEUE_SIZE > command_queue; static PlayingSoundID sound_counter; +// TODO: this should really use a hash index/pool with handles static PlayingSound * find_playing_sound( PlayingSoundID sound_id ) { - for( PlayingSound * ps : playing_sounds ) { - if( ps->id == sound_id ) { - return ps; + for( PlayingSound & ps : playing_sounds.elems ) { + if( ps.id == sound_id ) { + return &ps; } } @@ -123,8 +124,8 @@ AUDIO_OUTPUT_CALLBACK( mixer_mix ) { samples[ i ] = 0.0f; } - for( PlayingSound * ps : playing_sounds ) { - mixer_mix_sound( ps, samples, num_output_samples ); + for( PlayingSound & ps : playing_sounds.elems ) { + mixer_mix_sound( &ps, samples, num_output_samples ); } for( s32 i = 0; i < num_output_samples; i++ ) { diff --git a/pool.h b/pool.h @@ -3,125 +3,32 @@ #include "intrinsics.h" #include "array.h" -template< typename T, u32 N > -class Pool; - -template< typename T, u32 N > -class PoolIterator { -public: - PoolIterator( Pool< T, N > * p, u32 start ) { - pool = p; - idx = start; - next = idx == Pool< T, N >::INVALID_IDX ? idx : pool->nexts[ idx ]; - } - - T * operator*() { - return &pool->elems[ idx ]; - } - - bool operator!=( PoolIterator< T, N > other ) { - return idx != other.idx || next != other.next || pool != other.pool; - } - - void operator++() { - idx = next; - next = idx == Pool< T, N >::INVALID_IDX ? idx : pool->nexts[ idx ]; - } - -private: - Pool< T, N > * pool; - u32 idx; - u32 next; -}; - -template< typename T, u32 N > -class Pool { +template< typename T, size_t N > +struct Pool { public: Pool() { - clear(); - } - - void clear() { - for( u32 i = 0; i < N; i++ ) { - nexts[ i ] = i + 1; - } - nexts[ N - 1 ] = INVALID_IDX; - - first_free = 0; - first_used = INVALID_IDX; - num_used = 0; + elems = array< T >( elems_memory.ptr(), 0 ); } T * acquire() { - if( first_free == INVALID_IDX ) return NULL; + if( elems.n == N ) return NULL; - u32 idx = first_free; - - // remove idx from head of the free list - first_free = nexts[ idx ]; - - // add idx to the head of the used list - nexts[ idx ] = first_used; - prev_useds[ idx ] = INVALID_IDX; - if( first_used != INVALID_IDX ) { - prev_useds[ first_used ] = idx; - } - first_used = idx; - - num_used++; - - return &elems[ idx ]; - } - - void release( const T * elem ) { - if( elem == NULL ) return; - - u32 idx = checked_cast< u32 >( elem - elems.ptr() ); - ASSERT( idx < N ); - - // remove idx from the middle of the used list - if( nexts[ idx ] != INVALID_IDX ) { - prev_useds[ nexts[ idx ] ] = prev_useds[ idx ]; - } - if( prev_useds[ idx ] != INVALID_IDX ) { - nexts[ prev_useds[ idx ] ] = nexts[ idx ]; - } - if( first_used == idx ) { - first_used = nexts[ idx ]; - } - - // add idx to the head of the free list - nexts[ idx ] = first_free; - first_free = idx; - - num_used--; - } - - PoolIterator< T, N > begin() { - return PoolIterator< T, N >( this, first_used ); + elems.n++; + return &elems[ elems.n - 1 ]; } - PoolIterator< T, N > end() { - return PoolIterator< T, N >( this, INVALID_IDX ); - } + void release( T * x ) { + ASSERT( ( ( char * ) x - ( char * ) elems.ptr() ) % sizeof( T ) == 0 ); + ASSERT( x - elems.ptr() < ptrdiff_t( N ) ); - PoolIterator< const T, N > begin() const { - return PoolIterator< const T, N >( this, first_used ); + *x = elems[ elems.n - 1 ]; + elems.n--; } - PoolIterator< const T, N > end() const { - return PoolIterator< const T, N >( this, INVALID_IDX ); + void clear() { + elems.n = 0; } -private: - enum : u32 { INVALID_IDX = U32_MAX }; - - StaticArray< T, N > elems; - StaticArray< u32, N > nexts; - StaticArray< u32, N > prev_useds; - u32 first_free; - u32 first_used; - u32 num_used; - - friend class PoolIterator< T, N >; + StaticArray< T, N > elems_memory; + array< T > elems; };