Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

DeserializeSharedComponents hashcode problem

Discussion in 'Entity Component System' started by threedots1, Nov 7, 2019.

  1. threedots1

    threedots1

    Joined:
    Oct 9, 2014
    Posts:
    88
    I'm running into assertion errors when trying to deserialize my world.

    I have two different types of shared component data that can both have values of 0,0. One is an ID struct, the other is a Sector struct. Due to the way the deserializer is written, when it creates hash codes for these they both equal 0. This causes the deserialization to bomb out due to an assertion failure.

    Code (CSharp):
    1.  
    2. public static unsafe int DeserializeSharedComponents(EntityManager entityManager, BinaryReader reader)
    3. {
    4.     int storedVersion = reader.ReadInt();
    5.     if (storedVersion != CurrentFileFormatVersion)
    6.     {
    7.         throw new ArgumentException(
    8.             $"Attempting to read a entity scene stored in an old file format version (stored version : {storedVersion}, current version : {CurrentFileFormatVersion})");
    9.     }
    10.  
    11.     int numSharedComponents = reader.ReadInt();
    12.  
    13.     for (int i = 0; i < numSharedComponents; ++i)
    14.     {
    15.         SharedComponentRecord record = new SharedComponentRecord();
    16.         reader.ReadBytes(&record, sizeof(SharedComponentRecord));
    17.  
    18.         var buffer = new byte[record.ComponentSize];
    19.         reader.ReadBytes(UnsafeUtility.AddressOf(ref buffer[0]), record.ComponentSize);
    20.  
    21.         var typeIndex = TypeManager.GetTypeIndexFromStableTypeHash(record.StableTypeHash);
    22.         var data = TypeManager.ConstructComponentFromBuffer(typeIndex, UnsafeUtility.AddressOf(ref buffer[0]));
    23.  
    24.         // TODO: this recalculation should be removed once we merge the NET_DOTS and non NET_DOTS hashcode calculations
    25.         var hashCode = TypeManager.GetHashCode(data, typeIndex); // record.hashCode;
    26.         int index = entityManager.ManagedComponentStore.InsertSharedComponentAssumeNonDefault(typeIndex, hashCode, data);
    27.         Assert.AreEqual(i + 1, index);
    28.     }
    29.  
    30.     return numSharedComponents;
    31. }
    32.  
    I can't write custom HashCode functions for the different component types to offset their values because it calls an internal GetHashCode function.

    Has this been changed in the upcoming release?
     
  2. threedots1

    threedots1

    Joined:
    Oct 9, 2014
    Posts:
    88
    Looks like it isn't entities with similar hash codes causing the problem. I removed the other shared component type with 0 for values and it didn't fix the problem.

    Digging deeper into the code it looks like the TypeInfo saved for my blittable SCD always has a SizeInChunk of 0. When deserializing the SizeInChunk value is used to reconstruct the SCD, but as it always returns 0, all my SCDs return values of 0 and deserializing fails.
     
  3. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,753
    Can you post the actual exception?
     
  4. threedots1

    threedots1

    Joined:
    Oct 9, 2014
    Posts:
    88
     
  5. threedots1

    threedots1

    Joined:
    Oct 9, 2014
    Posts:
    88
    rider64_RQiKSxf2O5.png
    This pic shows the SCD going in during serialization. Size of 8 (2 uints)

    rider64_YWPC8TCk7Q.png
    This shows the TypeInfo retrieved while deserializing the SCD. The SizeInChunk value is used to perform the MemCpy.
    The tinfo in the debugger shows IsZeroSized == true and SizeInChunk == 0.
     
  6. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,753
    Oh I've seen this before but it was ages ago so I can't exactly remember solution and I'm out atm so can't check but...

    Do you have proxies setup for your shared component datas? -edit- this is only something for
    SerializeUtilityHybrid
     
    Last edited: Nov 8, 2019
  7. threedots1

    threedots1

    Joined:
    Oct 9, 2014
    Posts:
    88
    No, I don't. I'm guessing I need to describe how to serialize the SCD? Or at least describe how to deserialize, as the serialization seems to be working fine.