Fix shared_ptr cycles in C++ carla::Client

carla::client::detail::Simulator had a strong reference from
carla::client::LightManager, which meant that deleting the client-facing
carla::Client did not actually delete the Simulator object, meaning that
it remained connected. Fix that.
This commit is contained in:
anrp 2022-10-03 11:43:20 -04:00 committed by bernat
parent 38b020910a
commit 4e949228d4
5 changed files with 43 additions and 31 deletions

View File

@ -16,65 +16,77 @@ namespace client {
using LightGroup = rpc::LightState::LightGroup; using LightGroup = rpc::LightState::LightGroup;
Color Light::GetColor() const { Color Light::GetColor() const {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
return _light_manager->GetColor(_id); assert(light_manager && "No light_manager");
return light_manager->GetColor(_id);
} }
float Light::GetIntensity() const { float Light::GetIntensity() const {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
return _light_manager->GetIntensity(_id); assert(light_manager && "No light_manager");
return light_manager->GetIntensity(_id);
} }
LightGroup Light::GetLightGroup() const { LightGroup Light::GetLightGroup() const {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
return _light_manager->GetLightGroup(_id); assert(light_manager && "No light_manager");
return light_manager->GetLightGroup(_id);
} }
LightState Light::GetLightState() const { LightState Light::GetLightState() const {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
return _light_manager->GetLightState(_id); assert(light_manager && "No light_manager");
return light_manager->GetLightState(_id);
} }
bool Light::IsOn() const { bool Light::IsOn() const {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
return _light_manager->IsActive(_id) == true; assert(light_manager && "No light_manager");
return light_manager->IsActive(_id) == true;
} }
bool Light::IsOff() const { bool Light::IsOff() const {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
return _light_manager->IsActive(_id) == false; assert(light_manager && "No light_manager");
return light_manager->IsActive(_id) == false;
} }
void Light::SetColor(Color color) { void Light::SetColor(Color color) {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
_light_manager->SetColor(_id, color); assert(light_manager && "No light_manager");
light_manager->SetColor(_id, color);
} }
void Light::SetIntensity(float intensity) { void Light::SetIntensity(float intensity) {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
_light_manager->SetIntensity(_id, intensity); assert(light_manager && "No light_manager");
light_manager->SetIntensity(_id, intensity);
} }
void Light::SetLightGroup(LightGroup group) { void Light::SetLightGroup(LightGroup group) {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
_light_manager->SetLightGroup(_id, group); assert(light_manager && "No light_manager");
light_manager->SetLightGroup(_id, group);
} }
void Light::SetLightState(const LightState& state) { void Light::SetLightState(const LightState& state) {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
_light_manager->SetLightState(_id, state); assert(light_manager && "No light_manager");
light_manager->SetLightState(_id, state);
} }
void Light::TurnOn() { void Light::TurnOn() {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
_light_manager->SetActive(_id, true); assert(light_manager && "No light_manager");
light_manager->SetActive(_id, true);
} }
void Light::TurnOff() { void Light::TurnOff() {
assert(_light_manager && "No light_manager"); auto light_manager = _light_manager.lock();
_light_manager->SetActive(_id, false); assert(light_manager && "No light_manager");
light_manager->SetActive(_id, false);
} }
} // namespace client } // namespace client
} // namespace carla } // namespace carla

View File

@ -62,14 +62,14 @@ private:
friend class LightManager; friend class LightManager;
Light(SharedPtr<LightManager> light_manager, Light(WeakPtr<LightManager> light_manager,
geom::Location location, geom::Location location,
LightId id) LightId id)
: _light_manager(light_manager), : _light_manager(light_manager),
_location (location), _location (location),
_id (id) {} _id (id) {}
SharedPtr<LightManager> _light_manager; WeakPtr<LightManager> _light_manager;
geom::Location _location; geom::Location _location;
LightId _id; LightId _id;

View File

@ -22,7 +22,7 @@ LightManager::~LightManager(){
UpdateServerLightsState(true); UpdateServerLightsState(true);
} }
void LightManager::SetEpisode(detail::EpisodeProxy episode) { void LightManager::SetEpisode(detail::WeakEpisodeProxy episode) {
_episode = episode; _episode = episode;

View File

@ -43,7 +43,7 @@ public:
_dirty = other._dirty; _dirty = other._dirty;
} }
void SetEpisode(detail::EpisodeProxy episode); void SetEpisode(detail::WeakEpisodeProxy episode);
std::vector<Light> GetAllLights(LightGroup type = LightGroup::None) const; std::vector<Light> GetAllLights(LightGroup type = LightGroup::None) const;
// TODO: std::vector<Light> GetAllLightsInRoad(RoadId id, LightGroup type = LightGroup::None); // TODO: std::vector<Light> GetAllLightsInRoad(RoadId id, LightGroup type = LightGroup::None);
@ -99,7 +99,7 @@ private:
std::unordered_map<LightId, LightState> _lights_changes; std::unordered_map<LightId, LightState> _lights_changes;
std::unordered_map<LightId, Light> _lights; std::unordered_map<LightId, Light> _lights;
detail::EpisodeProxy _episode; detail::WeakEpisodeProxy _episode;
std::mutex _mutex; std::mutex _mutex;

View File

@ -134,7 +134,7 @@ namespace detail {
if (!GetEpisodeSettings().synchronous_mode) { if (!GetEpisodeSettings().synchronous_mode) {
WaitForTick(_client.GetTimeout()); WaitForTick(_client.GetTimeout());
} }
_light_manager->SetEpisode(EpisodeProxy{shared_from_this()}); _light_manager->SetEpisode(WeakEpisodeProxy{shared_from_this()});
} }
return EpisodeProxy{shared_from_this()}; return EpisodeProxy{shared_from_this()};
} }