I’m offloading a bunch of terrain generation to an AsyncTask.
I have a free function with this signature:
namespace GenerateMeshData
{
void CreateMeshData(TSafeSharedPtr<FProceduralChunkSharedData> SharedData,
FProceduralChunkData ChunkData,
FVector ActorLocation);
}
Where a TSafeSharedPtr<T>
is just
template <typename T>
using TSafeSharedPtr = TSharedPtr<T, ESPMode::ThreadSafe>;
I’m spawning a bunch of actors with ProceduralMeshes, and each one that spawns creates a new task to generate its mesh with
AsyncTask(ENamedThreads::Type::AnyBackgroundThreadNormalTask, [=, Location = GetActorLocation()]()
{ GenerateMeshData::CreateMeshData(SharedData, ChunkData, Location); });
SharedData here is simply a member of the Actor. It is a TSafeSharedPtr to a plain struct that contains TArrays of primitives (not UObjects) and a bool that is initialized to false and becomes true when the calculation is done. ChunkData is just a struct of settings for the generation, mostly ints.
This code all works; the terrain generation takes place and I have a manager Actor that simply spawns these in and out of the game as the player runs around. I can run around in infinite rolling hills to my heart’s content. However I have some sort of problem with the TSafeSharedPtr
, if I quit the game early I get an exception in the destructor of the pointer, right where the CreateMeshData function returns.
It seems to me that perhaps the object pointed to by the pointer is getting freed before this thread finishes, but that shouldn’t be possible with threadsafe reference counting . . . So I’m probably wrong and that’s not what’s happening.
Any help is greatly appreciated. Doubly so if there is a much better way to do this.