Reset: use ref-counting to own subsystems.

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.
This commit is contained in:
James Turner 2013-11-05 05:17:22 +00:00
parent b7df9026c0
commit 3e9ed08c53
2 changed files with 19 additions and 16 deletions

View File

@ -136,7 +136,7 @@ public:
SampleStatistic timeStat; SampleStatistic timeStat;
std::string name; std::string name;
SGSubsystem * subsystem; SGSharedPtr<SGSubsystem> subsystem;
double min_step_sec; double min_step_sec;
double elapsed_sec; double elapsed_sec;
bool collectTimeStats; bool collectTimeStats;
@ -321,12 +321,16 @@ SGSubsystemGroup::get_subsystem (const string &name)
void void
SGSubsystemGroup::remove_subsystem (const string &name) SGSubsystemGroup::remove_subsystem (const string &name)
{ {
for( size_t i = 0; i < _members.size(); i++ ) { MemberVec::iterator it = _members.begin();
if (name == _members[i]->name) { for (; it != _members.end(); ++it) {
_members.erase(_members.begin() + i); if (name == (*it)->name) {
delete *it;
_members.erase(it);
return; return;
} }
} }
SG_LOG(SG_GENERAL, SG_WARN, "remove_subsystem: missing:" << name);
} }
void void
@ -380,7 +384,6 @@ SGSubsystemGroup::Member::Member (const Member &)
SGSubsystemGroup::Member::~Member () SGSubsystemGroup::Member::~Member ()
{ {
delete subsystem;
} }
void void
@ -532,31 +535,28 @@ SGSubsystemMgr::add (const char * name, SGSubsystem * subsystem,
if (_subsystem_map.find(name) != _subsystem_map.end()) { if (_subsystem_map.find(name) != _subsystem_map.end()) {
SG_LOG(SG_GENERAL, SG_ALERT, "Adding duplicate subsystem " << name); 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; _subsystem_map[name] = subsystem;
} }
SGSubsystem* void
SGSubsystemMgr::remove(const char* name) SGSubsystemMgr::remove(const char* name)
{ {
SubsystemDict::iterator s =_subsystem_map.find(name); SubsystemDict::iterator s =_subsystem_map.find(name);
if (s == _subsystem_map.end()) { if (s == _subsystem_map.end()) {
return NULL; return;
} }
SGSubsystem* sub = s->second;
_subsystem_map.erase(s); _subsystem_map.erase(s);
// tedious part - we don't know which group the subsystem belongs too // tedious part - we don't know which group the subsystem belongs too
for (int i = 0; i < MAX_GROUPS; i++) { 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); _groups[i]->remove_subsystem(name);
break; break;
} }
} // of groups iteration } // of groups iteration
return sub;
} }

View File

@ -284,7 +284,8 @@ protected:
static void* reportTimingUserData; static void* reportTimingUserData;
}; };
typedef SGSharedPtr<SGSubsystem> SGSubsystemRef;
/** /**
* A group of FlightGear subsystems. * A group of FlightGear subsystems.
@ -332,7 +333,8 @@ private:
class Member; class Member;
Member* get_member (const std::string &name, bool create = false); Member* get_member (const std::string &name, bool create = false);
std::vector<Member *> _members; typedef std::vector<Member *> MemberVec;
MemberVec _members;
double _fixedUpdateTime; double _fixedUpdateTime;
double _updateTimeRemainder; double _updateTimeRemainder;
@ -401,11 +403,11 @@ public:
* remove a subsystem, and return a pointer to it. * remove a subsystem, and return a pointer to it.
* returns NULL if the subsystem was not found. * 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 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 reportTiming();
void setReportTimingCb(void* userData,SGSubsystemTimingCb cb) {reportTimingCb = cb;reportTimingUserData = userData;} void setReportTimingCb(void* userData,SGSubsystemTimingCb cb) {reportTimingCb = cb;reportTimingUserData = userData;}
@ -414,6 +416,7 @@ private:
SGSubsystemGroup* _groups[MAX_GROUPS]; SGSubsystemGroup* _groups[MAX_GROUPS];
unsigned int _initPosition; unsigned int _initPosition;
// non-owning reference
typedef std::map<std::string, SGSubsystem*> SubsystemDict; typedef std::map<std::string, SGSubsystem*> SubsystemDict;
SubsystemDict _subsystem_map; SubsystemDict _subsystem_map;
}; };