X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=src%2FScenery%2Fnewcache.cxx;h=8c0ebdb3cac1fa9ec87ecc221c6ea8645e6be3e0;hb=470292a4341334820681d6d6e2ecc6039b8d6dd6;hp=9d480724334b9473c22fee1ebe6398e2fc09dd69;hpb=a29cb28e9386a7fcfcbcbde47d6d5553476d58d9;p=flightgear.git diff --git a/src/Scenery/newcache.cxx b/src/Scenery/newcache.cxx index 9d4807243..8c0ebdb3c 100644 --- a/src/Scenery/newcache.cxx +++ b/src/Scenery/newcache.cxx @@ -30,7 +30,7 @@ #endif #include -#include +#include #include // plib include @@ -39,6 +39,7 @@ #include #include
+#include
#include // for scenery.center #include "newcache.hxx" @@ -49,7 +50,9 @@ SG_USING_NAMESPACE(std); // Constructor -FGNewCache::FGNewCache( void ) { +FGNewCache::FGNewCache( void ) : + max_cache_size(50) +{ tile_cache.clear(); } @@ -62,41 +65,32 @@ FGNewCache::~FGNewCache( void ) { // Free a tile cache entry void FGNewCache::entry_free( long cache_index ) { SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING CACHE ENTRY = " << cache_index ); - FGTileEntry *e = tile_cache[cache_index]; - e->free_tile(); - delete e; + FGTileEntry *tile = tile_cache[cache_index]; + tile->disconnect_ssg_nodes(); + +#ifdef WISH_PLIB_WAS_THREADED // but it isn't + tile->sched_removal(); +#else + tile->free_tile(); + delete tile; +#endif + tile_cache.erase( cache_index ); } // Initialize the tile cache subsystem void FGNewCache::init( void ) { - // This is a hack that should really get cleaned up at some point - extern ssgBranch *terrain; - SG_LOG( SG_TERRAIN, SG_INFO, "Initializing the tile cache." ); - // expand cache if needed. For best results ... i.e. to avoid - // tile load problems and blank areas: - max_cache_size = 50; // a random number to start with SG_LOG( SG_TERRAIN, SG_INFO, " max cache size = " << max_cache_size ); SG_LOG( SG_TERRAIN, SG_INFO, " current cache size = " << tile_cache.size() ); - - tile_map_iterator current = tile_cache.begin(); - tile_map_iterator end = tile_cache.end(); - - for ( ; current != end; ++current ) { - long index = current->first; - SG_LOG( SG_TERRAIN, SG_DEBUG, "clearing " << index ); - FGTileEntry *e = current->second; - e->tile_bucket.make_bad(); - entry_free(index); - } - // and ... just in case we missed something ... - terrain->removeAllKids(); +#if 0 // don't clear the cache + clear_cache(); +#endif SG_LOG( SG_TERRAIN, SG_INFO, " done with init()" ); } @@ -111,45 +105,15 @@ bool FGNewCache::exists( const SGBucket& b ) const { } -// depricated for threading -#if 0 -// Fill in a tile cache entry with real data for the specified bucket -void FGNewCache::fill_in( const SGBucket& b ) { - SG_LOG( SG_TERRAIN, SG_DEBUG, "FILL IN CACHE ENTRY = " << b.gen_index() ); - - // clear out a distant entry in the cache if needed. - make_space(); - - // create the entry - FGTileEntry *e = new FGTileEntry( b ); - - // register it in the cache - long tile_index = b.gen_index(); - tile_cache[tile_index] = e; - - SGPath tile_path; - if ( globals->get_fg_scenery() != (string)"" ) { - tile_path.set( globals->get_fg_scenery() ); - } else { - tile_path.set( globals->get_fg_root() ); - tile_path.append( "Scenery" ); - } - - // Load the appropriate data file - e->load( tile_path, true ); -} -#endif - - // Ensure at least one entry is free in the cache -void FGNewCache::make_space() { +bool FGNewCache::make_space() { SG_LOG( SG_TERRAIN, SG_DEBUG, "Make space in cache" ); SG_LOG( SG_TERRAIN, SG_DEBUG, "cache entries = " << tile_cache.size() ); SG_LOG( SG_TERRAIN, SG_DEBUG, "max size = " << max_cache_size ); if ( (int)tile_cache.size() < max_cache_size ) { // space in the cache, return - return; + return true; } while ( (int)tile_cache.size() >= max_cache_size ) { @@ -166,7 +130,7 @@ void FGNewCache::make_space() { long index = current->first; FGTileEntry *e = current->second; - if ( e->is_loaded() ) { + if ( e->is_loaded() && (e->get_pending_models() == 0) ) { // calculate approximate distance from view point sgdCopyVec3( abs_view_pos, globals->get_current_view()->get_abs_view_pos() ); @@ -189,36 +153,66 @@ void FGNewCache::make_space() { max_dist = dist; max_index = index; } - } + } else { + SG_LOG( SG_TERRAIN, SG_INFO, "loaded = " << e->is_loaded() + << " pending models = " << e->get_pending_models() ); + } } // If we made it this far, then there were no open cache entries. - // We will instead free the furthest cache entry and return it's - // index. - + // We will instead free the furthest cache entry and return true + + SG_LOG( SG_TERRAIN, SG_INFO, " max_dist = " << max_dist ); + SG_LOG( SG_TERRAIN, SG_INFO, " index = " << max_index ); if ( max_index >= 0 ) { - SG_LOG( SG_TERRAIN, SG_DEBUG, " max_dist = " << max_dist ); - SG_LOG( SG_TERRAIN, SG_DEBUG, " index = " << max_index ); entry_free( max_index ); + return true; } else { - SG_LOG( SG_TERRAIN, SG_ALERT, "WHOOPS!!! Dying in next_avail()" ); - exit( -1 ); + SG_LOG( SG_TERRAIN, SG_ALERT, "WHOOPS!!! can't make_space(), tile " + "cache is full, but no entries available for removal." ); + return false; } } } +// Clear all completely loaded tiles (ignores partially loaded tiles) +void FGNewCache::clear_cache() { + // This is a hack that should really get cleaned up at some point + extern ssgBranch *terrain; + + tile_map_iterator current = tile_cache.begin(); + tile_map_iterator end = tile_cache.end(); + + for ( ; current != end; ++current ) { + long index = current->first; + SG_LOG( SG_TERRAIN, SG_DEBUG, "clearing " << index ); + FGTileEntry *e = current->second; + if ( e->is_loaded() && (e->get_pending_models() == 0) ) { + e->tile_bucket.make_bad(); + entry_free(index); + } + } + + // and ... just in case we missed something ... + terrain->removeAllKids(); +} + + /** * Create a new tile and schedule it for loading. */ -void -FGNewCache::insert_tile( FGTileEntry *e ) -{ +bool FGNewCache::insert_tile( FGTileEntry *e ) { // clear out a distant entry in the cache if needed. - make_space(); + if ( make_space() ) { + // register it in the cache + long tile_index = e->get_tile_bucket().gen_index(); + tile_cache[tile_index] = e; - // register it in the cache - long tile_index = e->get_tile_bucket().gen_index(); - tile_cache[tile_index] = e; + return true; + } else { + // failed to find cache space + return false; + } }