Skip to content

Commit

Permalink
#5346: Fix a few crashes at shutdown, due to the worldspawn entity no…
Browse files Browse the repository at this point in the history
…t carrying a name spawnarg.

Worldspawn key/values are not observed anymore.
Ignore the map root node when it is inserted or removed.
  • Loading branch information
codereader committed Sep 29, 2020
1 parent fa320d0 commit 4627d4c
Showing 1 changed file with 24 additions and 6 deletions.
30 changes: 24 additions & 6 deletions plugins/dm.gameconnection/MapObserver.cpp
Expand Up @@ -12,7 +12,14 @@ class EntityNodeCollector : public scene::NodeVisitor
std::vector<IEntityNodePtr> foundEntities;

bool pre(const scene::INodePtr& node) override {
if (auto ptr = std::dynamic_pointer_cast<IEntityNode>(node)) {
if (auto ptr = std::dynamic_pointer_cast<IEntityNode>(node))
{
// Ignore worldspawn entities
if (ptr->getEntity().isWorldspawn())
{
return false;
}

foundEntities.push_back(ptr);
return false;
}
Expand All @@ -23,7 +30,10 @@ class EntityNodeCollector : public scene::NodeVisitor
static std::vector<IEntityNodePtr> getEntitiesInSubgraph(const scene::INodePtr& node)
{
EntityNodeCollector visitor;
node->traverse(visitor);
if (node)
{
node->traverse(visitor);
}
return visitor.foundEntities;
}

Expand Down Expand Up @@ -66,13 +76,19 @@ class MapObserver_SceneObserver : public scene::Graph::Observer {

public:
MapObserver_SceneObserver(MapObserver& owner) : _owner(owner) {}
virtual void onSceneNodeInsert(const scene::INodePtr& node) override {
virtual void onSceneNodeInsert(const scene::INodePtr& node) override
{
if (node->isRoot()) return; // ignore the map root

auto entityNodes = getEntitiesInSubgraph(node);
for (const IEntityNodePtr& entNode : entityNodes)
_owner.entityUpdated(entNode->name(), DiffStatus::added());
_owner.enableEntityObservers(entityNodes);
}
virtual void onSceneNodeErase(const scene::INodePtr& node) override {
virtual void onSceneNodeErase(const scene::INodePtr& node) override
{
if (node->isRoot()) return; // ignore the map root

auto entityNodes = getEntitiesInSubgraph(node);
_owner.disableEntityObservers(entityNodes);
for (const IEntityNodePtr& entNode : entityNodes)
Expand All @@ -82,7 +98,8 @@ class MapObserver_SceneObserver : public scene::Graph::Observer {

void MapObserver::enableEntityObservers(const std::vector<IEntityNodePtr>& entityNodes)
{
for (auto entNode : entityNodes) {
for (auto entNode : entityNodes)
{
if (_entityObservers.count(entNode.get()))
continue; //already tracked
auto* observer = new MapObserver_EntityObserver(*this);
Expand All @@ -94,7 +111,8 @@ void MapObserver::enableEntityObservers(const std::vector<IEntityNodePtr>& entit

void MapObserver::disableEntityObservers(const std::vector<IEntityNodePtr>& entityNodes)
{
for (auto entNode : entityNodes) {
for (auto entNode : entityNodes)
{
if (!_entityObservers.count(entNode.get()))
continue; //not tracked
Entity::Observer* observer = _entityObservers[entNode.get()];
Expand Down

0 comments on commit 4627d4c

Please sign in to comment.