public static bool IsSupported(TypeManager.TypeInfo info, out string notSupportedReason) { if (info.Category != TypeManager.TypeCategory.BufferData && info.Category != TypeManager.TypeCategory.ComponentData) { notSupportedReason = $"Persisting components need to be either ComponentData or BufferElementData. Type: {ComponentType.FromTypeIndex(info.TypeIndex).ToString()}"; return(false); } if (info.EntityOffsetCount > 0) { notSupportedReason = $"Persisting components with Entity References is not supported. Type: {ComponentType.FromTypeIndex(info.TypeIndex).ToString()}"; return(false); } if (info.BlobAssetRefOffsetCount > 0) { notSupportedReason = $"Persisting components with BlobAssetReferences is not supported. Type: {ComponentType.FromTypeIndex(info.TypeIndex).ToString()}"; return(false); } if (TypeManager.IsManagedComponent(info.TypeIndex)) { notSupportedReason = $"Persisting managed components supported. Type: {ComponentType.FromTypeIndex(info.TypeIndex).ToString()}"; return(false); } notSupportedReason = ""; return(true); }
private static unsafe void ClearEntityReferences(TypeManager.TypeInfo typeInfo, void *component, int baseOffset = 0) { if (!TypeManager.HasEntityReferences(typeInfo.TypeIndex)) { return; } for (var i = 0; i < typeInfo.EntityOffsetCount; i++) { var offset = typeInfo.EntityOffsets[i].Offset + baseOffset; *(Entity *)((byte *)component + offset) = Entity.Null; } }
private static void ValidateTypeForSerialization(TypeManager.TypeInfo typeInfo) { // Shared Components are expected to be handled specially and are not requiredto be blittable if (typeInfo.Category == TypeManager.TypeCategory.ISharedComponentData) { return; } if (!typeInfo.IsSerializable) { throw new ArgumentException($"Blittable component type '{TypeManager.GetType(typeInfo.TypeIndex)}' contains a (potentially nested) pointer field. " + $"Serializing bare pointers will likely lead to runtime errors. Remove this field and consider serializing the data " + $"it points to another way such as by using a BlobAssetReference or a [Serializable] ISharedComponent. If for whatever " + $"reason the pointer field should in fact be serialized, add the [ChunkSerializable] attribute to your type to bypass this error."); } }
public unsafe void Add(TypeManager.TypeInfo typeInfo) { if (m_TypeInfo[typeInfo.TypeIndex & TypeManager.ClearFlagsMask].StableTypeHash != 0) { return; } m_TypeInfo[typeInfo.TypeIndex & TypeManager.ClearFlagsMask] = new Layout { ElementSize = typeInfo.ElementSize, EntityOffsetCount = typeInfo.EntityOffsetCount, StableTypeHash = typeInfo.StableTypeHash, EntityOffsetPosition = m_EntityOffsets.Length }; fixed(TypeManager.EntityOffsetInfo *offsetInfo = typeInfo.EntityOffsets) { m_EntityOffsets.AddRange(offsetInfo, typeInfo.EntityOffsetCount * sizeof(TypeManager.EntityOffsetInfo)); } }
public static unsafe void SerializeWorld(EntityManager entityManager, BinaryWriter writer, out int[] sharedComponentsToSerialize, NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapInfos) { Dictionary <EntityArchetype, int> dictionary; EntityArchetype[] archetypeArray; writer.Write(CurrentFileFormatVersion); GetAllArchetypes(entityManager.ArchetypeManager, out dictionary, out archetypeArray); HashSet <int> source = new HashSet <int>(); EntityArchetype[] archetypeArray2 = archetypeArray; int index = 0; while (index < archetypeArray2.Length) { EntityArchetype archetype = archetypeArray2[index]; int num4 = 0; while (true) { if (num4 >= archetype.Archetype.TypesCount) { index++; break; } source.Add(archetype.Archetype.Types[num4].TypeIndex); num4++; } } var typeArray = (from t in source.Select(delegate(int index) { Type type = TypeManager.GetType(index); string assemblyQualifiedName = TypeManager.GetType(index).AssemblyQualifiedName; return(new { index = index, type = type, name = assemblyQualifiedName, hash = TypeManager.GetTypeInfo(index).FastEqualityTypeInfo.Hash, asciiName = Encoding.ASCII.GetBytes(assemblyQualifiedName) }); }) orderby t.name select t).ToArray(); int num = typeArray.Sum(t => t.asciiName.Length + 1); writer.Write(typeArray.Length); foreach (var type in typeArray) { writer.Write(type.hash); } writer.Write(num); foreach (var type2 in typeArray) { writer.Write(type2.asciiName); writer.Write((byte)0); } Dictionary <int, int> typeIndexMap = new Dictionary <int, int>(); int num7 = 0; while (true) { if (num7 >= typeArray.Length) { WriteArchetypes(writer, archetypeArray, typeIndexMap); NativeList <BufferPatchRecord> data = new NativeList <BufferPatchRecord>(0x80, Allocator.Temp); int num2 = GenerateRemapInfo(entityManager, archetypeArray, entityRemapInfos); writer.Write(num2); Chunk *chunk = (Chunk *)UnsafeUtility.Malloc(0x3f00L, 0x10, Allocator.Temp); Dictionary <int, int> dictionary3 = new Dictionary <int, int>(); int num8 = 0; while (true) { if (num8 >= archetypeArray.Length) { data.Dispose(); UnsafeUtility.Free((void *)chunk, Allocator.Temp); sharedComponentsToSerialize = new int[dictionary3.Count]; foreach (KeyValuePair <int, int> pair in dictionary3) { sharedComponentsToSerialize[pair.Value - 1] = pair.Key; } return; } Archetype *archetype = archetypeArray[num8].Archetype; Chunk * begin = (Chunk *)archetype->ChunkList.Begin; while (true) { if (begin == archetype->ChunkList.End) { num8++; break; } data.Clear(); UnsafeUtility.MemCpy((void *)chunk, (void *)begin, 0x3f00L); chunk->SharedComponentValueArray = (int *)(chunk + Chunk.GetSharedComponentOffset(archetype->NumSharedComponents)); byte *numPtr = &chunk->Buffer.FixedElementField; EntityRemapUtility.PatchEntities(archetype->ScalarEntityPatches, archetype->ScalarEntityPatchCount, archetype->BufferEntityPatches, archetype->BufferEntityPatchCount, numPtr, chunk->Count, ref entityRemapInfos); int num9 = 0; while (true) { if (num9 >= archetype->TypesCount) { ClearUnusedChunkData(chunk); chunk->ChunkListNode.Next = null; chunk->ChunkListNode.Prev = null; chunk->ChunkListWithEmptySlotsNode.Next = null; chunk->ChunkListWithEmptySlotsNode.Prev = null; chunk->Archetype = (Archetype *)num8; if (archetype->NumManagedArrays != 0) { throw new ArgumentException("Serialization of GameObject components is not supported for pure entity scenes"); } int num15 = 0; while (true) { if (num15 == archetype->NumSharedComponents) { writer.WriteBytes((void *)chunk, 0x3f00); writer.Write(data.Length); if (data.Length > 0) { writer.WriteList <BufferPatchRecord>(data); int num18 = 0; while (true) { if (num18 >= data.Length) { break; } BufferPatchRecord record2 = data[num18]; BufferHeader * headerPtr2 = (BufferHeader *)ref OffsetFromPointer((void *)&begin->Buffer.FixedElementField, record2.ChunkOffset); writer.WriteBytes((void *)headerPtr2->Pointer, record2.AllocSizeBytes); num18++; } } begin = (Chunk *)begin->ChunkListNode.Next; break; } int key = chunk->SharedComponentValueArray[num15]; if (chunk->SharedComponentValueArray[num15] != 0) { int num17; if (dictionary3.TryGetValue(key, out num17)) { chunk->SharedComponentValueArray[num15] = num17; } else { num17 = dictionary3.Count + 1; dictionary3.set_Item(key, num17); chunk->SharedComponentValueArray[num15] = num17; } } num15++; } break; } int num10 = archetype->TypeMemoryOrder[num9]; if ((archetype->Types + num10).IsBuffer) { BufferHeader * headerPtr = (BufferHeader *)OffsetFromPointer((void *)numPtr, archetype->Offsets[num10]); int offset = archetype->SizeOfs[num10]; int count = begin->Count; TypeManager.TypeInfo typeInfo = TypeManager.GetTypeInfo(archetype->Types[num10].TypeIndex); int num14 = 0; while (true) { if (num14 >= count) { break; } if (headerPtr->Pointer != null) { headerPtr->Pointer = null; BufferPatchRecord element = new BufferPatchRecord { ChunkOffset = (int)((long)((headerPtr - numPtr) / 1)), AllocSizeBytes = typeInfo.ElementSize * headerPtr->Capacity }; data.Add(element); } headerPtr = (BufferHeader *)OffsetFromPointer((void *)headerPtr, offset); num14++; } } num9++; } } } } typeIndexMap.set_Item(typeArray[num7].index, num7); num7++; } }
public static uint GetMaskedHash(NativeArray <byte> data, TypeManager.TypeInfo type, PaddingMasks masks, uint seed) { return(GetMaskedHash(data, masks.GetTypeMask(type), seed)); }
private static unsafe void ExtractEntityReferences(NativeList <EntityReferenceRemap> references, TypeManager.TypeInfo typeInfo, EntityManager manager, void *component, int baseOffset = 0) { if (!TypeManager.HasEntityReferences(typeInfo.TypeIndex)) { return; } for (var i = 0; i < typeInfo.EntityOffsetCount; i++) { var offset = typeInfo.EntityOffsets[i].Offset + baseOffset; var target = *(Entity *)((byte *)component + offset); if (!manager.Exists(target)) { continue; } if (!manager.HasComponent <EntityGuid>(target)) { continue; } var guid = manager.GetComponentData <EntityGuid>(target); references.Add(new EntityReferenceRemap { Guid = guid, Offset = offset, TypeHash = typeInfo.StableTypeHash }); } }
internal NativeView GetMaskView(TypeManager.TypeInfo type) => GetMaskView(type.TypeIndex);
public bool IsMasked(TypeManager.TypeInfo type) => IsMasked(type.TypeIndex);
public NativeArray <byte> GetTypeMask(TypeManager.TypeInfo type) => GetTypeMask(type.TypeIndex);