Skip to content

Commit

Permalink
[Entity] Fixed threading related crash
Browse files Browse the repository at this point in the history
  • Loading branch information
PanosK92 committed Nov 29, 2023
1 parent f7665f5 commit cf7e828
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 40 deletions.
1 change: 1 addition & 0 deletions editor/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ Editor::Editor()
{
// initialize the engine
Spartan::Engine::Initialize();

// initialize ImGui
ImGui::CreateContext();

Expand Down
47 changes: 13 additions & 34 deletions runtime/World/Entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,13 +540,13 @@ namespace Spartan
// remove this child from it's previous parent
if (m_parent)
{
m_parent->RemoveChild_Internal(this);
m_parent->RemoveChild(this);
}

// add this child to the new parent
if (new_parent)
{
new_parent->AddChild_Internal(this);
new_parent->AddChild(this);
new_parent->UpdateTransform();
}

Expand All @@ -564,7 +564,13 @@ namespace Spartan
if (child->GetObjectId() == GetObjectId())
return;

child->SetParent(this);
lock_guard lock(m_child_mutex);

// if this is not already a child, add it
if (!(find(m_children.begin(), m_children.end(), child) != m_children.end()))
{
m_children.emplace_back(child);
}
}

void Entity::RemoveChild(Entity* child)
Expand All @@ -575,6 +581,8 @@ namespace Spartan
if (child->GetObjectId() == GetObjectId())
return;

lock_guard lock(m_child_mutex);

// remove the child
m_children.erase(remove_if(m_children.begin(), m_children.end(), [child](Entity* vec_transform) { return vec_transform->GetObjectId() == child->GetObjectId(); }), m_children.end());

Expand All @@ -601,43 +609,14 @@ namespace Spartan
m_parent = new_parent;
}

void Entity::AddChild_Internal(Entity* child)
{
SP_ASSERT(child != nullptr);

// ensure that the child is not this transform
if (child->GetObjectId() == GetObjectId())
return;

lock_guard lock(m_child_add_remove_mutex);

// if this is not already a child, add it
if (!(find(m_children.begin(), m_children.end(), child) != m_children.end()))
{
m_children.emplace_back(child);
}
}

void Entity::RemoveChild_Internal(Entity* child)
{
SP_ASSERT(child != nullptr);

// ensure the transform is not itself
if (child->GetObjectId() == GetObjectId())
return;

lock_guard lock(m_child_add_remove_mutex);

// remove the child
m_children.erase(remove_if(m_children.begin(), m_children.end(), [child](Entity* vec_transform) { return vec_transform->GetObjectId() == child->GetObjectId(); }), m_children.end());
}

// searches the entire hierarchy, finds any children and saves them in m_children
// this is a recursive function, the children will also find their own children and so on
void Entity::AcquireChildren()
{
m_child_mutex.lock();
m_children.clear();
m_children.shrink_to_fit();
m_child_mutex.unlock();

auto entities = World::GetAllEntities();
for (const auto& entity : entities)
Expand Down
7 changes: 1 addition & 6 deletions runtime/World/Entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,7 @@ namespace Spartan
bool m_hierarchy_visibility = true;
std::array<std::shared_ptr<Component>, 13> m_components;

// internal functions don't propagate changes throughout the hierarchy
// They just make enough changes so that the hierarchy can be resolved later (in one go)
void SetParent_Internal(Entity* parent);
void AddChild_Internal(Entity* child);
void RemoveChild_Internal(Entity* child);

void UpdateTransform();
Math::Matrix GetParentTransformMatrix() const;

Expand All @@ -200,6 +195,6 @@ namespace Spartan
// misc
bool m_position_changed_this_frame = false;
bool m_rotation_changed_this_frame = false;
std::mutex m_child_add_remove_mutex;
std::mutex m_child_mutex;
};
}

0 comments on commit cf7e828

Please sign in to comment.