]> git.mxchange.org Git - flightgear.git/commitdiff
Make the tile-manager a well-behaved SGSubsystem
authorJames Turner <zakalawe@mac.com>
Fri, 1 Oct 2010 18:09:19 +0000 (19:09 +0100)
committerJames Turner <zakalawe@mac.com>
Fri, 1 Oct 2010 18:09:19 +0000 (19:09 +0100)
src/AIModel/AIAircraft.cxx
src/Main/fg_commands.cxx
src/Main/fg_init.cxx
src/Main/globals.cxx
src/Main/main.cxx
src/Scenery/tilemgr.cxx
src/Scenery/tilemgr.hxx

index 58db48478f8f4b413f92eccc3989d0de8a2f5864..f117810c17f447e29884d8e496cbf265e434efd7 100644 (file)
@@ -421,7 +421,7 @@ void FGAIAircraft::getGroundElev(double dt) {
         double range = 500.0;
         if (!globals->get_tile_mgr()->scenery_available(pos, range)) {
             // Try to shedule tiles for that position.
-            globals->get_tile_mgr()->update( pos, range );
+            globals->get_tile_mgr()->schedule_tiles_at( pos, range );
         }
 
         double alt;
index 1fe2c4ce464f801e235750e8c242162d08cdd135..74551bc9170b683f7fc1aa87a7c82b97112e1d3e 100644 (file)
@@ -556,15 +556,9 @@ do_tile_cache_reload (const SGPropertyNode * arg)
     if ( !freeze ) {
        fgSetBool("/sim/freeze/master", true);
     }
-    if ( globals->get_tile_mgr()->init() ) {
-       // Load the local scenery data
-        double visibility_meters = fgGetDouble("/environment/visibility-m");
-       globals->get_tile_mgr()->update( visibility_meters );
-    } else {
-       SG_LOG( SG_GENERAL, SG_ALERT, 
-               "Error in Tile Manager initialization!" );
-       exit(-1);
-    }
+
+    globals->get_subsystem("tile-manager")->reinit();
+
     if ( !freeze ) {
        fgSetBool("/sim/freeze/master", false);
     }
@@ -1241,8 +1235,6 @@ do_presets_commit (const SGPropertyNode * arg)
 
     fgReInitSubsystems();
 
-    globals->get_tile_mgr()->update( fgGetDouble("/environment/visibility-m") );
-
 #if 0
     if ( ! fgGetBool("/sim/presets/onground") ) {
         fgSetBool( "/sim/freeze/master", true );
index 38c4d8ee56e618da4b484082f04d2aaa69bf68bb..c62e96eafaf6e29aedb722a1975f20bec10bf49e 100644 (file)
@@ -1321,14 +1321,8 @@ bool fgInitSubsystems() {
     // Initialize the scenery management subsystem.
     ////////////////////////////////////////////////////////////////////
 
-    if ( globals->get_tile_mgr()->init() ) {
-        // Load the local scenery data
-        double visibility_meters = fgGetDouble("/environment/visibility-m");
-        globals->get_tile_mgr()->update( visibility_meters );
-    } else {
-        SG_LOG( SG_GENERAL, SG_ALERT, "Error in Tile Manager initialization!" );
-        exit(-1);
-    }
+    globals->add_subsystem("tile-manager", globals->get_tile_mgr(), 
+      SGSubsystemMgr::DISPLAY);
 
     globals->get_scenery()->get_scene_graph()
         ->addChild(simgear::Particles::getCommonRoot());
@@ -1553,7 +1547,8 @@ void fgReInitSubsystems()
     globals->get_controls()->reset_all();
 
     globals->get_subsystem("time")->reinit();
-
+    globals->get_subsystem("tile-manager")->reinit();
+    
     if ( !freeze ) {
         fgSetBool("/sim/freeze/master", false);
     }
@@ -1580,7 +1575,6 @@ void doSimulatorReset(void)  // from gui_local.cxx -- TODO merge with fgReInitSu
 
     fgReInitSubsystems();
 
-    globals->get_tile_mgr()->update(fgGetDouble("/environment/visibility-m"));
     fgSetBool("/sim/signals/reinit", false);
 
     if (!freeze)
index 0bd14a3bc56f6f722fce888c31adafaae4e237f2..c52c5e1823c68cf4cf6dbd39f5bc9b8d98e312f7 100644 (file)
@@ -193,7 +193,6 @@ FGGlobals::~FGGlobals()
     delete model_mgr;
     delete channel_options_list;
     delete initial_waypoints;
-    delete tile_mgr;
     delete scenery;
     delete fontcache;
 
index 2522e69dd859f0d4f7bc87d8436ce320dfe3ac5a..294c39c924346f08b69da8c20327b12db2a7804a 100644 (file)
@@ -159,19 +159,6 @@ static void fgMainLoop( void ) {
     
     globals->get_subsystem_mgr()->update(sim_dt);
     globals->get_aircraft_model()->update(sim_dt);
-    
-    //
-    // Tile Manager updates - see if we need to load any new scenery tiles.
-    //   this code ties together the fdm, viewer and scenery classes...
-    //   we may want to move this to its own class at some point
-    //
-    double visibility_meters = fgGetDouble("/environment/visibility-m");
-    globals->get_tile_mgr()->prep_ssg_nodes( visibility_meters );
-
-    // update tile manager for view...
-    SGVec3d viewPos = globals->get_current_view()->get_view_pos();
-    SGGeod geodViewPos = SGGeod::fromCart(viewPos);
-    globals->get_tile_mgr()->update(geodViewPos, visibility_meters);
 
     // run Nasal's settimer() loops right before the view manager
     globals->get_event_mgr()->update(sim_dt);
index e5cd08bbb281bd8b9358b71f0cd468d831bbde06..5abcf791db30254caccc9208a153c736f5a7e3d3 100644 (file)
@@ -67,7 +67,7 @@ FGTileMgr::~FGTileMgr() {
 
 
 // Initialize the Tile Manager subsystem
-int FGTileMgr::init() {
+void FGTileMgr::init() {
     SG_LOG( SG_TERRAIN, SG_INFO, "Initializing Tile Manager subsystem." );
 
     _options = new SGReaderWriterBTGOptions;
@@ -80,65 +80,75 @@ int FGTileMgr::init() {
     std::copy(sc.begin(), sc.end(), back_inserter(fp));
 
     TileEntry::setModelLoadHelper(this);
+    
+    _visibilityMeters = fgGetNode("/environment/visibility-m", true);
+    
 
-    tile_cache.init();
+    reinit();
+}
 
-    state = Inited;
 
-    previous_bucket.make_bad();
-    current_bucket.make_bad();
+void FGTileMgr::reinit()
+{
+  tile_cache.init();
+  
+  state = Inited;
 
-    longitude = latitude = -1000.0;
+  previous_bucket.make_bad();
+  current_bucket.make_bad();
+  longitude = latitude = -1000.0;
 
-    return 1;
+  // force an update now
+  update(0.0);
 }
 
 // schedule a tile for loading
 void FGTileMgr::sched_tile( const SGBucket& b, const bool is_inner_ring ) {
     // see if tile already exists in the cache
     TileEntry *t = tile_cache.get_tile( b );
-
-    if ( !t ) {
-        // make space in the cache
-        SceneryPager* pager = FGScenery::getPagerSingleton();
-        while ( (int)tile_cache.get_size() > tile_cache.get_max_cache_size() ) {
-            long index = tile_cache.get_oldest_tile();
-            if ( index >= 0 ) {
-                TileEntry *old = tile_cache.get_tile( index );
-                tile_cache.clear_entry( index );
-                osg::ref_ptr<osg::Object> subgraph = old->getNode();
-                old->removeFromSceneGraph();
-                delete old;
-                // zeros out subgraph ref_ptr, so subgraph is owned by
-                // the pager and will be deleted in the pager thread.
-                pager->queueDeleteRequest(subgraph);
-            } else {
-                // nothing to free ?!? forge ahead
-                break;
-            }
+    if (t) {
+      t->set_inner_ring( is_inner_ring );
+      return;
+    }
+    
+    // make space in the cache
+    SceneryPager* pager = FGScenery::getPagerSingleton();
+    while ( (int)tile_cache.get_size() > tile_cache.get_max_cache_size() ) {
+        long index = tile_cache.get_oldest_tile();
+        if ( index >= 0 ) {
+            TileEntry *old = tile_cache.get_tile( index );
+            tile_cache.clear_entry( index );
+            osg::ref_ptr<osg::Object> subgraph = old->getNode();
+            old->removeFromSceneGraph();
+            delete old;
+            // zeros out subgraph ref_ptr, so subgraph is owned by
+            // the pager and will be deleted in the pager thread.
+            pager->queueDeleteRequest(subgraph);
+        } else {
+            // nothing to free ?!? forge ahead
+            break;
         }
+    }
 
-        // create a new entry
-        TileEntry *e = new TileEntry( b );
+    // create a new entry
+    TileEntry *e = new TileEntry( b );
 
-        // insert the tile into the cache
-        if ( tile_cache.insert_tile( e ) ) {
-            // update_queues will generate load request
-        } else {
-            // insert failed (cache full with no available entries to
-            // delete.)  Try again later
-            delete e;
-        }
-        // Attach to scene graph
-        e->addToSceneGraph(globals->get_scenery()->get_terrain_branch());
+    // insert the tile into the cache
+    if ( tile_cache.insert_tile( e ) ) {
+        // update_queues will generate load request
     } else {
-        t->set_inner_ring( is_inner_ring );
+        // insert failed (cache full with no available entries to
+        // delete.)  Try again later
+        delete e;
     }
+    // Attach to scene graph
+    e->addToSceneGraph(globals->get_scenery()->get_terrain_branch());
 }
 
 
 // schedule a needed buckets for loading
-void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) {
+void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) {
+    
     // sanity check (unfortunately needed!)
     if ( longitude < -180.0 || longitude > 180.0 
          || latitude < -90.0 || latitude > 90.0 )
@@ -155,8 +165,6 @@ void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) {
     SG_LOG( SG_TERRAIN, SG_INFO,
             "scheduling needed tiles for " << longitude << " " << latitude );
 
-    // vis = fgGetDouble("/environment/visibility-m");
-
     double tile_width = curr_bucket.get_width_m();
     double tile_height = curr_bucket.get_height_m();
     // cout << "tile width = " << tile_width << "  tile_height = "
@@ -209,29 +217,6 @@ void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) {
     }
 }
 
-
-void FGTileMgr::initialize_queue()
-{
-    // First time through or we have teleported, initialize the
-    // system and load all relavant tiles
-
-    SG_LOG( SG_TERRAIN, SG_INFO, "Initialize_queue(): Updating Tile list for "
-            << current_bucket );
-    // cout << "tile cache size = " << tile_cache.get_size() << endl;
-
-    // wipe/initialize tile cache
-    // tile_cache.init();
-    previous_bucket.make_bad();
-
-    // build the local area list and schedule tiles for loading
-
-    // start with the center tile and work out in concentric
-    // "rings"
-
-    double visibility_meters = fgGetDouble("/environment/visibility-m");
-    schedule_needed(visibility_meters, current_bucket);
-}
-
 osg::Node*
 FGTileMgr::loadTileModel(const string& modelPath, bool cacheModel)
 {
@@ -322,16 +307,17 @@ void FGTileMgr::update_queues()
 // given the current lon/lat (in degrees), fill in the array of local
 // chunks.  If the chunk isn't already in the cache, then read it from
 // disk.
-int FGTileMgr::update( double visibility_meters )
+void FGTileMgr::update(double)
 {
+    SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update()" );
     SGVec3d viewPos = globals->get_current_view()->get_view_pos();
-    return update(SGGeod::fromCart(viewPos), visibility_meters);
+    prep_ssg_nodes();
+    double vis = _visibilityMeters->getDoubleValue();
+    schedule_tiles_at(SGGeod::fromCart(viewPos), vis);
 }
 
-int FGTileMgr::update( const SGGeod& location, double visibility_meters)
+int FGTileMgr::schedule_tiles_at(const SGGeod& location, double rangeM)
 {
-    SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update()" );
-
     longitude = location.getLongitudeDeg();
     latitude = location.getLatitudeDeg();
 
@@ -351,16 +337,16 @@ int FGTileMgr::update( const SGGeod& location, double visibility_meters)
             // We've moved to a new bucket, we need to schedule any
             // needed tiles for loading.
             SG_LOG( SG_TERRAIN, SG_INFO, "FGTileMgr::update()" );
-            schedule_needed(visibility_meters, current_bucket);
+            schedule_needed(current_bucket, rangeM);
         }
     } else if ( state == Start || state == Inited ) {
         SG_LOG( SG_TERRAIN, SG_INFO, "State == Start || Inited" );
-//        initialize_queue();
+
         state = Running;
         if (current_bucket != previous_bucket
             && current_bucket.get_chunk_lon() != -1000) {
                SG_LOG( SG_TERRAIN, SG_INFO, "FGTileMgr::update()" );
-               schedule_needed(visibility_meters, current_bucket);
+               schedule_needed(current_bucket, rangeM);
         }
     }
 
@@ -372,11 +358,12 @@ int FGTileMgr::update( const SGGeod& location, double visibility_meters)
     return 1;
 }
 
-void FGTileMgr::prep_ssg_nodes(float vis) {
+void FGTileMgr::prep_ssg_nodes() {
 
     // traverse the potentially viewable tile list and update range
     // selector and transform
 
+    double vis = _visibilityMeters->getDoubleValue();
     TileEntry *e;
     tile_cache.reset_traversal();
 
index 6b415e53b6e8a94401ea83e2a8bb4860b009afd3..13588342bb5604b147d0f42a2ea6d82b6656b358 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <simgear/compiler.h>
 
+#include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/bucket/newbucket.hxx>
 #include <simgear/scene/tgdb/TileEntry.hxx>
 #include <simgear/scene/tgdb/TileCache.hxx>
@@ -37,7 +38,7 @@ namespace osg
 class Node;
 }
 
-class FGTileMgr : public simgear::ModelLoadHelper {
+class FGTileMgr : public SGSubsystem, public simgear::ModelLoadHelper {
 
 private:
 
@@ -49,15 +50,12 @@ private:
     };
 
     load_state state;
-
-    // initialize the cache
-    void initialize_queue();
-
+    
     // schedule a tile for loading
     void sched_tile( const SGBucket& b, const bool is_inner_ring );
 
     // schedule a needed buckets for loading
-    void schedule_needed(double visibility_meters, const SGBucket& curr_bucket);
+    void schedule_needed(const SGBucket& curr_bucket, double rangeM);
 
     SGBucket previous_bucket;
     SGBucket current_bucket;
@@ -77,29 +75,31 @@ private:
      */
     simgear::TileCache tile_cache;
 
+    // Update the various queues maintained by the tilemagr (private
+    // internal function, do not call directly.)
+    void update_queues();
+    
+    // Prepare the ssg nodes corresponding to each tile.  For each
+    // tile, set the ssg transform and update it's range selector
+    // based on current visibilty void prep_ssg_nodes( float
+    // visibility_meters );
+    void prep_ssg_nodes();
+    
+    SGPropertyNode* _visibilityMeters;
+    
 public:
     FGTileMgr();
 
     ~FGTileMgr();
 
     // Initialize the Tile Manager
-    int init();
+    virtual void init();
+    virtual void reinit();
 
-    // Update the various queues maintained by the tilemagr (private
-    // internal function, do not call directly.)
-    void update_queues();
+    virtual void update(double dt);
 
-    // given the current lon/lat (in degrees), fill in the array of
-    // local chunks.  If the chunk isn't already in the cache, then
-    // read it from disk.
-    int update( double visibility_meters );
-    int update( const SGGeod& location, double visibility_meters);
+    int schedule_tiles_at(const SGGeod& location, double rangeM);
 
-    // Prepare the ssg nodes corresponding to each tile.  For each
-    // tile, set the ssg transform and update it's range selector
-    // based on current visibilty void prep_ssg_nodes( float
-    // visibility_meters );
-    void prep_ssg_nodes(float visibility_meters );
 
     const SGBucket& get_current_bucket () const { return current_bucket; }