IFixedRateManager has me a little Nervous

If I understand correctly, ComponentSystemGroup.UpdateCallback was added to support the DOTS team’s need to support fixed timestep system updates in Unity.Physics.

However, using ComponentSystemGroup.UpdateCallback to repeat a group of systems for other reasons has been an important part of our code. There are some valid reasons to run a group of systems more than once in an ECS game, although it would be tough for me to share much about our use without getting into NDA territory.

The recent change to ComponentSystemGroup in Entities 0.16 replaces UpdateCallback with the IFixedRateManager interface. Right now, this isn’t a problem - We can use that interface to do the same thing we were doing with UpdateCallback.

However, the API change is concerning, because it takes a feature which was previously named in a purpose-independent way (“UpdateCallback”), and renames it to seem like it’s only valid to use for one, specific purpose (“IFixedRateManager”).

Our team can’t help but be a little nervous about this: Although this API change still lets us do what we need (we just write an IFixedRateManager.ShouldGroupUpdate() method that checks our own logic, and ignores anything related to timesteps) - Could that change in the future?

It’s not out of the question that IFixedRateManager may also go away at some point, in favor an internal solution that only allows for repeating systems based on fixed timesteps. That would make life quite difficult for us. We would probably end up creating our own, custom version of ComponentSystemGroup, which let us do what we need. But that would move a fundamental part of our code out of sync with the standard DOTS library: a worrisome prospect, as Unity could choose to add internal functionality to ComponentSystemGroup in the future - something we couldn’t replicate.

It would be very nice to get a reassurance that Unity isn’t planning to get rid of the ability to repeat a ComponentSystemGroup’s systems for reasons other than fixed timestep updates. Ideally, there should always be a way to repeat a ComponentSystemGroup based on whatever criteria a dev wants.

Thanks for any input.

4 Likes

I think IFixedRateManager must become more abstract IUpdateRateManager

2 Likes

I agree. I currently have a group of systems that updates every 1 second. This works fine with a “fixed update” API, but within that group, I’m updating a couple of systems 3 times each. To accomplish this, I have a group that runs inside the fixed rate group, but its Update callback returns true exactly 3 times.

I went with this approach to avoid duplicating a bunch of Entities.ForEach calls 3 times in the same system. The Update callback seemed like a good way to do this, but with the API change, I’m now wondering if this feature was only intended for fixed rate use cases.

Can you show a minimum code of doing this using IFixedRateManager?

Here is a simple example of a IFixedRateManager implementation that can be used to run a group N times:

public class FixedUpdateCountManager : IFixedRateManager
{
    private readonly int _iterations;
    private int _lastIteration;
 
    // Needed for interface, but not used.
    public float Timestep { get; set; }

    public FixedUpdateCountManager(int iterations) => _iterations = iterations;

    public bool ShouldGroupUpdate(ComponentSystemGroup group)
    {
        if (_lastIteration >= _iterations)
        {
            _lastIteration = 0;
            return false;
        }
        _lastIteration++;
        return true;
    }
}

And here is a system group that runs in the SimulationSystemGroup that makes use of it:

[UpdateInGroup(typeof(SimulationSystemGroup))]
public class RunThreeTimesSystemGroup: ComponentSystemGroup
{
    public RunThreeTimesSystemGroup() => FixedRateManager = new FixedUpdateCountManager(3);
}
1 Like