Fix #1168 deregister registered actors on "OnDestroyed" event
This commit is contained in:
parent
67c2d900e5
commit
7cb8e00135
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include "GameFramework/Controller.h"
|
||||
|
||||
void FActorDispatcher::Bind(FActorDefinition Definition, SpawnFunctionType Functor)
|
||||
void UActorDispatcher::Bind(FActorDefinition Definition, SpawnFunctionType Functor)
|
||||
{
|
||||
if (UActorBlueprintFunctionLibrary::CheckActorDefinition(Definition))
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ void FActorDispatcher::Bind(FActorDefinition Definition, SpawnFunctionType Funct
|
|||
}
|
||||
}
|
||||
|
||||
void FActorDispatcher::Bind(ACarlaActorFactory &ActorFactory)
|
||||
void UActorDispatcher::Bind(ACarlaActorFactory &ActorFactory)
|
||||
{
|
||||
for (const auto &Definition : ActorFactory.GetDefinitions())
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ void FActorDispatcher::Bind(ACarlaActorFactory &ActorFactory)
|
|||
}
|
||||
}
|
||||
|
||||
TPair<EActorSpawnResultStatus, FActorView> FActorDispatcher::SpawnActor(
|
||||
TPair<EActorSpawnResultStatus, FActorView> UActorDispatcher::SpawnActor(
|
||||
const FTransform &Transform,
|
||||
FActorDescription Description)
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ TPair<EActorSpawnResultStatus, FActorView> FActorDispatcher::SpawnActor(
|
|||
Result.Status = EActorSpawnResultStatus::UnknownError;
|
||||
}
|
||||
|
||||
auto View = Result.IsValid() ? Registry.Register(*Result.Actor, std::move(Description)) : FActorView();
|
||||
auto View = Result.IsValid() ? RegisterActor(*Result.Actor, std::move(Description)) : FActorView();
|
||||
|
||||
if (!View.IsValid())
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ TPair<EActorSpawnResultStatus, FActorView> FActorDispatcher::SpawnActor(
|
|||
return MakeTuple(Result.Status, View);
|
||||
}
|
||||
|
||||
bool FActorDispatcher::DestroyActor(AActor *Actor)
|
||||
bool UActorDispatcher::DestroyActor(AActor *Actor)
|
||||
{
|
||||
if (Actor == nullptr) {
|
||||
UE_LOG(LogCarla, Error, TEXT("Trying to destroy nullptr actor"));
|
||||
|
@ -102,9 +102,18 @@ bool FActorDispatcher::DestroyActor(AActor *Actor)
|
|||
UE_LOG(LogCarla, Log, TEXT("Destroying actor: '%s'"), *Id);
|
||||
if (Actor->Destroy())
|
||||
{
|
||||
Registry.Deregister(Actor);
|
||||
return true;
|
||||
}
|
||||
UE_LOG(LogCarla, Error, TEXT("Failed to destroy actor: '%s'"), *Id);
|
||||
return false;
|
||||
}
|
||||
|
||||
FActorView UActorDispatcher::RegisterActor(AActor &Actor, FActorDescription Description)
|
||||
{
|
||||
auto View = Registry.Register(Actor, std::move(Description));
|
||||
if (View.IsValid())
|
||||
{
|
||||
Actor.OnDestroyed.AddDynamic(this, &UActorDispatcher::OnActorDestroyed);
|
||||
}
|
||||
return View;
|
||||
}
|
||||
|
|
|
@ -14,12 +14,17 @@
|
|||
#include "Containers/Array.h"
|
||||
#include "Templates/Function.h"
|
||||
|
||||
#include "ActorDispatcher.generated.h"
|
||||
|
||||
class ACarlaActorFactory;
|
||||
|
||||
/// Actor in charge of binding ActorDefinitions to spawn functions, as well as
|
||||
/// Object in charge of binding ActorDefinitions to spawn functions, as well as
|
||||
/// keeping the registry of all the actors spawned.
|
||||
class FActorDispatcher
|
||||
UCLASS()
|
||||
class CARLA_API UActorDispatcher : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
using SpawnFunctionType = TFunction<FActorSpawnResult(const FTransform &, const FActorDescription &)>;
|
||||
|
@ -51,16 +56,15 @@ public:
|
|||
/// destruction, false if indestructible or nullptr.
|
||||
bool DestroyActor(AActor *Actor);
|
||||
|
||||
/// Register an actor that was not created using "SpawnActor" function but
|
||||
/// that should be kept in the registry.
|
||||
FActorView RegisterActor(AActor &Actor, FActorDescription ActorDescription);
|
||||
|
||||
const TArray<FActorDefinition> &GetActorDefinitions() const
|
||||
{
|
||||
return Definitions;
|
||||
}
|
||||
|
||||
FActorRegistry &GetActorRegistry()
|
||||
{
|
||||
return Registry;
|
||||
}
|
||||
|
||||
const FActorRegistry &GetActorRegistry() const
|
||||
{
|
||||
return Registry;
|
||||
|
@ -68,6 +72,12 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
UFUNCTION()
|
||||
void OnActorDestroyed(AActor *Actor)
|
||||
{
|
||||
Registry.Deregister(Actor);
|
||||
}
|
||||
|
||||
TArray<FActorDefinition> Definitions;
|
||||
|
||||
TArray<SpawnFunctionType> SpawnFunctions;
|
||||
|
|
|
@ -38,7 +38,9 @@ UCarlaEpisode::UCarlaEpisode(const FObjectInitializer &ObjectInitializer)
|
|||
Id([]() {
|
||||
static uint32 COUNTER = 0u;
|
||||
return ++COUNTER;
|
||||
}()) {}
|
||||
}()) {
|
||||
ActorDispatcher = CreateDefaultSubobject<UActorDispatcher>(TEXT("ActorDispatcher"));
|
||||
}
|
||||
|
||||
TArray<FTransform> UCarlaEpisode::GetRecommendedSpawnPoints() const
|
||||
{
|
||||
|
@ -90,7 +92,7 @@ void UCarlaEpisode::InitializeAtBeginPlay()
|
|||
FActorDescription Description;
|
||||
Description.Id = TEXT("spectator");
|
||||
Description.Class = Spectator->GetClass();
|
||||
ActorDispatcher.GetActorRegistry().Register(*Spectator, Description);
|
||||
ActorDispatcher->RegisterActor(*Spectator, Description);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -104,6 +106,6 @@ void UCarlaEpisode::InitializeAtBeginPlay()
|
|||
FActorDescription Description;
|
||||
Description.Id = UCarlaEpisode_GetTrafficSignId(Actor->GetTrafficSignState());
|
||||
Description.Class = Actor->GetClass();
|
||||
ActorDispatcher.GetActorRegistry().Register(*Actor, Description);
|
||||
ActorDispatcher->RegisterActor(*Actor, Description);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
UFUNCTION(BlueprintCallable)
|
||||
const TArray<FActorDefinition> &GetActorDefinitions() const
|
||||
{
|
||||
return ActorDispatcher.GetActorDefinitions();
|
||||
return ActorDispatcher->GetActorDefinitions();
|
||||
}
|
||||
|
||||
/// Return the list of recommended spawn points for vehicles.
|
||||
|
@ -90,7 +90,7 @@ public:
|
|||
|
||||
const FActorRegistry &GetActorRegistry() const
|
||||
{
|
||||
return ActorDispatcher.GetActorRegistry();
|
||||
return ActorDispatcher->GetActorRegistry();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
@ -105,7 +105,7 @@ public:
|
|||
/// invalid.
|
||||
FActorView FindActor(FActorView::IdType ActorId) const
|
||||
{
|
||||
return ActorDispatcher.GetActorRegistry().Find(ActorId);
|
||||
return ActorDispatcher->GetActorRegistry().Find(ActorId);
|
||||
}
|
||||
|
||||
/// Find the actor view of @a Actor.
|
||||
|
@ -114,7 +114,7 @@ public:
|
|||
/// invalid.
|
||||
FActorView FindActor(AActor *Actor) const
|
||||
{
|
||||
return ActorDispatcher.GetActorRegistry().Find(Actor);
|
||||
return ActorDispatcher->GetActorRegistry().Find(Actor);
|
||||
}
|
||||
|
||||
/// Find the actor view of @a Actor. If the actor is not found, a "fake" view
|
||||
|
@ -124,7 +124,7 @@ public:
|
|||
/// If the actor is pending kill, the returned view is invalid.
|
||||
FActorView FindOrFakeActor(AActor *Actor) const
|
||||
{
|
||||
return ActorDispatcher.GetActorRegistry().FindOrFake(Actor);
|
||||
return ActorDispatcher->GetActorRegistry().FindOrFake(Actor);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
@ -143,7 +143,7 @@ public:
|
|||
const FTransform &Transform,
|
||||
FActorDescription ActorDescription)
|
||||
{
|
||||
return ActorDispatcher.SpawnActor(Transform, std::move(ActorDescription));
|
||||
return ActorDispatcher->SpawnActor(Transform, std::move(ActorDescription));
|
||||
}
|
||||
|
||||
/// Spawns an actor based on @a ActorDescription at @a Transform. To properly
|
||||
|
@ -170,7 +170,7 @@ public:
|
|||
UFUNCTION(BlueprintCallable)
|
||||
bool DestroyActor(AActor *Actor)
|
||||
{
|
||||
return ActorDispatcher.DestroyActor(Actor);
|
||||
return ActorDispatcher->DestroyActor(Actor);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
@ -194,7 +194,7 @@ private:
|
|||
|
||||
void RegisterActorFactory(ACarlaActorFactory &ActorFactory)
|
||||
{
|
||||
ActorDispatcher.Bind(ActorFactory);
|
||||
ActorDispatcher->Bind(ActorFactory);
|
||||
}
|
||||
|
||||
const uint32 Id = 0u;
|
||||
|
@ -202,7 +202,8 @@ private:
|
|||
UPROPERTY(VisibleAnywhere)
|
||||
FString MapName;
|
||||
|
||||
FActorDispatcher ActorDispatcher;
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
UActorDispatcher *ActorDispatcher = nullptr;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
APawn *Spectator = nullptr;
|
||||
|
|
|
@ -75,21 +75,21 @@ static carla::Buffer AWorldObserver_Serialize(
|
|||
write_data(header);
|
||||
|
||||
// Write every actor.
|
||||
for (auto &&actor_view : Registry) {
|
||||
check(actor_view.GetActor() != nullptr);
|
||||
for (auto &&View : Registry) {
|
||||
check(View.IsValid());
|
||||
constexpr float TO_METERS = 1e-2;
|
||||
const auto velocity = TO_METERS * actor_view.GetActor()->GetVelocity();
|
||||
const auto velocity = TO_METERS * View.GetActor()->GetVelocity();
|
||||
// get the angular velocity
|
||||
const auto RootComponent = Cast<UPrimitiveComponent>(actor_view.GetActor()->GetRootComponent());
|
||||
const auto RootComponent = Cast<UPrimitiveComponent>(View.GetActor()->GetRootComponent());
|
||||
FVector angularVelocity { 0.0f, 0.0f, 0.0f };
|
||||
if (RootComponent != nullptr)
|
||||
angularVelocity = RootComponent->GetPhysicsAngularVelocityInDegrees();
|
||||
ActorDynamicState info = {
|
||||
actor_view.GetActorId(),
|
||||
actor_view.GetActor()->GetActorTransform(),
|
||||
View.GetActorId(),
|
||||
View.GetActor()->GetActorTransform(),
|
||||
carla::geom::Vector3D{velocity.X, velocity.Y, velocity.Z},
|
||||
carla::geom::Vector3D{angularVelocity.X, angularVelocity.Y, angularVelocity.Z},
|
||||
AWorldObserver_GetActorState(actor_view)
|
||||
AWorldObserver_GetActorState(View)
|
||||
};
|
||||
write_data(info);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue