Search Unity

Can EntityManager.SetComponentDataRaw() be exposed and add query overload?

Discussion in 'Entity Component System' started by Lieene-Guo, Sep 18, 2020.

  1. Lieene-Guo

    Lieene-Guo

    Joined:
    Aug 20, 2013
    Posts:
    547
    EntityManager.SetComponentDataRaw(Entity entity, int typeIndex, void* data, int size)
    Is very useful for System design. When the component data type is not yet defined.
    I have made a ComponentData level Database to store untyped data blobs. which utilizes SetComponentDataRaw to update ComponentData by level automatically. I believe. Expose and overriding SetComponentDataRaw is a pretty good idea for early-stage system design.

    The user could be expecting:
    1. EntityQuery overload
    2. Async overload
    3. EntityCommandBuffer equivalent API
    4. Maybe also SystemBase equivalent API

    Code (CSharp):
    1.         unsafe public static void SetComponentLevelRaw(this EntityManager em, Entity entity, ref LeveledDatabaseBlob blobData, Locator locator, int level = 1)
    2.             => em.SetComponentDataRaw(entity, locator.TypeIndex, blobData.GetDataRaw(locator, level).UnsafePtr, locator.DataSize);
    3.  
    4.         unsafe public static void SetComponentLevelRaw(this EntityManager em, Entity entity, ref LeveledDatabaseBlob blobData, int id, int level = 1)
    5.             => em.SetComponentLevelRaw(entity, ref blobData, blobData.GetLocatorByID(id), level);
    6.  
    7.         unsafe public static void SetComponentLevelRaw(this EntityManager em, Entity entity, ref LeveledDatabaseBlob blobData, FixedString32 name, int level = 1)
    8.             => em.SetComponentLevelRaw(entity, ref blobData, blobData.GetIdByName(name), level);

    PS. Data in my ComponentData level Database is filled via a combination of reflection editor inspector GUI and .cvs/.exel file. Data type can be pick from unity editor later when it's defined.
     

    Attached Files:

    Last edited: Sep 18, 2020
    FoodFish_ and cultureulterior like this.
  2. quabug

    quabug

    Joined:
    Jul 18, 2015
    Posts:
    66
    You can use `AssemblyReference` to access internal method in `Unity.Entities`
    upload_2020-9-18_23-34-45.png
     
    florianhanke and JesOb like this.
  3. Lieene-Guo

    Lieene-Guo

    Joined:
    Aug 20, 2013
    Posts:
    547
    Yes, That's what I have been using. I just what unity to consider generalize and public this API.

    P.S. the AssemblyReference trick is better to be use with.
    Code (CSharp):
    1. using System.Runtime.CompilerServices;
    2. [assembly: InternalsVisibleTo("YourAssemblyName")]
    When you still want to keep you internally accessible code in a separate dll
     
    Last edited: Sep 20, 2020
    brunocoimbra likes this.
  4. Lieene-Guo

    Lieene-Guo

    Joined:
    Aug 20, 2013
    Posts:
    547
  5. Lieene-Guo

    Lieene-Guo

    Joined:
    Aug 20, 2013
    Posts:
    547
    This code is part of my DataLevelSystem witch upgrade ComponentData when there is a Level Change(upgrade)
    Code (CSharp):
    1.  
    2.     var entityMgrCache = EntityManager;
    3.     Entities.WithName("UpdateDataLevel")
    4.     .WithBurst()
    5.     .WithEntityQueryOptions(EntityQueryOptions.IncludeDisabled | EntityQueryOptions.IncludePrefab)
    6.     .WithChangeFilter<LeveledComponentID>()
    7.     .WithStoreEntityQueryInField(ref LevelChangeQuery)
    8.     .ForEach((Entity e, in DynamicBuffer<LeveledComponentID> IDs) =>
    9.     {
    10.         ref var dataBlob = ref dataAsset.Value;
    11.         for (int i = 0, len = IDs.Length; i < len; i++)
    12.         {
    13.             var id_Lv = IDs[i];
    14.             var locator = dataBlob.GetLocatorByID(id_Lv.ID);
    15.             var cType = locator.ComponentType();
    16.             unsafe
    17.             {
    18.                 entityMgrCache.SetComponentDataRaw(e, locator.TypeIndex, dataBlob.GetDataRaw(locator, id_Lv.Level).UnsafePtr, locator.DataSize);
    19. //Data Type is unknow when coding this system, so pointer and TypeIndex must be used
    20.             }
    21.             //entityMgrCache.SetComponentLevelRaw(e, ref dataBlob, locator, id_Lv.Level);
    22.         }
    23.     }).Run();
    24.     //}).ScheduleParallel(); //Cannot ScheduleParallel Needs EntityCommandBuffer.ParallelWriter.SetComponentDataRaw
    25.  
    This kind of Data management system need more general version of SetComponentDataRaw
     
  6. FoodFish_

    FoodFish_

    Joined:
    May 3, 2018
    Posts:
    58
    +1 for SetComponentDataRaw. Would like to set a component's value using ComponentType or TypeIndex. It would also be nice if EntityCommandBuffer.UnsafeSetComponent was exposed.