Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

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.