Skip to content

Commit

Permalink
Made material slot setup threadsafe.
Browse files Browse the repository at this point in the history
  • Loading branch information
Koderz committed Mar 24, 2024
1 parent b4dfba7 commit 44c7649
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 3 deletions.
66 changes: 65 additions & 1 deletion Source/RealtimeMeshComponent/Private/RealtimeMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,61 @@ URealtimeMesh::URealtimeMesh(const FObjectInitializer& ObjectInitializer)
{
}

void URealtimeMesh::BroadcastBoundsChangedEvent()
{
if (!IsInGameThread())
{
TWeakObjectPtr<URealtimeMesh> WeakThis(this);
AsyncTask(ENamedThreads::GameThread, [WeakThis]()
{
if (const auto Mesh = WeakThis.Get())
{
Mesh->BoundsChangedEvent.Broadcast(Mesh);
}
});
}
else
{
BoundsChangedEvent.Broadcast(this);
}
}

void URealtimeMesh::BroadcastRenderDataChangedEvent(bool bShouldRecreateProxies)
{
if (!IsInGameThread())
{
TWeakObjectPtr<URealtimeMesh> WeakThis(this);
AsyncTask(ENamedThreads::GameThread, [WeakThis, bShouldRecreateProxies]()
{
if (const auto Mesh = WeakThis.Get())
{
Mesh->RenderDataChangedEvent.Broadcast(Mesh, bShouldRecreateProxies);
}
});
}
else
{
RenderDataChangedEvent.Broadcast(this, bShouldRecreateProxies);
}
}

void URealtimeMesh::BroadcastCollisionBodyUpdatedEvent(UBodySetup* NewBodySetup)
{
CollisionBodyUpdatedEvent.Broadcast(this, NewBodySetup);
if (!IsInGameThread())
{
TWeakObjectPtr<URealtimeMesh> WeakThis(this);
AsyncTask(ENamedThreads::GameThread, [WeakThis, NewBodySetup]()
{
if (const auto Mesh = WeakThis.Get())
{
Mesh->CollisionBodyUpdatedEvent.Broadcast(Mesh, NewBodySetup);
}
});
}
else
{
CollisionBodyUpdatedEvent.Broadcast(this, NewBodySetup);
}
}

void URealtimeMesh::Initialize(const TSharedRef<RealtimeMesh::FRealtimeMeshSharedResources>& InSharedResources)
Expand All @@ -64,6 +116,8 @@ void URealtimeMesh::Initialize(const TSharedRef<RealtimeMesh::FRealtimeMeshShare

void URealtimeMesh::Reset(bool bCreateNewMeshData)
{
RealtimeMesh::FRealtimeMeshScopeGuardWrite ScopeGuard(SharedResources->GetGuard());

UE_LOG(LogTemp, Warning, TEXT("RM Resetting... %s"), *GetName());
if (!bCreateNewMeshData)
{
Expand Down Expand Up @@ -122,6 +176,8 @@ void URealtimeMesh::RemoveTrailingLOD()

void URealtimeMesh::SetupMaterialSlot(int32 MaterialSlot, FName SlotName, UMaterialInterface* InMaterial)
{
RealtimeMesh::FRealtimeMeshScopeGuardWrite ScopeGuard(SharedResources->GetGuard());

// Does this slot already exist?
if (SlotNameLookup.Contains(SlotName))
{
Expand All @@ -148,39 +204,47 @@ void URealtimeMesh::SetupMaterialSlot(int32 MaterialSlot, FName SlotName, UMater

int32 URealtimeMesh::GetMaterialIndex(FName MaterialSlotName) const
{
RealtimeMesh::FRealtimeMeshScopeGuardRead ScopeGuard(SharedResources->GetGuard());

const int32* SlotIndex = SlotNameLookup.Find(MaterialSlotName);
return SlotIndex ? *SlotIndex : INDEX_NONE;
}

bool URealtimeMesh::IsMaterialSlotNameValid(FName MaterialSlotName) const
{
RealtimeMesh::FRealtimeMeshScopeGuardRead ScopeGuard(SharedResources->GetGuard());
return SlotNameLookup.Contains(MaterialSlotName);
}

FRealtimeMeshMaterialSlot URealtimeMesh::GetMaterialSlot(int32 SlotIndex) const
{
RealtimeMesh::FRealtimeMeshScopeGuardRead ScopeGuard(SharedResources->GetGuard());
return MaterialSlots[SlotIndex];
}

int32 URealtimeMesh::GetNumMaterials() const
{
RealtimeMesh::FRealtimeMeshScopeGuardRead ScopeGuard(SharedResources->GetGuard());
return MaterialSlots.Num();
}

TArray<FName> URealtimeMesh::GetMaterialSlotNames() const
{
RealtimeMesh::FRealtimeMeshScopeGuardRead ScopeGuard(SharedResources->GetGuard());
TArray<FName> OutNames;
SlotNameLookup.GetKeys(OutNames);
return OutNames;
}

TArray<FRealtimeMeshMaterialSlot> URealtimeMesh::GetMaterialSlots() const
{
RealtimeMesh::FRealtimeMeshScopeGuardRead ScopeGuard(SharedResources->GetGuard());
return MaterialSlots;
}

UMaterialInterface* URealtimeMesh::GetMaterial(int32 SlotIndex) const
{
RealtimeMesh::FRealtimeMeshScopeGuardRead ScopeGuard(SharedResources->GetGuard());
if (MaterialSlots.IsValidIndex(SlotIndex))
{
return MaterialSlots[SlotIndex].Material;
Expand Down
4 changes: 2 additions & 2 deletions Source/RealtimeMeshComponent/Public/RealtimeMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class REALTIMEMESHCOMPONENT_API URealtimeMesh : public UObject, public IInterfac
FCollisionBodyUpdated& OnCollisionBodyUpdated() { return CollisionBodyUpdatedEvent; }

protected:
void BroadcastBoundsChangedEvent() { BoundsChangedEvent.Broadcast(this); }
void BroadcastRenderDataChangedEvent(bool bShouldRecreateProxies) { RenderDataChangedEvent.Broadcast(this, bShouldRecreateProxies); }
void BroadcastBoundsChangedEvent();
void BroadcastRenderDataChangedEvent(bool bShouldRecreateProxies);
void BroadcastCollisionBodyUpdatedEvent(UBodySetup* NewBodySetup);

void Initialize(const TSharedRef<RealtimeMesh::FRealtimeMeshSharedResources>& InSharedResources);
Expand Down

0 comments on commit 44c7649

Please sign in to comment.