From: James Turner Date: Tue, 5 Nov 2013 05:17:22 +0000 (+0000) Subject: Reset: use ref-counting to own subsystems. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=3e9ed08c53ef4ef465455a98309e26ddbecf686d;p=simgear.git 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. --- diff --git a/simgear/structure/subsystem_mgr.cxx b/simgear/structure/subsystem_mgr.cxx index 5ce69831..05a07205 100644 --- a/simgear/structure/subsystem_mgr.cxx +++ b/simgear/structure/subsystem_mgr.cxx @@ -136,7 +136,7 @@ public: SampleStatistic timeStat; std::string name; - SGSubsystem * subsystem; + SGSharedPtr 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; } diff --git a/simgear/structure/subsystem_mgr.hxx b/simgear/structure/subsystem_mgr.hxx index 1919db4b..4fd935f1 100644 --- a/simgear/structure/subsystem_mgr.hxx +++ b/simgear/structure/subsystem_mgr.hxx @@ -284,7 +284,8 @@ protected: static void* reportTimingUserData; }; - +typedef SGSharedPtr SGSubsystemRef; + /** * A group of FlightGear subsystems. @@ -332,7 +333,8 @@ private: class Member; Member* get_member (const std::string &name, bool create = false); - std::vector _members; + typedef std::vector 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 SubsystemDict; SubsystemDict _subsystem_map; };