Skip to content

Commit

Permalink
Add a convenience function for getting possibly non-existing componen…
Browse files Browse the repository at this point in the history
…ts. (#629)

Signed-off-by: Martin Pecka <[email protected]>
  • Loading branch information
peci1 authored and chapulina committed Jul 23, 2021
1 parent 6f901af commit 7b5b61d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
13 changes: 13 additions & 0 deletions include/ignition/gazebo/EntityComponentManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,19 @@ namespace ignition
public: template<typename ComponentTypeT>
ComponentTypeT *Component(const ComponentKey &_key);

/// \brief Get a mutable component assigned to an entity based on a
/// component type. If the component doesn't exist, create it and
/// initialize with the given default value.
/// \param[in] _entity The entity.
/// \param[in] _default The value that should be used to construct
/// the component in case the component doesn't exist.
/// \return The component of the specified type assigned to the specified
/// entity.
public: template<typename ComponentTypeT>
ComponentTypeT *ComponentDefault(Entity _entity,
const typename ComponentTypeT::Type &_default =
typename ComponentTypeT::Type());

/// \brief Get the data from a component.
/// * If the component type doesn't hold any data, this won't compile.
/// * If the entity doesn't have that component, it will return nullopt.
Expand Down
14 changes: 14 additions & 0 deletions include/ignition/gazebo/detail/EntityComponentManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,20 @@ ComponentTypeT *EntityComponentManager::Component(const ComponentKey &_key)
this->ComponentImplementation(_key));
}

//////////////////////////////////////////////////
template<typename ComponentTypeT>
ComponentTypeT *EntityComponentManager::ComponentDefault(Entity _entity,
const typename ComponentTypeT::Type &_default)
{
auto comp = this->Component<ComponentTypeT>(_entity);
if (!comp)
{
this->CreateComponent(_entity, ComponentTypeT(_default));
comp = this->Component<ComponentTypeT>(_entity);
}
return comp;
}

//////////////////////////////////////////////////
template<typename ComponentTypeT>
std::optional<typename ComponentTypeT::Type>
Expand Down
25 changes: 25 additions & 0 deletions src/EntityComponentManager_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,31 @@ TEST_P(EntityComponentManagerFixture, EntitiesAndComponents)
EXPECT_FALSE(manager.EntityHasComponentType(kNullEntity,
IntComponent::typeId));

// Query non-existing component, the default value is default-constructed
BoolComponent *boolComp = manager.ComponentDefault<BoolComponent>(entity);
ASSERT_NE(nullptr, boolComp);
EXPECT_TRUE(manager.HasComponentType(BoolComponent::typeId));
EXPECT_TRUE(manager.EntityHasComponentType(entity, BoolComponent::typeId));
EXPECT_EQ(false, boolComp->Data());

// Query non-existing component, the default value is used
DoubleComponent *doubleComp =
manager.ComponentDefault<DoubleComponent>(entity, 1.0);
ASSERT_NE(nullptr, doubleComp);
EXPECT_TRUE(manager.HasComponentType(DoubleComponent::typeId));
EXPECT_TRUE(manager.EntityHasComponentType(entity, IntComponent::typeId));
EXPECT_TRUE(manager.EntityHasComponentType(entity, DoubleComponent::typeId));
EXPECT_FALSE(
manager.EntityHasComponentType(entity2, DoubleComponent::typeId));
EXPECT_FLOAT_EQ(1.0, doubleComp->Data());

// Query existing component, the default value is not used
IntComponent *intComp = manager.ComponentDefault<IntComponent>(entity, 124);
ASSERT_NE(nullptr, intComp);
EXPECT_TRUE(manager.HasComponentType(IntComponent::typeId));
EXPECT_TRUE(manager.EntityHasComponentType(entity, IntComponent::typeId));
EXPECT_EQ(123, intComp->Data());

// Remove all entities
manager.RequestRemoveEntities();
EXPECT_EQ(3u, manager.EntityCount());
Expand Down

0 comments on commit 7b5b61d

Please sign in to comment.