Optimize Actor::DestroyChildren
This commit is contained in:
@@ -466,12 +466,71 @@ Array<Actor*> Actor::GetChildren(const MClass* type) const
|
||||
|
||||
void Actor::DestroyChildren(float timeLeft)
|
||||
{
|
||||
if (Children.IsEmpty())
|
||||
return;
|
||||
PROFILE_CPU();
|
||||
|
||||
// Actors system doesn't support editing scene hierarchy from multiple threads
|
||||
if (!IsInMainThread() && IsDuringPlay())
|
||||
{
|
||||
LOG(Error, "Editing scene hierarchy is only allowed on a main thread.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all actors
|
||||
Array<Actor*> children = Children;
|
||||
|
||||
// Inform Editor beforehand
|
||||
Level::callActorEvent(Level::ActorEventType::OnActorDestroyChildren, this, nullptr);
|
||||
|
||||
if (_scene && IsActiveInHierarchy())
|
||||
{
|
||||
// Disable children
|
||||
for (Actor* child : children)
|
||||
{
|
||||
if (child->IsActiveInHierarchy())
|
||||
{
|
||||
child->OnDisableInHierarchy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Level::ScenesLock.Lock();
|
||||
|
||||
// Remove children all at once
|
||||
Children.Clear();
|
||||
_isHierarchyDirty = true;
|
||||
|
||||
// Unlink children from scene hierarchy
|
||||
for (Actor* child : children)
|
||||
{
|
||||
child->_parent = nullptr;
|
||||
if (!_isActiveInHierarchy)
|
||||
child->_isActive = false; // Force keep children deactivated to reduce overhead during destruction
|
||||
if (_scene)
|
||||
child->SetSceneInHierarchy(nullptr);
|
||||
}
|
||||
|
||||
Level::ScenesLock.Unlock();
|
||||
|
||||
// Inform actors about this
|
||||
for (Actor* child : children)
|
||||
{
|
||||
child->OnParentChanged();
|
||||
}
|
||||
|
||||
// Unlink children for hierarchy
|
||||
for (Actor* child : children)
|
||||
{
|
||||
//child->EndPlay();
|
||||
|
||||
//child->SetParent(nullptr, false, false);
|
||||
}
|
||||
|
||||
// Delete objects
|
||||
const bool useGameTime = timeLeft > ZeroTolerance;
|
||||
for (Actor* child : children)
|
||||
{
|
||||
child->SetParent(nullptr, false, false);
|
||||
child->DeleteObject(timeLeft, useGameTime);
|
||||
}
|
||||
}
|
||||
@@ -1280,7 +1339,6 @@ void Actor::OnActiveChanged()
|
||||
if (wasActiveInTree != IsActiveInHierarchy())
|
||||
OnActiveInTreeChanged();
|
||||
|
||||
//if (GetScene())
|
||||
Level::callActorEvent(Level::ActorEventType::OnActorActiveChanged, this, nullptr);
|
||||
}
|
||||
|
||||
@@ -1311,7 +1369,6 @@ void Actor::OnActiveInTreeChanged()
|
||||
|
||||
void Actor::OnOrderInParentChanged()
|
||||
{
|
||||
//if (GetScene())
|
||||
Level::callActorEvent(Level::ActorEventType::OnActorOrderInParentChanged, this, nullptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -263,6 +263,9 @@ Delegate<Actor*, Actor*> Level::ActorParentChanged;
|
||||
Delegate<Actor*> Level::ActorOrderInParentChanged;
|
||||
Delegate<Actor*> Level::ActorNameChanged;
|
||||
Delegate<Actor*> Level::ActorActiveChanged;
|
||||
#if USE_EDITOR
|
||||
Delegate<Actor*> Level::ActorDestroyChildren;
|
||||
#endif
|
||||
Delegate<Scene*, const Guid&> Level::SceneSaving;
|
||||
Delegate<Scene*, const Guid&> Level::SceneSaved;
|
||||
Delegate<Scene*, const Guid&> Level::SceneSaveError;
|
||||
@@ -851,6 +854,11 @@ void Level::callActorEvent(ActorEventType eventType, Actor* a, Actor* b)
|
||||
case ActorEventType::OnActorActiveChanged:
|
||||
ActorActiveChanged(a);
|
||||
break;
|
||||
#if USE_EDITOR
|
||||
case ActorEventType::OnActorDestroyChildren:
|
||||
ActorDestroyChildren(a);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -549,7 +549,13 @@ private:
|
||||
OnActorOrderInParentChanged = 3,
|
||||
OnActorNameChanged = 4,
|
||||
OnActorActiveChanged = 5,
|
||||
#if USE_EDITOR
|
||||
OnActorDestroyChildren = 6,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void callActorEvent(ActorEventType eventType, Actor* a, Actor* b);
|
||||
#if USE_EDITOR
|
||||
API_EVENT(Internal) static Delegate<Actor*> ActorDestroyChildren;
|
||||
#endif
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user