Search Unity

Bug RequireSingletonForUpdate does not seem to work the same way as RequireForUpdate

Discussion in 'Entity Component System' started by alexandre-fiset, Aug 31, 2021.

  1. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    715
    We stumbled upon a really weird issue. We have a system that shows a debug console view when pressing "#". The DebugConsoleView is a singleton and pressing the input adds some components to it to trigger it's transition to "shown" state.

    The problem we encountered is that the update stopped working after showing the view. The Entities inspector still displayed our DebugConsoleView as existing and being alone / a singleton. It seems like structural changes to a singleton can somehow make RequireSingletonForUpdate<Component> stop working.

    Changing it to RequireForUpdate(query) worked, even if the query always have 1 entry. So I wondered, what works differently under the hood for RequireSingletonForUpdate for it to not work under the same circumstances than RequireForUpdate(singletonQuery)?

    It really took me a while to pinpoint the singleton requirement as the culprit in my situation and now I fear this bug can happen elsewhere in my program.

    The system is simple. It listens to three inputs and triggers some structual changes when an input pass. There's not much more to it.
     
  2. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    260
    I haven't experienced any problems with using RequireSingletonForUpdate, but I'll keep an eye out for any. It looks like the implementation for RequireSingletonForUpdate internally just requires the query of the singleton for update.

    Code (CSharp):
    1.         public void RequireSingletonForUpdate<T>()
    2.         {
    3.             var type = ComponentType.ReadOnly<T>();
    4.             var query = GetSingletonEntityQueryInternal(type);
    5.             RequireForUpdate(query);
    6.         }
    I wonder if something in GetSingletonEntityQueryInternal is to blame?

    Code (CSharp):
    1.         internal EntityQuery GetSingletonEntityQueryInternal(ComponentType type)
    2.         {
    3.             ref var handles = ref EntityQueries;
    4.  
    5.             for (var i = 0; i != handles.Length; i++)
    6.             {
    7.                 var query = handles[i];
    8.                 var queryData = query._GetImpl()->_QueryData;
    9.  
    10.                 // EntityQueries are constructed including the Entity ID
    11.                 if (2 != queryData->RequiredComponentsCount)
    12.                     continue;
    13.  
    14.                 if (queryData->RequiredComponents[1] != type)
    15.                     continue;
    16.  
    17.                 return query;
    18.             }
    19.  
    20.             var newQuery = EntityManager.CreateEntityQuery(&type, 1);
    21.  
    22.             AddReaderWriters(newQuery);
    23.             AfterQueryCreated(newQuery);
    24.  
    25.             return newQuery;
    26.         }
     
  3. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    It's probably a long shot... but I was wondering why my RequireSingletonForUpdate was not working properly and then once I moved it from OnStartRunning() to OnCreate() it started working.
     
    bb8_1 and Elapotp like this.