]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scenery/newcache.cxx
Small tweaks to initialization sequence and logic so we can default to
[flightgear.git] / src / Scenery / newcache.cxx
index 9d480724334b9473c22fee1ebe6398e2fc09dd69..8c0ebdb3cac1fa9ec87ecc221c6ea8645e6be3e0 100644 (file)
@@ -30,7 +30,7 @@
 #endif
 
 #include <GL/glut.h>
-#include <simgear/xgl/xgl.h>
+#include <GL/gl.h>
 
 #include <plib/ssg.h>          // plib include
 
@@ -39,6 +39,7 @@
 #include <simgear/misc/sg_path.hxx>
 
 #include <Main/globals.hxx>
+#include <Main/viewer.hxx>
 #include <Scenery/scenery.hxx>  // 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;
+    }
 }