How to provide preallocated data to parallel jobs?

One of the recurring issues I have with dots is how to provide preallocated data to parallel jobs. As Native structures can not be nested I can not have a NativeArray nor can I have a MyData field in a IComponentData

In the past I have created variants of Native* without the safety features and this allows me to provide preallocated data to parallel jobs where I access a particular instance using NativeThreadIndex, combined with lazy allocation this works reasonably well for any number of threads

Currently I am looking to provide preallocated PhysicsWorlds to a parallel job and now the approach above breaks down. I can put worlds in a list with the safety features removed, but as PhysicsWorld contains Native structures the memory leak detection system thinks I am leaking the worlds I store in this list.

Is there a solution to this, can I somehow associate a PhysicsWorld with IComponentData that I’m not aware of?

So I don’t like systems accessing other systems so I changed how I used Unity Physics and made a singleton component that held the physics world with automatic dependency management so I don’t need to access the physics systems.

The physics worlds have NativeContainers though.

This isn’t the exact same problem you are looking at, but I’ve attached the source code to how I do it and maybe you can take inspiration from it.
AtomicSafetyManager is a slightly modified version from within the physics package
NativeArrayProxy is from the physics package

6972107–822029–CollisionWorldProxy.cs (5.87 KB)
6972107–822032–PhysicsWorldOutputDependencySystem.cs (2.67 KB)
6972107–822035–PhysicsWorldInputDependencySystem.cs (1.23 KB)

1 Like

Thanks so much, I’ll check it out

That should work yeah, as my only issue is memory leak detection failing when storing physicsworlds in a list without safety features Im going to stick with this for now, yuk:

void StoreWorld(PhysicsWorld world, SimulationContext simulationContext)
{
    switch (_worldIndex)
    {
        case 0:
            _world0 = world;
            _context0 = simulationContext;
            break;
        case 1:
            _world1 = world;
            _context1 = simulationContext;
            break;
        // ...
        default:
            throw new ArgumentOutOfRangeException($"Failed to store world: {_worldIndex}");
    }

    ++_worldIndex;
}