In my new game that I make with ecs I want to be able to store all my buildings in a NativeParallelHashMap.
The HashMap should be a dictionary with the key int2 as the position and the value is an entity.
The problem is that the NativeParallelHashMap is not primitive (so I can’t set this as a singleton) and I neither found a solution nor an alternative for the hashmap.
If you’re still thinking “singleton” you’re in the wrong forum.
You will not find a single singleton in jobified (entitified?) DOTS code and for good reason: they won’t work with jobs, or entity systems for that matter.
A singleton implies a static reference to a managed instance, neither static variables nor managed references are allowed in Jobs.
What Tertle said. In 1.0 system data is encouraged to move outside of systems unless it’s local but for something like a Hashmap that’s read by several systems, a Singleton is pretty cool. The nice thing about it, if you set the system dependency via GetSingleton or GetSingletonRW in OnCreate you don’t even have to worry about some scheduled jobs reading while it’s still being written to. The job system takes care of it. It could work as static just fine but having clear dependencies is quite important in Entities.
The best way to find out how this works is to look at PhysicsWorldSingleton in BuildPhysicsWorld.
That’s incorrect. As many said above. We use singleton entities for shared native containers for the long time before 1.0 (since the first versions if I remember correctly, it’s been very long time ago). We using class IComponentData (as before 1.0 native containers not allowed for struct ICD because of managed DisposeSentinel) with our custom dependency tracking mechanism, and every system which requires access to that shared native container (for example global map container on pathfinding requests queue) doing this properly through singleton entity with required access pattern (RO\RW) and passing that native container to required jobs without breaking any dependency chains.
So I’m a bit further. But I still have a question.
How can I use the Singleton in a Entities.ForEach with ScheduleParallel?
When I want to get access to it, it says:
error DC0004: Entities.ForEach Lambda expression captures a non-value type ‘buildingSystem’. This is only allowed with .WithoutBurst() and .Run()
(I used the ecs 0.5 example of mattdymott)
Thank you
Because BuildingSystem is a managed system you won’t be able to use it directly inside a job.
Instead assign a local variable with the hash map and because the hash map is not managed you can use it inside a job.
public partial class SomeOtherSystem : SystemBase
{
protected override void OnUpdate()
{
var buildingSystem = World.GetOrCreate<BuildingSystem>();
var buildingHashMap = buildingSystem.BuildingHashMap;
Entities
.ForEach((Entity entity) =>
{
var entity = buildingHashMap[new int2(0, 0)];
})
.Run();
}
}