Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry-Pick #1317: Fix segfault at exit #1441

Merged
merged 1 commit into from
Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/ignition/gazebo/EntityComponentManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ namespace ignition
/// \tparam ComponentTypeTs All the component types that define a view.
/// \return A pointer to the view.
private: template<typename ...ComponentTypeTs>
detail::View<ComponentTypeTs...> *FindView() const;
detail::View *FindView() const;

/// \brief Find a view based on the provided component type ids.
/// \param[in] _types The component type ids that serve as a key into
Expand Down
3 changes: 1 addition & 2 deletions include/ignition/gazebo/detail/BaseView.hh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#define IGNITION_GAZEBO_DETAIL_BASEVIEW_HH_

#include <cstddef>
#include <memory>
#include <set>
#include <unordered_map>
#include <vector>
Expand Down Expand Up @@ -69,7 +68,7 @@ struct ComponentTypeHasher
class IGNITION_GAZEBO_VISIBLE BaseView
{
/// \brief Destructor
public: virtual ~BaseView() = default;
public: virtual ~BaseView();

/// \brief See if an entity is a part of the view
/// \param[in] _entity The entity
Expand Down
69 changes: 59 additions & 10 deletions include/ignition/gazebo/detail/EntityComponentManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,50 @@ void EntityComponentManager::EachNoCache(typename identity<std::function<
}
}

namespace detail
{
/// \brief Helper template to call a callback function with each of the
/// components in the _data vector expanded as arguments to the callback
/// function.
/// \tparam ComponentTypeTs The actual types of each of the components.
/// \tparam FuncT The type of the callback function.
/// \tparam BaseComponentT Either "BaseComponent" or "const BaseComponent"
/// \tparam Is Index sequence that will be used to iterate through the vector
/// _data.
/// \param[in] _f The callback function
/// \param[in] _entity The entity associated with the components.
/// \param[in] _data A vector of component pointers that will be expanded to
/// become the arguments of the callback function _f.
/// \return The value of return by the function _f.
template <typename... ComponentTypeTs, typename FuncT, typename BaseComponentT,
std::size_t... Is>
constexpr bool applyFunctionImpl(const FuncT &_f, const Entity &_entity,
const std::vector<BaseComponentT *> &_data,
std::index_sequence<Is...>)
{
return _f(_entity, static_cast<ComponentTypeTs *>(_data[Is])...);
}

/// \brief Helper template to call a callback function with each of the
/// components in the _data vector expanded as arguments to the callback
/// function.
/// \tparam ComponentTypeTs The actual types of each of the components.
/// \tparam FuncT The type of the callback function.
/// \tparam BaseComponentT Either "BaseComponent" or "const BaseComponent"
/// \param[in] _f The callback function
/// \param[in] _entity The entity associated with the components.
/// \param[in] _data A vector of component pointers that will be expanded to
/// become the arguments of the callback function _f.
/// \return The value of return by the function _f.
template <typename... ComponentTypeTs, typename FuncT, typename BaseComponentT>
constexpr bool applyFunction(const FuncT &_f, const Entity &_entity,
const std::vector<BaseComponentT *> &_data)
{
return applyFunctionImpl<ComponentTypeTs...>(
_f, _entity, _data, std::index_sequence_for<ComponentTypeTs...>{});
}
} // namespace detail

//////////////////////////////////////////////////
template<typename ...ComponentTypeTs>
void EntityComponentManager::Each(typename identity<std::function<
Expand All @@ -385,7 +429,8 @@ void EntityComponentManager::Each(typename identity<std::function<
// function.
for (const Entity entity : view->Entities())
{
if (!std::apply(_f, view->EntityComponentConstData(entity)))
const auto &data = view->EntityComponentData(entity);
if (!detail::applyFunction<const ComponentTypeTs...>(_f, entity, data))
{
break;
}
Expand All @@ -405,7 +450,8 @@ void EntityComponentManager::Each(typename identity<std::function<
// function.
for (const Entity entity : view->Entities())
{
if (!std::apply(_f, view->EntityComponentData(entity)))
const auto &data = view->EntityComponentData(entity);
if (!detail::applyFunction<ComponentTypeTs...>(_f, entity, data))
{
break;
}
Expand Down Expand Up @@ -434,7 +480,8 @@ void EntityComponentManager::EachNew(typename identity<std::function<
// function.
for (const Entity entity : view->NewEntities())
{
if (!std::apply(_f, view->EntityComponentData(entity)))
const auto &data = view->EntityComponentData(entity);
if (!detail::applyFunction<ComponentTypeTs...>(_f, entity, data))
{
break;
}
Expand All @@ -455,7 +502,8 @@ void EntityComponentManager::EachNew(typename identity<std::function<
// function.
for (const Entity entity : view->NewEntities())
{
if (!std::apply(_f, view->EntityComponentConstData(entity)))
const auto &data = view->EntityComponentData(entity);
if (!detail::applyFunction<const ComponentTypeTs...>(_f, entity, data))
{
break;
}
Expand All @@ -476,7 +524,8 @@ void EntityComponentManager::EachRemoved(typename identity<std::function<
// function.
for (const Entity entity : view->ToRemoveEntities())
{
if (!std::apply(_f, view->EntityComponentConstData(entity)))
const auto &data = view->EntityComponentData(entity);
if (!detail::applyFunction<const ComponentTypeTs...>(_f, entity, data))
{
break;
}
Expand All @@ -485,15 +534,15 @@ void EntityComponentManager::EachRemoved(typename identity<std::function<

//////////////////////////////////////////////////
template<typename ...ComponentTypeTs>
detail::View<ComponentTypeTs...> *EntityComponentManager::FindView() const
detail::View *EntityComponentManager::FindView() const
{
auto viewKey = std::vector<ComponentTypeId>{ComponentTypeTs::typeId...};

auto baseViewMutexPair = this->FindView(viewKey);
auto baseViewPtr = baseViewMutexPair.first;
if (nullptr != baseViewPtr)
{
auto view = static_cast<detail::View<ComponentTypeTs...>*>(baseViewPtr);
auto view = static_cast<detail::View*>(baseViewPtr);

std::unique_ptr<std::lock_guard<std::mutex>> viewLock;
if (this->LockAddingEntitiesToViews())
Expand Down Expand Up @@ -527,7 +576,7 @@ detail::View<ComponentTypeTs...> *EntityComponentManager::FindView() const
}

// create a new view if one wasn't found
detail::View<ComponentTypeTs...> view;
detail::View view(std::set<ComponentTypeId>{ComponentTypeTs::typeId...});

for (const auto &vertex : this->Entities().Vertices())
{
Expand All @@ -547,8 +596,8 @@ detail::View<ComponentTypeTs...> *EntityComponentManager::FindView() const
}

baseViewPtr = this->AddView(viewKey,
std::make_unique<detail::View<ComponentTypeTs...>>(view));
return static_cast<detail::View<ComponentTypeTs...>*>(baseViewPtr);
std::make_unique<detail::View>(std::move(view)));
return static_cast<detail::View *>(baseViewPtr);
}

//////////////////////////////////////////////////
Expand Down
Loading