]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scenery/newcache.cxx
Make FGViewer::update() a pure virtual because FGViewer is a base class
[flightgear.git] / src / Scenery / newcache.cxx
index b6d26bb7f2bc0f47f3a797f20becfeb021f2c02a..b9ffb038fda1d3fadd32f21324b3285e0b1f0809 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
 
 
 #include "newcache.hxx"
 #include "tileentry.hxx"
-#include "tilemgr.hxx"         // temp, need to delete later
-
-SG_USING_NAMESPACE(std);
 
 
-// the tile cache
-FGNewCache global_tile_cache;
+SG_USING_NAMESPACE(std);
 
 
 // Constructor
-FGNewCache::FGNewCache( void ) {
+FGNewCache::FGNewCache( void ) :
+    max_cache_size(50)
+{
     tile_cache.clear();
 }
 
@@ -66,55 +64,48 @@ 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 right now
+    clear_cache();
+#endif
 
     SG_LOG( SG_TERRAIN, SG_INFO, "  done with init()"  );
 }
 
 
 // Search for the specified "bucket" in the cache
-bool FGNewCache::exists( const SGBucket& b ) {
+bool FGNewCache::exists( const SGBucket& b ) const {
     long tile_index = b.gen_index();
-    tile_map_iterator it = tile_cache.find( tile_index );
+    const_tile_map_iterator it = tile_cache.find( tile_index );
 
     return ( it != tile_cache.end() );
 }
 
 
+// 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() );
@@ -140,13 +131,12 @@ void FGNewCache::fill_in( const SGBucket& b ) {
     // 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() {
     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 );
 
@@ -169,26 +159,29 @@ void FGNewCache::make_space() {
            long index = current->first;
            FGTileEntry *e = current->second;
 
-           // calculate approximate distance from view point
-           sgdCopyVec3( abs_view_pos,
-                        globals->get_current_view()->get_abs_view_pos() );
-
-           SG_LOG( SG_TERRAIN, SG_DEBUG, "DIST Abs view pos = " 
-                   << abs_view_pos[0] << ","
-                   << abs_view_pos[1] << ","
-                   << abs_view_pos[2] );
-           SG_LOG( SG_TERRAIN, SG_DEBUG,
-                   "    ref point = " << e->center );
-
-           sgdVec3 center;
-           sgdSetVec3( center, e->center.x(), e->center.y(), e->center.z() );
-           dist = sgdDistanceVec3( center, abs_view_pos );
-
-           SG_LOG( SG_TERRAIN, SG_DEBUG, "    distance = " << dist );
-
-           if ( dist > max_dist ) {
-               max_dist = dist;
-               max_index = index;
+           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() );
+
+               SG_LOG( SG_TERRAIN, SG_DEBUG, "DIST Abs view pos = " 
+                       << abs_view_pos[0] << ","
+                       << abs_view_pos[1] << ","
+                       << abs_view_pos[2] );
+               SG_LOG( SG_TERRAIN, SG_DEBUG,
+                       "    ref point = " << e->center );
+
+               sgdVec3 center;
+               sgdSetVec3( center,
+                           e->center.x(), e->center.y(), e->center.z() );
+               dist = sgdDistanceVec3( center, abs_view_pos );
+
+               SG_LOG( SG_TERRAIN, SG_DEBUG, "    distance = " << dist );
+
+               if ( dist > max_dist ) {
+                   max_dist = dist;
+                   max_index = index;
+               }
            }
        }
 
@@ -201,8 +194,48 @@ void FGNewCache::make_space() {
            SG_LOG( SG_TERRAIN, SG_DEBUG, "    index = " << max_index );
            entry_free( max_index );
        } else {
-           SG_LOG( SG_TERRAIN, SG_ALERT, "WHOOPS!!! Dying in next_avail()" );
+           SG_LOG( SG_TERRAIN, SG_ALERT, "WHOOPS!!! Dying in make_space()"
+                    "tile cache is full, but no entries available to removal.");
            exit( -1 );
        }
     }
 }
+
+
+// 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 )
+{
+    // clear out a distant entry in the cache if needed.
+    make_space();
+
+    // register it in the cache
+    long tile_index = e->get_tile_bucket().gen_index();
+    tile_cache[tile_index] = e;
+
+}