]> git.mxchange.org Git - simgear.git/commitdiff
Reset: use ref-counting to own subsystems.
authorJames Turner <zakalawe@mac.com>
Tue, 5 Nov 2013 05:17:22 +0000 (05:17 +0000)
committerJames Turner <zakalawe@mac.com>
Tue, 12 Nov 2013 23:12:45 +0000 (23:12 +0000)
Change the subsystem-group and manager code to use shared-ptr references
to subsystems, instead of holding a raw pointer. Hence the manager becomes
the owning ref to most subsystems.

simgear/structure/subsystem_mgr.cxx
simgear/structure/subsystem_mgr.hxx

index 5ce6983115e834430cdf5fc38d88b70e401f8d66..05a072059b6d6c686c3dd00f837949415262edcd 100644 (file)
@@ -136,7 +136,7 @@ public:
 
     SampleStatistic timeStat;
     std::string name;
-    SGSubsystem * subsystem;
+    SGSharedPtr<SGSubsystem> subsystem;
     double min_step_sec;
     double elapsed_sec;
     bool collectTimeStats;
@@ -321,12 +321,16 @@ SGSubsystemGroup::get_subsystem (const string &name)
 void
 SGSubsystemGroup::remove_subsystem (const string &name)
 {
-    for( size_t i = 0; i < _members.size(); i++ ) {
-        if (name == _members[i]->name) {
-            _members.erase(_members.begin() + i);
+    MemberVec::iterator it = _members.begin();
+    for (; it != _members.end(); ++it) {
+        if (name == (*it)->name) {
+            delete *it;
+            _members.erase(it);
             return;
         }
     }
+    
+    SG_LOG(SG_GENERAL, SG_WARN, "remove_subsystem: missing:" << name);
 }
 
 void
@@ -380,7 +384,6 @@ SGSubsystemGroup::Member::Member (const Member &)
 
 SGSubsystemGroup::Member::~Member ()
 {
-    delete subsystem;
 }
 
 void
@@ -532,31 +535,28 @@ SGSubsystemMgr::add (const char * name, SGSubsystem * subsystem,
 
     if (_subsystem_map.find(name) != _subsystem_map.end()) {
         SG_LOG(SG_GENERAL, SG_ALERT, "Adding duplicate subsystem " << name);
-        throw sg_exception("duplicate subsystem");
+        throw sg_exception("duplicate subsystem:" + std::string(name));
     }
     _subsystem_map[name] = subsystem;
 }
 
-SGSubsystem* 
+void
 SGSubsystemMgr::remove(const char* name)
 {
   SubsystemDict::iterator s =_subsystem_map.find(name);
   if (s == _subsystem_map.end()) {
-    return NULL;
+    return;
   }
   
-  SGSubsystem* sub = s->second;
   _subsystem_map.erase(s);
   
 // tedious part - we don't know which group the subsystem belongs too
   for (int i = 0; i < MAX_GROUPS; i++) {
-    if (_groups[i]->get_subsystem(name) == sub) {
+    if (_groups[i]->get_subsystem(name) != NULL) {
       _groups[i]->remove_subsystem(name);
       break;
     }
   } // of groups iteration
-  
-  return sub;
 }
 
 
index 1919db4b458d1a116a88a4bd2b8b37e9315ac86b..4fd935f1aec8778f78d5ba14836802e2f0cfa0f6 100644 (file)
@@ -284,7 +284,8 @@ protected:
   static void* reportTimingUserData;
 };
 
-
+typedef SGSharedPtr<SGSubsystem> SGSubsystemRef;
+    
 \f
 /**
  * A group of FlightGear subsystems.
@@ -332,7 +333,8 @@ private:
     class Member;
     Member* get_member (const std::string &name, bool create = false);
 
-    std::vector<Member *> _members;
+    typedef std::vector<Member *> MemberVec;
+    MemberVec _members;
     
     double _fixedUpdateTime;
     double _updateTimeRemainder;
@@ -401,11 +403,11 @@ public:
      * remove a subsystem, and return a pointer to it.
      * returns NULL if the subsystem was not found.
      */
-    virtual SGSubsystem* remove(const char* name);
+    virtual void remove(const char* name);
 
     virtual SGSubsystemGroup * get_group (GroupType group);
 
-    virtual SGSubsystem * get_subsystem(const std::string &name) const;
+    virtual SGSubsystem* get_subsystem(const std::string &name) const;
 
     void reportTiming();
     void setReportTimingCb(void* userData,SGSubsystemTimingCb cb) {reportTimingCb = cb;reportTimingUserData = userData;}
@@ -414,6 +416,7 @@ private:
     SGSubsystemGroup* _groups[MAX_GROUPS];
     unsigned int _initPosition;
   
+    // non-owning reference
     typedef std::map<std::string, SGSubsystem*> SubsystemDict;
     SubsystemDict _subsystem_map;
 };