]> git.mxchange.org Git - flightgear.git/commitdiff
Restructuring how tiles are freed to allow us to eventually spread the task
authorcurt <curt>
Thu, 25 Jul 2002 21:57:58 +0000 (21:57 +0000)
committercurt <curt>
Thu, 25 Jul 2002 21:57:58 +0000 (21:57 +0000)
out over multiple frames.

src/Scenery/newcache.cxx
src/Scenery/newcache.hxx
src/Scenery/tilemgr.cxx
src/Scenery/tilemgr.hxx

index 98122377c99f585a619ab246781e14a486b2af9b..9e1040d3d0506961a964fcf06fa3e07c4aabccc9 100644 (file)
@@ -171,6 +171,54 @@ bool FGNewCache::make_space() {
 }
 
 
+// Return the index of the oldest tile in the cache, return -1 if
+// nothing available to be removed.
+long FGNewCache::get_oldest_tile() {
+    // we need to free the furthest entry
+    long max_index = -1;
+    double timestamp = 0.0;
+    double min_time = 2419200000.0f; // one month should be enough
+    double max_time = 0;
+
+    tile_map_iterator current = tile_cache.begin();
+    tile_map_iterator end = tile_cache.end();
+    
+    for ( ; current != end; ++current ) {
+        long index = current->first;
+        FGTileEntry *e = current->second;
+        if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
+            
+            timestamp = e->get_timestamp();
+            if ( timestamp < min_time ) {
+                max_index = index;
+                min_time = timestamp;
+            }
+            if ( timestamp > max_time ) {
+                max_time = timestamp;
+            }
+
+        } else {
+            SG_LOG( SG_TERRAIN, SG_DEBUG, "loaded = " << e->is_loaded()
+                    << " pending models = " << e->get_pending_models()
+                    << " time stamp = " << e->get_timestamp() );
+        }
+    }
+
+    SG_LOG( SG_TERRAIN, SG_INFO, "    min_time = " << min_time );
+    SG_LOG( SG_TERRAIN, SG_INFO, "    index = " << max_index );
+    SG_LOG( SG_TERRAIN, SG_INFO, "    max_time = " << max_time );
+
+    return max_index;
+}
+
+
+// Clear a cache entry, note that the cache only holds pointers
+// and this does not free the object which is pointed to.
+void FGNewCache::clear_entry( long cache_index ) {
+    tile_cache.erase( cache_index );
+}
+
+
 // Clear all completely loaded tiles (ignores partially loaded tiles)
 void FGNewCache::clear_cache() {
 
index 4a10884bd04cd800fcd7e0b6ab10582f21a2d6d7..8060a1becea9dfe8b2978cd779d4bd55c0aa3b21 100644 (file)
@@ -85,6 +85,14 @@ public:
     // Ensure at least one entry is free in the cache
     bool make_space();
 
+    // Return the index of the oldest tile in the cache, return -1 if
+    // nothing available to be removed.
+    long get_oldest_tile();
+
+    // Clear a cache entry, note that the cache only holds pointers
+    // and this does not free the object which is pointed to.
+    void clear_entry( long cache_entry );
+
     // Clear all completely loaded tiles (ignores partially loaded tiles)
     void clear_cache();
 
index 53d2d6d4eb59e1a210e66305530fc786e1f5baec..2d3dd9dda301e63e293780be21fae19a9c319b44 100644 (file)
@@ -62,6 +62,7 @@ SGLockedQueue<FGDeferredModel *> FGTileMgr::model_queue;
 queue<FGTileEntry *> FGTileMgr::attach_queue;
 queue<FGDeferredModel *> FGTileMgr::model_queue;
 #endif // ENABLE_THREADS
+queue<FGTileEntry *> FGTileMgr::delete_queue;
 
 
 // Constructor
@@ -69,7 +70,8 @@ FGTileMgr::FGTileMgr():
     state( Start ),
     current_tile( NULL ),
     vis( 16000 ),
-    counter_hack(0)
+    counter_hack(0),
+    max_cache_size(100)
 {
 }
 
@@ -128,6 +130,19 @@ void FGTileMgr::sched_tile( const SGBucket& b ) {
     FGTileEntry *t = tile_cache.get_tile( b );
 
     if ( t == NULL ) {
+        // make space in the cache
+        while ( tile_cache.get_size() > max_cache_size ) {
+            long index = tile_cache.get_oldest_tile();
+            if ( index >= 0 ) {
+                FGTileEntry *old = tile_cache.get_tile( index );
+                delete_queue.push( old );
+                tile_cache.clear_entry( index );
+            } else {
+                // nothing to free ?!? forge ahead
+                break;
+            }
+        }
+
         // create a new entry
         FGTileEntry *e = new FGTileEntry( b );
 
@@ -174,7 +189,7 @@ void FGTileMgr::schedule_needed( double vis, SGBucket curr_bucket) {
     // cout << "xrange = " << xrange << "  yrange = " << yrange << endl;
 
     // note * 2 at end doubles cache size (for fdm and viewer)
-    tile_cache.set_max_cache_size( (2*xrange + 2) * (2*yrange + 2) * 2 );
+    max_cache_size = (2*xrange + 2) * (2*yrange + 2) * 2;
 
     SGBucket b;
 
@@ -345,6 +360,14 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters,
        // cout << "Adding ssg nodes for "
     }
 
+    if ( !delete_queue.empty() ) {
+       FGTileEntry* e = delete_queue.front();
+       delete_queue.pop();
+        e->disconnect_ssg_nodes();
+        e->free_tile();
+        delete e;
+    }
+
     // no reason to update this if we haven't moved...
     if ( longitude != last_longitude || latitude != last_latitude ) {
       // update current elevation... 
@@ -363,9 +386,10 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters,
 
 // timer event driven call to scheduler for the purpose of refreshing the tile timestamps
 void FGTileMgr::refresh_view_timestamps() {
-  SG_LOG( SG_TERRAIN, SG_INFO,
-      "Refreshing timestamps for " << current_bucket.get_center_lon() << " " << current_bucket.get_center_lat() );
-  schedule_needed(fgGetDouble("/environment/visibility-m"), current_bucket);
+    SG_LOG( SG_TERRAIN, SG_INFO,
+        "Refreshing timestamps for " << current_bucket.get_center_lon()
+        << " " << current_bucket.get_center_lat() );
+    schedule_needed(fgGetDouble("/environment/visibility-m"), current_bucket);
 }
 
 // check and set current tile and scenery center...
index 9eebc5dcb5af0c9166d9685320b455e0cfe40e85..714bafa760cd96e6d5a583be3afe111b6c24679b 100644 (file)
@@ -105,6 +105,7 @@ private:
     /**
      * tile cache
      */
+    int max_cache_size;
     FGNewCache tile_cache;
 
     /**
@@ -129,6 +130,7 @@ private:
     static queue<FGTileEntry *> attach_queue;
     static queue<FGDeferredModel *> model_queue;
 #endif // ENABLE_THREADS
+    static queue<FGTileEntry *> delete_queue;
 
 public:
 
@@ -137,13 +139,6 @@ public:
      */
     static void ready_to_attach( FGTileEntry *t ) { attach_queue.push( t ); }
 
-#ifdef WISH_PLIB_WAS_THREADED // but it isn't
-    /**
-     * Tile is detatched from scene graph and is ready to delete
-     */
-    inline void ready_to_delete( FGTileEntry *t ) { loader.remove( t ); }
-#endif
-
     /**
      * Add a pending model to the 'deferred model load' queue
      */