@@ -45,6 +45,13 @@ class ignition::gazebo::EntityComponentManagerPrivate
45
45
public: void InsertEntityRecursive (Entity _entity,
46
46
std::unordered_set<Entity> &_set);
47
47
48
+ // / \brief Recursively erase an entity and all its descendants from a given
49
+ // / set.
50
+ // / \param[in] _entity Entity to be erased.
51
+ // / \param[in, out] _set Set to erase from.
52
+ public: void EraseEntityRecursive (Entity _entity,
53
+ std::unordered_set<Entity> &_set);
54
+
48
55
// / \brief Register a new component type.
49
56
// / \param[in] _typeId Type if of the new component.
50
57
// / \return True if created successfully.
@@ -156,6 +163,9 @@ class ignition::gazebo::EntityComponentManagerPrivate
156
163
// / which belongs the component, and the value is the component being
157
164
// / removed.
158
165
std::unordered_multimap<Entity, ComponentKey> removedComponents;
166
+
167
+ // / \brief Set of entities that are prevented from removal.
168
+ public: std::unordered_set<Entity> pinnedEntities;
159
169
};
160
170
161
171
// ////////////////////////////////////////////////
@@ -236,6 +246,17 @@ void EntityComponentManagerPrivate::InsertEntityRecursive(Entity _entity,
236
246
_set.insert (_entity);
237
247
}
238
248
249
+ // ///////////////////////////////////////////////
250
+ void EntityComponentManagerPrivate::EraseEntityRecursive (Entity _entity,
251
+ std::unordered_set<Entity> &_set)
252
+ {
253
+ for (const auto &vertex : this ->entities .AdjacentsFrom (_entity))
254
+ {
255
+ this ->EraseEntityRecursive (vertex.first , _set);
256
+ }
257
+ _set.erase (_entity);
258
+ }
259
+
239
260
// ///////////////////////////////////////////////
240
261
void EntityComponentManager::RequestRemoveEntity (Entity _entity,
241
262
bool _recursive)
@@ -252,6 +273,23 @@ void EntityComponentManager::RequestRemoveEntity(Entity _entity,
252
273
this ->dataPtr ->InsertEntityRecursive (_entity, tmpToRemoveEntities);
253
274
}
254
275
276
+ // Remove entities from tmpToRemoveEntities that are marked as
277
+ // unremovable.
278
+ for (auto iter = tmpToRemoveEntities.begin ();
279
+ iter != tmpToRemoveEntities.end ();)
280
+ {
281
+ if (std::find (this ->dataPtr ->pinnedEntities .begin (),
282
+ this ->dataPtr ->pinnedEntities .end (), *iter) !=
283
+ this ->dataPtr ->pinnedEntities .end ())
284
+ {
285
+ iter = tmpToRemoveEntities.erase (iter);
286
+ }
287
+ else
288
+ {
289
+ ++iter;
290
+ }
291
+ }
292
+
255
293
{
256
294
std::lock_guard<std::mutex> lock (this ->dataPtr ->entityRemoveMutex );
257
295
this ->dataPtr ->toRemoveEntities .insert (tmpToRemoveEntities.begin (),
@@ -267,11 +305,41 @@ void EntityComponentManager::RequestRemoveEntity(Entity _entity,
267
305
// ///////////////////////////////////////////////
268
306
void EntityComponentManager::RequestRemoveEntities ()
269
307
{
308
+ if (this ->dataPtr ->pinnedEntities .empty ())
270
309
{
271
- std::lock_guard<std::mutex> lock (this ->dataPtr ->entityRemoveMutex );
272
- this ->dataPtr ->removeAllEntities = true ;
310
+ {
311
+ std::lock_guard<std::mutex> lock (this ->dataPtr ->entityRemoveMutex );
312
+ this ->dataPtr ->removeAllEntities = true ;
313
+ }
314
+ this ->RebuildViews ();
315
+ }
316
+ else
317
+ {
318
+ std::unordered_set<Entity> tmpToRemoveEntities;
319
+
320
+ // Store the to-be-removed entities in a temporary set so we can call
321
+ // UpdateViews on each of them
322
+ for (const auto &vertex : this ->dataPtr ->entities .Vertices ())
323
+ {
324
+ if (std::find (this ->dataPtr ->pinnedEntities .begin (),
325
+ this ->dataPtr ->pinnedEntities .end (), vertex.first ) ==
326
+ this ->dataPtr ->pinnedEntities .end ())
327
+ {
328
+ tmpToRemoveEntities.insert (vertex.first );
329
+ }
330
+ }
331
+
332
+ {
333
+ std::lock_guard<std::mutex> lock (this ->dataPtr ->entityRemoveMutex );
334
+ this ->dataPtr ->toRemoveEntities .insert (tmpToRemoveEntities.begin (),
335
+ tmpToRemoveEntities.end ());
336
+ }
337
+
338
+ for (const auto &removedEntity : tmpToRemoveEntities)
339
+ {
340
+ this ->UpdateViews (removedEntity);
341
+ }
273
342
}
274
- this ->RebuildViews ();
275
343
}
276
344
277
345
// ///////////////////////////////////////////////
@@ -1514,3 +1582,37 @@ void EntityComponentManagerPrivate::AddModifiedComponent(const Entity &_entity)
1514
1582
1515
1583
this ->modifiedComponents .insert (_entity);
1516
1584
}
1585
+
1586
+ // ///////////////////////////////////////////////
1587
+ void EntityComponentManager::PinEntity (const Entity _entity, bool _recursive)
1588
+ {
1589
+ if (_recursive)
1590
+ {
1591
+ this ->dataPtr ->InsertEntityRecursive (_entity,
1592
+ this ->dataPtr ->pinnedEntities );
1593
+ }
1594
+ else
1595
+ {
1596
+ this ->dataPtr ->pinnedEntities .insert (_entity);
1597
+ }
1598
+ }
1599
+
1600
+ // ///////////////////////////////////////////////
1601
+ void EntityComponentManager::UnpinEntity (const Entity _entity, bool _recursive)
1602
+ {
1603
+ if (_recursive)
1604
+ {
1605
+ this ->dataPtr ->EraseEntityRecursive (_entity,
1606
+ this ->dataPtr ->pinnedEntities );
1607
+ }
1608
+ else
1609
+ {
1610
+ this ->dataPtr ->pinnedEntities .erase (_entity);
1611
+ }
1612
+ }
1613
+
1614
+ // ///////////////////////////////////////////////
1615
+ void EntityComponentManager::UnpinAllEntities ()
1616
+ {
1617
+ this ->dataPtr ->pinnedEntities .clear ();
1618
+ }
0 commit comments