Clean up for Behavior API
Use TObjPtr to improve null checking. Add option to clear only specific kinds of Behaviors. Fixed removal checks while ticking. Don't stop at now-null behaviors when iterating.
This commit is contained in:
parent
1e05bb2a55
commit
7efd301810
6 changed files with 88 additions and 75 deletions
|
|
@ -213,8 +213,8 @@ void AActor::EnableNetworking(const bool enable)
|
|||
|
||||
size_t AActor::PropagateMark()
|
||||
{
|
||||
TMap<FName, DBehavior*>::Iterator it = { Behaviors };
|
||||
TMap<FName, DBehavior*>::Pair* pair = nullptr;
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Iterator it = { Behaviors };
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Pair* pair = nullptr;
|
||||
while (it.NextPair(pair))
|
||||
GC::Mark(pair->Value);
|
||||
|
||||
|
|
@ -491,33 +491,34 @@ void DBehavior::OnDestroy()
|
|||
Super::OnDestroy();
|
||||
}
|
||||
|
||||
bool AActor::RemoveBehavior(const PClass& type)
|
||||
bool AActor::RemoveBehavior(FName type)
|
||||
{
|
||||
if (Behaviors.CheckKey(type.TypeName))
|
||||
bool res = false;
|
||||
auto b = Behaviors.CheckKey(type);
|
||||
if (b != nullptr)
|
||||
{
|
||||
auto b = Behaviors[type.TypeName];
|
||||
|
||||
Behaviors.Remove(type.TypeName);
|
||||
if (b != nullptr && !(b->ObjectFlags & OF_EuthanizeMe))
|
||||
if (b->Get() != nullptr)
|
||||
{
|
||||
b->Destroy();
|
||||
return true;
|
||||
b->ForceGet()->Destroy();
|
||||
res = true;
|
||||
}
|
||||
|
||||
Behaviors.Remove(type);
|
||||
}
|
||||
|
||||
return false;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int RemoveBehavior(AActor* self, PClass* type)
|
||||
{
|
||||
return self->RemoveBehavior(*type);
|
||||
return self->RemoveBehavior(type->TypeName);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, RemoveBehavior, RemoveBehavior)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_CLASS_NOT_NULL(type, DBehavior);
|
||||
ACTION_RETURN_BOOL(self->RemoveBehavior(*type));
|
||||
ACTION_RETURN_BOOL(self->RemoveBehavior(type->TypeName));
|
||||
}
|
||||
|
||||
DBehavior* AActor::AddBehavior(PClass& type)
|
||||
|
|
@ -525,7 +526,7 @@ DBehavior* AActor::AddBehavior(PClass& type)
|
|||
if (type.bAbstract || !type.IsDescendantOf(NAME_Behavior))
|
||||
return nullptr;
|
||||
|
||||
auto b = FindBehavior(type);
|
||||
auto b = FindBehavior(type.TypeName);
|
||||
if (b == nullptr)
|
||||
{
|
||||
b = dyn_cast<DBehavior>(type.CreateNew());
|
||||
|
|
@ -542,7 +543,7 @@ DBehavior* AActor::AddBehavior(PClass& type)
|
|||
|
||||
if (b->ObjectFlags & OF_EuthanizeMe)
|
||||
{
|
||||
RemoveBehavior(type);
|
||||
RemoveBehavior(type.TypeName);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -556,7 +557,7 @@ DBehavior* AActor::AddBehavior(PClass& type)
|
|||
|
||||
if (b->ObjectFlags & OF_EuthanizeMe)
|
||||
{
|
||||
RemoveBehavior(type);
|
||||
RemoveBehavior(type.TypeName);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -582,12 +583,12 @@ void AActor::TickBehaviors()
|
|||
TArray<FName> toRemove = {};
|
||||
TArray<DBehavior*> toTick = {};
|
||||
|
||||
TMap<FName, DBehavior*>::Iterator it = { Behaviors };
|
||||
TMap<FName, DBehavior*>::Pair* pair = nullptr;
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Iterator it = { Behaviors };
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Pair* pair = nullptr;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto b = pair->Value;
|
||||
if (b == nullptr || (b->ObjectFlags & OF_EuthanizeMe))
|
||||
auto b = pair->Value.Get();
|
||||
if (b == nullptr)
|
||||
{
|
||||
toRemove.Push(pair->Key);
|
||||
continue;
|
||||
|
|
@ -598,9 +599,9 @@ void AActor::TickBehaviors()
|
|||
|
||||
for (auto& b : toTick)
|
||||
{
|
||||
if (b->Owner != this)
|
||||
if ((b->ObjectFlags & OF_EuthanizeMe) || b->Owner != this)
|
||||
{
|
||||
toRemove.Push(pair->Key);
|
||||
toRemove.Push(b->GetClass()->TypeName);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -610,12 +611,12 @@ void AActor::TickBehaviors()
|
|||
VMCall(func, params, 1, nullptr, 0);
|
||||
|
||||
if (b->ObjectFlags & OF_EuthanizeMe)
|
||||
toRemove.Push(pair->Key);
|
||||
toRemove.Push(b->GetClass()->TypeName);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& type : toRemove)
|
||||
RemoveBehavior(*PClass::FindClass(type));
|
||||
RemoveBehavior(type);
|
||||
}
|
||||
|
||||
static void TickBehaviors(AActor* self)
|
||||
|
|
@ -632,14 +633,14 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, TickBehaviors, TickBehaviors)
|
|||
|
||||
static DBehavior* FindBehavior(AActor* self, PClass* type)
|
||||
{
|
||||
return self->FindBehavior(*type);
|
||||
return self->FindBehavior(type->TypeName);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, FindBehavior, FindBehavior)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_CLASS_NOT_NULL(type, DBehavior);
|
||||
ACTION_RETURN_OBJECT(self->FindBehavior(*type));
|
||||
ACTION_RETURN_OBJECT(self->FindBehavior(type->TypeName));
|
||||
}
|
||||
|
||||
void AActor::MoveBehaviors(AActor& from)
|
||||
|
|
@ -653,12 +654,12 @@ void AActor::MoveBehaviors(AActor& from)
|
|||
|
||||
// Clean up any empty behaviors that remained as well while
|
||||
// changing the owner.
|
||||
TMap<FName, DBehavior*>::Iterator it = { Behaviors };
|
||||
TMap<FName, DBehavior*>::Pair* pair = nullptr;
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Iterator it = { Behaviors };
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Pair* pair = nullptr;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto b = pair->Value;
|
||||
if (b == nullptr || (b->ObjectFlags & OF_EuthanizeMe))
|
||||
auto b = pair->Value.Get();
|
||||
if (b == nullptr)
|
||||
{
|
||||
toRemove.Push(pair->Key);
|
||||
continue;
|
||||
|
|
@ -673,7 +674,7 @@ void AActor::MoveBehaviors(AActor& from)
|
|||
}
|
||||
|
||||
for (auto& type : toRemove)
|
||||
RemoveBehavior(*PClass::FindClass(type));
|
||||
RemoveBehavior(type);
|
||||
}
|
||||
|
||||
static void MoveBehaviors(AActor* self, AActor* from)
|
||||
|
|
@ -689,30 +690,37 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, MoveBehaviors, MoveBehaviors)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void AActor::ClearBehaviors()
|
||||
void AActor::ClearBehaviors(PClass* type)
|
||||
{
|
||||
TArray<FName> toRemove = {};
|
||||
|
||||
TMap<FName, DBehavior*>::Iterator it = { Behaviors };
|
||||
TMap<FName, DBehavior*>::Pair* pair = nullptr;
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Iterator it = { Behaviors };
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Pair* pair = nullptr;
|
||||
while (it.NextPair(pair))
|
||||
toRemove.Push(pair->Key);
|
||||
{
|
||||
auto b = pair->Value.Get();
|
||||
if (type == nullptr || b == nullptr || b->IsKindOf(type))
|
||||
toRemove.Push(pair->Key);
|
||||
}
|
||||
|
||||
for (auto& type : toRemove)
|
||||
RemoveBehavior(*PClass::FindClass(type));
|
||||
RemoveBehavior(type);
|
||||
|
||||
Behaviors.Clear();
|
||||
// If not removing a specific type, clear whatever remains.
|
||||
if (type == nullptr)
|
||||
Behaviors.Clear();
|
||||
}
|
||||
|
||||
static void ClearBehaviors(AActor* self)
|
||||
static void ClearBehaviors(AActor* self, PClass* type)
|
||||
{
|
||||
self->ClearBehaviors();
|
||||
self->ClearBehaviors(type);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ClearBehaviors, ClearBehaviors)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
self->ClearBehaviors();
|
||||
PARAM_CLASS(type, DBehavior);
|
||||
self->ClearBehaviors(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -720,38 +728,38 @@ void AActor::UnlinkBehaviorsFromLevel()
|
|||
{
|
||||
TArray<FName> toRemove = {};
|
||||
|
||||
TMap<FName, DBehavior*>::Iterator it = { Behaviors };
|
||||
TMap<FName, DBehavior*>::Pair* pair = nullptr;
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Iterator it = { Behaviors };
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Pair* pair = nullptr;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto b = pair->Value;
|
||||
if (b == nullptr || (b->ObjectFlags & OF_EuthanizeMe))
|
||||
auto b = pair->Value.Get();
|
||||
if (b == nullptr)
|
||||
toRemove.Push(pair->Key);
|
||||
else
|
||||
b->Level->RemoveActorBehavior(*b);
|
||||
}
|
||||
|
||||
for (auto& type : toRemove)
|
||||
RemoveBehavior(*PClass::FindClass(type));
|
||||
RemoveBehavior(type);
|
||||
}
|
||||
|
||||
void AActor::LinkBehaviorsToLevel()
|
||||
{
|
||||
TArray<FName> toRemove = {};
|
||||
|
||||
TMap<FName, DBehavior*>::Iterator it = { Behaviors };
|
||||
TMap<FName, DBehavior*>::Pair* pair = nullptr;
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Iterator it = { Behaviors };
|
||||
TMap<FName, TObjPtr<DBehavior*>>::Pair* pair = nullptr;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto b = pair->Value;
|
||||
if (b == nullptr || (b->ObjectFlags & OF_EuthanizeMe))
|
||||
auto b = pair->Value.Get();
|
||||
if (b == nullptr)
|
||||
toRemove.Push(pair->Key);
|
||||
else
|
||||
Level->AddActorBehavior(*b);
|
||||
}
|
||||
|
||||
for (auto& type : toRemove)
|
||||
RemoveBehavior(*PClass::FindClass(type));
|
||||
RemoveBehavior(type);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue