@@ -138,8 +138,15 @@ class ignition::gazebo::EntityComponentManagerPrivate
138
138
public: mutable std::mutex removedComponentsMutex;
139
139
140
140
// / \brief The set of all views.
141
+ // / The value is a pair of the view itself and a mutex that can be used for
142
+ // / locking the view to ensure thread safety when adding entities to the view.
141
143
public: mutable std::unordered_map<detail::ComponentTypeKey,
142
- std::unique_ptr<detail::BaseView>, detail::ComponentTypeHasher> views;
144
+ std::pair<std::unique_ptr<detail::BaseView>,
145
+ std::unique_ptr<std::mutex>>, detail::ComponentTypeHasher> views;
146
+
147
+ // / \brief A flag that indicates whether views should be locked while adding
148
+ // / new entities to them or not.
149
+ public: bool lockAddEntitiesToViews{false };
143
150
144
151
// / \brief Cache of previously queried descendants. The key is the parent
145
152
// / entity for which descendants were queried, and the value are all its
@@ -417,7 +424,7 @@ void EntityComponentManager::ClearNewlyCreatedEntities()
417
424
418
425
for (auto &view : this ->dataPtr ->views )
419
426
{
420
- view.second ->ResetNewEntityState ();
427
+ view.second . first ->ResetNewEntityState ();
421
428
}
422
429
}
423
430
@@ -465,7 +472,7 @@ void EntityComponentManager::RequestRemoveEntity(Entity _entity,
465
472
{
466
473
for (auto &view : this ->dataPtr ->views )
467
474
{
468
- view.second ->MarkEntityToRemove (removedEntity);
475
+ view.second . first ->MarkEntityToRemove (removedEntity);
469
476
}
470
477
}
471
478
}
@@ -523,7 +530,7 @@ void EntityComponentManager::ProcessRemoveEntityRequests()
523
530
// Remove the entity from views.
524
531
for (auto &view : this ->dataPtr ->views )
525
532
{
526
- view.second ->RemoveEntity (entity);
533
+ view.second . first ->RemoveEntity (entity);
527
534
}
528
535
}
529
536
// Clear the set of entities to remove.
@@ -566,7 +573,7 @@ bool EntityComponentManager::RemoveComponent(
566
573
567
574
// update views to reflect the component removal
568
575
for (auto &viewPair : this ->dataPtr ->views )
569
- viewPair.second ->NotifyComponentRemoval (_entity, _typeId);
576
+ viewPair.second . first ->NotifyComponentRemoval (_entity, _typeId);
570
577
}
571
578
572
579
this ->dataPtr ->AddModifiedComponent (_entity);
@@ -802,7 +809,7 @@ bool EntityComponentManager::CreateComponentImplementation(
802
809
updateData = false ;
803
810
for (auto &viewPair : this ->dataPtr ->views )
804
811
{
805
- auto &view = viewPair.second ;
812
+ auto &view = viewPair.second . first ;
806
813
if (this ->EntityMatches (_entity, view->ComponentTypes ()))
807
814
view->MarkEntityToAdd (_entity, this ->IsNewEntity (_entity));
808
815
}
@@ -833,7 +840,7 @@ bool EntityComponentManager::CreateComponentImplementation(
833
840
834
841
for (auto &viewPair : this ->dataPtr ->views )
835
842
{
836
- viewPair.second ->NotifyComponentAddition (_entity,
843
+ viewPair.second . first ->NotifyComponentAddition (_entity,
837
844
this ->IsNewEntity (_entity), _componentTypeId);
838
845
}
839
846
}
@@ -941,14 +948,18 @@ const EntityGraph &EntityComponentManager::Entities() const
941
948
}
942
949
943
950
// ////////////////////////////////////////////////
944
- detail::BaseView *EntityComponentManager::FindView (
951
+ std::pair< detail::BaseView *, std::mutex *> EntityComponentManager::FindView (
945
952
const std::vector<ComponentTypeId> &_types) const
946
953
{
947
954
std::lock_guard<std::mutex> lockViews (this ->dataPtr ->viewsMutex );
955
+ std::pair<detail::BaseView *, std::mutex *> viewMutexPair (nullptr , nullptr );
948
956
auto iter = this ->dataPtr ->views .find (_types);
949
957
if (iter != this ->dataPtr ->views .end ())
950
- return iter->second .get ();
951
- return nullptr ;
958
+ {
959
+ viewMutexPair.first = iter->second .first .get ();
960
+ viewMutexPair.second = iter->second .second .get ();
961
+ }
962
+ return viewMutexPair;
952
963
}
953
964
954
965
// ////////////////////////////////////////////////
@@ -959,9 +970,10 @@ detail::BaseView *EntityComponentManager::AddView(
959
970
// If the view already exists, then the map will return the iterator to
960
971
// the location that prevented the insertion.
961
972
std::lock_guard<std::mutex> lockViews (this ->dataPtr ->viewsMutex );
962
- auto iter = this ->dataPtr ->views .insert (
963
- std::make_pair (_types, std::move (_view))).first ;
964
- return iter->second .get ();
973
+ auto iter = this ->dataPtr ->views .insert (std::make_pair (_types,
974
+ std::make_pair (std::move (_view),
975
+ std::make_unique<std::mutex>()))).first ;
976
+ return iter->second .first .get ();
965
977
}
966
978
967
979
// ////////////////////////////////////////////////
@@ -970,7 +982,7 @@ void EntityComponentManager::RebuildViews()
970
982
IGN_PROFILE (" EntityComponentManager::RebuildViews" );
971
983
for (auto &viewPair : this ->dataPtr ->views )
972
984
{
973
- auto &view = viewPair.second ;
985
+ auto &view = viewPair.second . first ;
974
986
view->Reset ();
975
987
976
988
// Add all the entities that match the component types to the
@@ -1700,6 +1712,18 @@ void EntityComponentManager::SetEntityCreateOffset(uint64_t _offset)
1700
1712
this ->dataPtr ->entityCount = _offset;
1701
1713
}
1702
1714
1715
+ // ///////////////////////////////////////////////
1716
+ void EntityComponentManager::LockAddingEntitiesToViews (bool _lock)
1717
+ {
1718
+ this ->dataPtr ->lockAddEntitiesToViews = _lock;
1719
+ }
1720
+
1721
+ // ///////////////////////////////////////////////
1722
+ bool EntityComponentManager::LockAddingEntitiesToViews () const
1723
+ {
1724
+ return this ->dataPtr ->lockAddEntitiesToViews ;
1725
+ }
1726
+
1703
1727
// ///////////////////////////////////////////////
1704
1728
void EntityComponentManagerPrivate::AddModifiedComponent (const Entity &_entity)
1705
1729
{
0 commit comments