ecsrx.unity icon indicating copy to clipboard operation
ecsrx.unity copied to clipboard

GetComponent throwing random KeyNotFoundException

Open yanek opened this issue 7 years ago • 3 comments

  • Unity: 2017.3.1f1
  • EcsRx: 0.11.0 (release)
  • Zenject: 5.5.1
  • UniRx: 5.5.0

I am facing a weird issue where the name of a class seems to makes EcsRx throw KeyNotFoundExceptions whenever I use entity.GetComponent. I was not able to isolate a clear pattern, so I will try to be as precise as possible.

So, I have a really simple ISetupSystem...

public class RotationSetupSystem : ISetupSystem
{
    public RotationSetupSystem () {
        TargetGroup = new Group(typeof(RotationComponent), typeof(ViewComponent));
    }

    public IGroup TargetGroup { get; private set; }

    public void Setup (IEntity entity) {
        Quaternion value = entity.GetComponent<ViewComponent>().View.transform.localRotation;
        entity.GetComponent<RotationComponent>().Value = value.eulerAngles;
    }
}

... which throws this error whenever I hit Play in Unity:

KeyNotFoundException: The given key was not present in the dictionary.
System.Collections.Generic.Dictionary`2[System.Type,EcsRx.Components.IComponent].get_Item (System.Type key) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:150)
EcsRx.Entities.Entity.GetComponent[ViewComponent] () (at Assets/Libraries/EcsRx/Framework/Entities/Entity.cs:75)
Sources.Systems.Core.RotationSetupSystem.Setup (IEntity entity) (at Assets/Sources/Systems/Core/RotationSetupSystem.cs:26)
...

I double checked that all target entities had a View, and a RotationComponent, and everything looked fine. So I started messing around, and renaming the system's class to FooRotationSetupSystem makes it work as expected.

I first thought that RotationSetupSystem might have been a reserved name by EcsRx but found no trace of it. I renamed the class again to ViewRotationSetupSystem and, bad luck, the exception was back!

I tried a bunch of names for that system, and some are working, some are throwing a KeyNotFoundException. And as I said, I was not able to isolate some kind of pattern, or rule, it seems completely random but specific to that system (I never had this issue before, with any other system I wrote).

yanek avatar Apr 05 '18 09:04 yanek

Hmm seems odd, it implies that ViewComponent is not on the entity, but they would have to be for the system to run, you able to discuss in Gitter as I will probably need to ask further questions about the entity setup code and what other systems are interacting on the entity etc?

Ultimately the name of the system or component shouldnt matter, it seems more like some systems are running before others depending on their resolving order (which may be alphabetic under the hood, thats up to Zenject), so it could be a case of all applicable systems are located, then they are actioned, but one of the systems before this one removes the ViewComponent but then the next system in line to use it blows up because the component has been removed in another system when it has been trying to resolve.

grofit avatar Apr 05 '18 09:04 grofit

The fix for this should be to check after each system run that the components still apply when it is bulk applying applicable systems.

Will look at getting this put in once the rx battle has died down and the new version can be pushed out.

grofit avatar May 01 '18 10:05 grofit

This is still something that needs confirming in a regression step, will look at adding a test to isolate and fix, I have been fighting with the Rx issues and now have a JSON issue which is taking priority :(

grofit avatar Sep 14 '18 21:09 grofit