TypeHash
Produces a stable type hash for a Type based on its layout in memory and how that memory should be interpreted.
Read time 2 minutesLast updated a day ago
Definition
- Type: Class
- Namespace: Unity.Entities
- Assembly: UnityEngine.EntitiesModule
public class TypeHash
Remarks
This hash is NOT expected to remain the same across versions.
You can rename field members and this hash isn't affected. However, if a field's type changes, this hash changes, because the interpretation of the underlying memory will have contextually changed.
The purpose of the stable type hash is to provide a version linking serialized component data to its runtime representation.
As such, the type hash has a few requirements:
-
R0: TypeHashes apply only to types that Unity.Entities serializes. The internals of a UnityEngine.Object reference contained in a component mustn't have an effect on the type hash. You can safely change the internals of the UnityEngine.Object reference because they're serialized outside of Unity.Entities.
-
R1: Types with the same data layout but are different types should have different hashes.
-
R2: If a type's data layout changes, so should the type hash. This includes:
-
A nested field's data layout changes (for example, a new member added)
-
FieldOffsets, explicit size, or pack alignment are changed
-
Different types of the same width swap places (for example if a uint swaps with an int)
-
Note: Unity can't detect if fields of the same type swap (for example, mInt1 swaps with mInt2) This is a semantic difference which you should increase your component [TypeVersion(1)] attribute. You shouldn't try to hash field names to handle this, because you can't control all field names. Also, field names have no effect serialization and doesn't affect hashes.
-
R3: You should version the hash in case the semantics of a type change, but the data layout is unchanged
-
R4: DOTS Runtime relies on hashes generated from the Editor (used in serialized data) and hashes generated during compilation. These hashes must match. This rule exists because of the following:
-
-
Tiny swapa out assemblies for 'tiny' versions, which means you should avoid any hashing using the AssemblyName or handle it specially for the known swapped assemblies.
-
This means you should avoid Type.AssemblyQualifiedName in hashes, but as well, closed-form generic types include the assembly qualified name for GenericArguments in Type.FullName which causes issues. For example, @@typeof(ComponentWithGeneric.GenericField).FullName == Unity.Entities.ComponentWithGeneric.GenericField@@10, Culture=neutral, PublicKeyToken=b77a5c561934e089`
-
System.Reflection and Mono.Cecil provide different Type names (they use a different format). Generating hashes from System.Reflection to match hashes using Mono.Cecil must account for this difference.
Static Methods
Method | Description |
|---|---|
| CalculateMemoryOrdering | Calculates a MemoryOrdering for the input type. |
| CalculateStableTypeHash | Calculates a stable type hash for the input type. |
| CombineFNV1A64 | Combines a FNV1A64 hash with a value. |
| FNV1A64 | Generates a FNV1A64 hash. |