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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Trying to store a String in a blittable format

Discussion in 'Entity Component System' started by mikejoye, Aug 8, 2018.

  1. mikejoye

    mikejoye

    Joined:
    Apr 10, 2018
    Posts:
    6
    I have a component called UserAction like this:
    Code (CSharp):
    1. public struct UserAction : IComponentData
    2. {
    3.      public String Name;  
    4. }
    I keep on getting the error:
    is an IComponentData, and thus must be blittable (No managed object is allowed on the struct)
    when I run this code:
    Code (CSharp):
    1. World.Active.GetOrCreateManager<EntityManager>).CreateArchetype(ComponentType.Create<UserAction>());
    I have tried :
    Code (CSharp):
    1. public struct UserAction : IComponentData
    2. {
    3.      public byte[] Name;
    4. }
    and
    Code (CSharp):
    1. public struct UserAction : IComponentData
    2. {
    3.         public NativeArray<byte> Name;      
    4. }
    but i get the same error every time I try to create an EntityArchetype.
    How do you store Strings into a blittable format so we can use them
     
  2. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    Right now, you can't store strings or containers (neither managed C# nor the new NativeContainers) in an IComponentData.

    You can store non-blittable reference types in ISharedComponentData, but you won't be able to pass an ISharedComponentData with non-blittable types to a Job, and definitely not a Burst-enabled Job.

    I've heard they're working on a solution for containers and strings maybe in 2018.3/2019.1, but for now, I recommend a string table ID or hash, with the lookup table or dictionary attached to a system, and accessible on the main thread.
     
  3. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,624
    The question is why do you need a string on IComponentData

    While some type of support will come eventually, it's usually a sign your architecture is poorly designed.

    Use Enums
     
  4. mikejoye

    mikejoye

    Joined:
    Apr 10, 2018
    Posts:
    6
    I really like your idea about string table, and just storing the pointer to the value with in the string table.
     
  5. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,558
    Unless you have predefined strings you can do as above.
    Or, in case you have variable strings, you can create ASCII equivalent as hash table/array, storing each character in array of bytes.
     
  6. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    I was using BitConverter to change string to int but I got too few characters in one int for my use and finally gave up. If your string is just 4 character max that might be viable. Anyway in my case I only need to equality compare the string with the one in mono world so my work around is .GetHashCode on it so that the whole string become whatever int.
     
  7. jamiebrynes

    jamiebrynes

    Joined:
    Sep 12, 2017
    Posts:
    18
    I've used the pointer to a resource strategy before and it has worked pretty good (Github Gist link). There are a few gotchas however:

    1. If you make the resource allocator general enough, you can cause memory leaks by never releasing data that is no longer pointed to (that is, you have to free the memory when you are done with it).
    2. It does break cache line continuity meaning you do take a performance hit
    3. It still won't work in jobs.

    But it does the trick for simple use cases.
     
    mikejoye likes this.
  8. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    335
    Sidestepping from the main question, you probably want to use Enums instead of Strings to define user actions.
     
  9. mikejoye

    mikejoye

    Joined:
    Apr 10, 2018
    Posts:
    6
    Enums are useful when you have predefined set of items, since adding additional Enums at runtime is not easy task. Our project supports the addition of UserAction and many other things at runtime from external assemblies. The Name property is really used as property that synced up to the UI display, and must go thru our localization system so that value is displayed in the users native language. A Enum will not server us any use, but a int that points to string in a table of strings would be more useful(similar to how strings are handle in OpenXML format).

    one thing we found that was useful to use Byte[] which System.Byte is good for job system.
     
    Last edited: Aug 9, 2018