void AddArrayElement(PackedManagedType elementType, int elementIndex, System.Action <BuildChildrenArgs> add) { if (elementType.isArray) { var pointer = m_MemoryReader.ReadPointer(address + (ulong)(elementIndex * m_Snapshot.virtualMachineInformation.pointerSize) + (ulong)m_Snapshot.virtualMachineInformation.arrayHeaderSize); var item = new ArrayPropertyGridItem(m_Owner, m_Snapshot, pointer, m_MemoryReader) { depth = this.depth + 1, type = elementType }; item.OnInitialize(); this.AddChild(item); } else if (elementType.isValueType) { if (elementType.isPrimitive) { var args = new BuildChildrenArgs(); args.parent = this; args.type = elementType; args.address = address + (ulong)(elementIndex * elementType.size) + (ulong)m_Snapshot.virtualMachineInformation.arrayHeaderSize - (ulong)m_Snapshot.virtualMachineInformation.objectHeaderSize; args.memoryReader = new MemoryReader(m_Snapshot); add(args); } else { // this is the container node for the array elements. // if we don't add the container, all fields are simply added to the array node itself. // however, we want each array element being groupped var pointer = address + (ulong)(elementIndex * elementType.size) + (ulong)m_Snapshot.virtualMachineInformation.arrayHeaderSize; var item = new ArrayElementPropertyGridItem(m_Owner, m_Snapshot, pointer, new MemoryReader(m_Snapshot)) { depth = this.depth + 1, type = elementType }; item.Initialize(); this.AddChild(item); pointer = address + (ulong)(elementIndex * elementType.size) + (ulong)m_Snapshot.virtualMachineInformation.arrayHeaderSize - (ulong)m_Snapshot.virtualMachineInformation.objectHeaderSize; var args = new BuildChildrenArgs(); args.parent = item; args.type = elementType; args.address = pointer; args.memoryReader = new MemoryReader(m_Snapshot); add(args); } } else { // address of element var addressOfElement = address + (ulong)(elementIndex * m_Snapshot.virtualMachineInformation.pointerSize) + (ulong)m_Snapshot.virtualMachineInformation.arrayHeaderSize; var pointer = m_MemoryReader.ReadPointer(addressOfElement); if (pointer != 0) { var i = m_Snapshot.FindManagedObjectTypeOfAddress(pointer); if (i != -1) { elementType = m_Snapshot.managedTypes[i]; } } // this is the container node for the reference type. // if we don't add the container, all fields are simply added to the array node itself. // however, we want each array element being groupped var item = new ArrayElementPropertyGridItem(m_Owner, m_Snapshot, addressOfElement, m_MemoryReader) { depth = this.depth + 1, type = elementType }; item.Initialize(); this.AddChild(item); // Only add the actual element fields if the pointer is valid if (pointer != 0) { var args = new BuildChildrenArgs(); args.parent = item; args.type = elementType; args.address = pointer; args.memoryReader = new MemoryReader(m_Snapshot); add(args); } } }
void AddType(PropertyGridItem.BuildChildrenArgs args) { var target = args.parent; var type = args.type; var address = args.address; var reader = args.memoryReader; var addStatic = reader is StaticMemoryReader; var addInstance = !addStatic; if (target.depth > 64) { Debug.LogFormat("recursive reference found? type: {0}", type.name); return; } // Add the base class, if any, to the tree. if (type.isDerivedReferenceType && !type.isArray) { var baseType = m_Snapshot.managedTypes[type.baseOrElementTypeIndex]; var isSystemObject = baseType.managedTypesArrayIndex == m_Snapshot.coreTypes.systemObject; if (!isSystemObject && PackedManagedTypeUtility.HasTypeOrBaseAnyField(m_Snapshot, baseType, !addStatic, addStatic)) { var item = new BaseClassPropertyGridItem(this, m_Snapshot, address, reader) { depth = target.depth + 1, type = baseType }; item.Initialize(); target.AddChild(item); } } // Array if (type.isArray) { // Normally the baseOrElementTypeIndex of an array represents the element type. // If inspecting static generic fields though, there is no element type available for '_EmptyArray'. // class ArrayList<T> // { // static readonly T[] _EmptyArray = new T[0]; // } if (type.baseOrElementTypeIndex == -1) { return; } var pointer = address; var item = new ArrayPropertyGridItem(this, m_Snapshot, pointer, reader) { depth = target.depth + 1, type = type, displayName = type.name, }; item.Initialize(); target.AddChild(item); return; } for (var n = 0; n < type.fields.Length; ++n) { if (type.fields[n].isStatic && !addStatic) { continue; } if (!type.fields[n].isStatic && !addInstance) { continue; } var fieldType = m_Snapshot.managedTypes[type.fields[n].managedTypesArrayIndex]; // Array if (fieldType.isArray) { if (fieldType.baseOrElementTypeIndex == -1) { continue; } var pointer = reader.ReadPointer(address + (ulong)type.fields[n].offset); var item = new ArrayPropertyGridItem(this, m_Snapshot, pointer, new MemoryReader(m_Snapshot)) { depth = target.depth + 1, type = fieldType, displayName = type.fields[n].name }; item.Initialize(); target.AddChild(item); continue; } // Primitive types and types derived from System.Enum if (fieldType.isValueType && (fieldType.isPrimitive || m_Snapshot.IsEnum(fieldType))) { var item = new PrimitiveTypePropertyGridItem(this, m_Snapshot, address + (ulong)type.fields[n].offset, reader) { depth = target.depth + 1, field = type.fields[n] }; item.Initialize(); target.AddChild(item); continue; } // Value types if (fieldType.isValueType) { var item = new ValueTypePropertyGridItem(this, m_Snapshot, address + (ulong)type.fields[n].offset, reader) { depth = target.depth + 1, field = type.fields[n] }; item.Initialize(); target.AddChild(item); continue; } // Reference types //if (fieldType.isPointer) { var item = new ReferenceTypePropertyGridItem(this, m_Snapshot, address + (ulong)type.fields[n].offset, reader) { depth = target.depth + 1, field = type.fields[n] }; item.Initialize(); target.AddChild(item); continue; } } }