]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/tgdb/TileCache.cxx
Remove using std:: from the metar header, remove HTTP support, add very basic unit...
[simgear.git] / simgear / scene / tgdb / TileCache.cxx
index 1d34fd8df06ff04ebfa457ff1a02b42dca2aff80..04ef996f282a3b026ebb0115eea9d68cf9e0449c 100644 (file)
@@ -1,4 +1,4 @@
-// newcache.cxx -- routines to handle scenery tile caching
+// TileCache.cxx -- routines to handle scenery tile caching
 //
 // Written by Curtis Olson, started December 2000.
 //
@@ -47,14 +47,12 @@ TileCache::~TileCache( void ) {
 
 
 // Free a tile cache entry
-void TileCache::entry_free( long cache_index ) {
-    SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING CACHE ENTRY = " << cache_index );
-    TileEntry *tile = tile_cache[cache_index];
+void TileCache::entry_free( long tile_index ) {
+    SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING CACHE ENTRY = " << tile_index );
+    TileEntry *tile = tile_cache[tile_index];
     tile->removeFromSceneGraph();
-
+    tile_cache.erase( tile_index );
     delete tile;
-
-    tile_cache.erase( cache_index );
 }
 
 
@@ -67,9 +65,7 @@ void TileCache::init( void ) {
     SG_LOG( SG_TERRAIN, SG_INFO, "  current cache size = "
             << tile_cache.size() );
 
-#if 0 // don't clear the cache
     clear_cache();
-#endif
 
     SG_LOG( SG_TERRAIN, SG_INFO, "  done with init()"  );
 }
@@ -84,13 +80,12 @@ bool TileCache::exists( const SGBucket& b ) const {
 }
 
 
-// Return the index of the oldest tile in the cache, return -1 if
+// Return the index of a tile to be dropped from the cache, return -1 if
 // nothing available to be removed.
-long TileCache::get_oldest_tile() {
-    // we need to free the furthest entry
+long TileCache::get_drop_tile() {
     long min_index = -1;
-    double timestamp = 0.0;
     double min_time = DBL_MAX;
+    float priority = FLT_MAX;
 
     tile_map_iterator current = tile_cache.begin();
     tile_map_iterator end = tile_cache.end();
@@ -98,15 +93,27 @@ long TileCache::get_oldest_tile() {
     for ( ; current != end; ++current ) {
         long index = current->first;
         TileEntry *e = current->second;
-        if ( e->is_loaded() ) {
-            timestamp = e->get_timestamp();
-            if ( timestamp < min_time ) {
-                min_time = timestamp;
+        if (( !e->is_current_view() )&&
+            ( e->is_expired(current_time) ))
+        {
+            if (e->is_expired(current_time - 1.0)&&
+                !e->is_loaded())
+            {
+                /* Immediately drop "empty" tiles which are no longer used/requested, and were last requested > 1 second ago...
+                 * Allow a 1 second timeout since an empty tiles may just be loaded...
+                 */
+                SG_LOG( SG_TERRAIN, SG_DEBUG, "    dropping an unused and empty tile");
+                break;
+            }
+            if (( e->get_time_expired() < min_time )||
+                (( e->get_time_expired() == min_time)&&
+                 ( priority > e->get_priority())))
+            {
+                // drop oldest tile with lowest priority
+                min_time = e->get_time_expired();
+                priority = e->get_priority();
                 min_index = index;
             }
-        } else {
-            SG_LOG( SG_TERRAIN, SG_DEBUG, "loaded = " << e->is_loaded()
-                    << " time stamp = " << e->get_timestamp() );
         }
     }
 
@@ -117,24 +124,27 @@ long TileCache::get_oldest_tile() {
 }
 
 
-// Clear the inner ring flag for all tiles in the cache so that the
-// external tile scheduler can flag the inner ring correctly.
-void TileCache::clear_inner_ring_flags() {
+// Clear all flags indicating tiles belonging to the current view
+void TileCache::clear_current_view()
+{
     tile_map_iterator current = tile_cache.begin();
     tile_map_iterator end = tile_cache.end();
 
     for ( ; current != end; ++current ) {
         TileEntry *e = current->second;
-        if ( e->is_loaded() ) {
-            e->set_inner_ring( false );
+        if (e->is_current_view())
+        {
+            // update expiry time for tiles belonging to most recent position
+            e->update_time_expired( current_time );
+            e->set_current_view( false );
         }
     }
 }
 
 // Clear a cache entry, note that the cache only holds pointers
 // and this does not free the object which is pointed to.
-void TileCache::clear_entry( long cache_index ) {
-    tile_cache.erase( cache_index );
+void TileCache::clear_entry( long tile_index ) {
+    tile_cache.erase( tile_index );
 }
 
 
@@ -166,8 +176,46 @@ bool TileCache::insert_tile( TileEntry *e ) {
     // register tile in the cache
     long tile_index = e->get_tile_bucket().gen_index();
     tile_cache[tile_index] = e;
-    e->set_timestamp(current_time);
+    e->update_time_expired(current_time);
 
     return true;
 }
 
+/**
+ * Reloads a tile when it's already in memory.
+ */
+void TileCache::refresh_tile(long tile_index)
+{
+    const_tile_map_iterator it = tile_cache.find( tile_index );
+    if ( it == tile_cache.end() )
+        return;
+
+    SG_LOG( SG_TERRAIN, SG_DEBUG, "REFRESHING CACHE ENTRY = " << tile_index );
+
+    if (it->second)
+        it->second->refresh();
+}
+
+// update tile's priority and expiry time according to current request
+void TileCache::request_tile(TileEntry* t,float priority,bool current_view,double request_time)
+{
+    if ((!current_view)&&(request_time<=0.0))
+        return;
+
+    // update priority when higher - or old request has expired
+    if ((t->is_expired(current_time))||
+         (priority > t->get_priority()))
+    {
+        t->set_priority( priority );
+    }
+
+    if (current_view)
+    {
+        t->update_time_expired( current_time );
+        t->set_current_view( true );
+    }
+    else
+    {
+        t->update_time_expired( current_time+request_time );
+    }
+}