#ECS - System State Sharing Questions

1 messages · Page 1 of 1 (latest)

craggy sierra
#

I'm currently building a prototype using only ECS where it's possible.

To share State between systems without creating dependencies I found 2 main ways so far.

The first one :

Have a ComponentData as a singleton in the system,
querying it with

SystemAPI.GetSingleton<T>() 
// or  SystemAPI.GetSingletonRW<>() if I need to modify stuff in the component in a system update look 

and then doing stuff on it.

The second is to do a

 EntityManager.AddComponent<T>(SystemHandle);

In the system that do the calculation , then

EntityManager.SetComponentData(SystemHandle, new T(){});

When I calculate the value
Then in the systems that use that component do a :

SystemHandle sytemHandle = EntityManager.World.GetExistingSystem<T>();

To store the reference of the system & then later query :

EntityManager.GetComponentData<T>(sytemHandle)

To request the data.

Thinking long term , code cleanyness etc ... which option seems the most reasonable ?
Both are possible but I don't get when to use what approach.

#

ECS - System State Sharing Question

fiery shadow
#

Haven't seen the second yet. I think it was recommended that only one system updates a singleton. Maybe explaining your use case makes it easier to answer?

wise marsh
#

First definitely better! in general, we explicitly recommend against referring to one system from another.

craggy sierra
craggy sierra
# wise marsh First definitely better! in general, we explicitly recommend against referring t...

Fair enough. thanks for the answer

System wise do you have a specific recommendation concerning execution order ?

Like I create custom groups , and order them around the existing life cycles systems currently and then ordering them one after the others. Hopefully it should not pose too much problems in the future.

( my main concern is scalability , do you have any recommendation on that front ? )

wise marsh
#

for scalability, the main things are to use bursted isystems, avoid structural changes where possible, and profile. this method of using singletons to communicate between systems was originally invented for the purpose of converting all our internal systems to bursted isystems, which we did for the express purpose of speed/scale

craggy sierra
#

Gotcha, thanks !

#

At least I know i'm on the right track.

stark raptor
craggy sierra
#

Obviously not
But good practices matter

#

If one thing has been made for a purpose, better use that same thing 🙂

wise marsh
# stark raptor 🤔 Does it mean when u have 100 bursted isystems it will create 100 isystems sin...

i'm not the system entity expert, but i believe it will actually create a system entity with at least a SystemInstance on it for every system, bursted isystem or otherwise. that said, not all of them will end up in the same chunk, because for example, at least in master, ECB systems add their singletons to their system entities, which means those system entities will move to another chunk by virtue of changing archetype.

why do you ask?

stark raptor
bitter radish
#

(please note any benchmarking about this stuff i might have done was in 0.17 or 0.51)

#

(i have not bench marked 1.0 like this - we still use 0.51 at work so it's not a focus for me, better things to work on in free time!)

wise marsh
#

this does not add that many archetypes. archetype fragmentation may be an issue, but without a profile saying so i'm highly skeptical that system entities contribute to it significantly

craggy sierra
#

Now that i'm thinking about it ....

Is it worth it to cache the entity where the singleton is ?

or should I not worry about that and simple just do a SystemAPI.GetSingleton in the update loop directly ?

An another question is related to the usage of ISystem -> in the system that calculate & update the data in the singleton component what is the optimal way of updating the data ?

SystemAPI.GetSingletonRW<T>().ValueRW = something

Or updating the values individually ? ( I suppose that if you have 3 fields & update them one by one it's 3 structural changes instead of one with the previous way )

wise marsh
#

it is not structural changes; in general updating values in a singleton is not a structural change. structural changes are where an entity changes archetype (e.g. by adding or removing components, or by changing the value of a shared component) and therefore has to have its component data moved between chunks

craggy sierra
#

An another question about best practice I was wondering about in the case of some system state is Imagine that we have something like that :

public partial class TestSystem : SystemBase
    {        
        protected override void OnCreate()
        {
            dataEntity = EntityManager.CreateSingleton<GridBrushSnapComponent>();
        }

        protected override void OnUpdate()
        {
         NativeArray<float3> _dataPoints = new NativeArray<float3>(10000, Allocator.TempJob);

        dataPointsJob job = new()
            {
                Datapoint = _dataPoints;
            };

          job.Schedule() // or complete , whatever 

        _dataPoints.CopyTo(SystemAPI.GetSingletonRW<DataPointComponent>().ValueRW.DataPoint);

        _dataPoints.Dispose();
        }
    }

My question here is : Is that a good way of doing that kind of work ?
Or would it be better to just take the _dataPoints out of the update loop so it's allocated once ?
Or maybe I should work directly with the Singleton Component in that situation ?

#

it's just a dumb example to, next , generalise practices in a form of kindof a cook book for dots 😄

#

ECS - System State Sharing Questions

wise marsh
#

i should note that GetSingletonRW requires a sync point, which i did not talk about but which can cause performance issues, basically because we have to make sure that no outstanding jobs are reading from that component. if this is an issue, you'll see bubbles of idle worker threads associated with your system in the profiler. it can be tricky to both ensure complete safety against race conditions and also no pipeline bubbles, but such is optimization work.

the example you posted should not work because you do have to schedule and then complete in order to access the data accessed by the job, rather than only scheduling.

other than that, seems fine to me. also, we should be releasing samples soon(tm) that hopefully will have good examples of how to do this stuff

craggy sierra
#

No way of havng early access to these samples ? 😄