| | 1 | | // Copyright (c) 2020-2024 dotBunny Inc. |
| | 2 | | // dotBunny licenses this file to you under the BSL-1.0 license. |
| | 3 | | // See the LICENSE file in the project root for more information. |
| | 4 | |
|
| | 5 | | #if !UNITY_DOTSRUNTIME |
| | 6 | |
|
| | 7 | | using System; |
| | 8 | | using System.Text; |
| | 9 | | using UnityEngine.Profiling; |
| | 10 | | using Object = UnityEngine.Object; |
| | 11 | |
|
| | 12 | | namespace GDX.Developer.Reports.Resource.Objects |
| | 13 | | { |
| | 14 | | /// <summary> |
| | 15 | | /// An information storage object for a target <see cref="object" />. |
| | 16 | | /// </summary> |
| | 17 | | /// <exception cref="UnsupportedRuntimeException">Not supported on DOTS Runtime.</exception> |
| | 18 | | public class ObjectInfo : IComparable |
| | 19 | | { |
| | 20 | | /// <summary> |
| | 21 | | /// The fully qualified reflection definition of the <see cref="ObjectInfo" />. |
| | 22 | | /// </summary> |
| | 23 | | public const string TypeDefinition = "GDX.Developer.Reports.Resource.Objects.ObjectInfo,GDX"; |
| | 24 | |
|
| | 25 | | /// <summary> |
| | 26 | | /// The number of copies of the <see cref="Reference" /> object known by Unity. |
| | 27 | | /// </summary> |
| | 28 | | public uint CopyCount; |
| | 29 | |
|
| | 30 | | /// <summary> |
| | 31 | | /// The memory usage of the actual <see cref="Reference" /> object (in bytes). |
| | 32 | | /// </summary> |
| | 33 | | public long MemoryUsage; |
| | 34 | |
|
| | 35 | | /// <summary> |
| | 36 | | /// The name of the <see cref="Reference" /> object. |
| | 37 | | /// </summary> |
| | 38 | | public string Name; |
| | 39 | |
|
| | 40 | | /// <summary> |
| | 41 | | /// A <see cref="TransientReference" /> to the target object. |
| | 42 | | /// </summary> |
| | 43 | | public TransientReference Reference; |
| | 44 | |
|
| | 45 | | /// <summary> |
| | 46 | | /// The total memory usage of the <see cref="Reference" /> object (in bytes). |
| | 47 | | /// </summary> |
| | 48 | | public long TotalMemoryUsage; |
| | 49 | |
|
| | 50 | | /// <summary> |
| | 51 | | /// The cached <see cref="Type" /> of the <see cref="Reference" /> object. |
| | 52 | | /// </summary> |
| | 53 | | public Type Type; |
| | 54 | |
|
| | 55 | | /// <summary> |
| | 56 | | /// Evaluate if the compared <see cref="ObjectInfo" /> utilizes more memory then this one. |
| | 57 | | /// </summary> |
| | 58 | | /// <param name="obj">The <see cref="ObjectInfo" /> to compare against.</param> |
| | 59 | | /// <returns>1 if larger, otherwise 0.</returns> |
| | 60 | | public int CompareTo(object obj) |
| 197962 | 61 | | { |
| 197962 | 62 | | if (!(obj is ObjectInfo info)) |
| 0 | 63 | | { |
| 0 | 64 | | return 0; |
| | 65 | | } |
| | 66 | |
|
| 197962 | 67 | | if (TotalMemoryUsage > info.TotalMemoryUsage) |
| 75077 | 68 | | { |
| 75077 | 69 | | return -1; |
| | 70 | | } |
| | 71 | |
|
| 122885 | 72 | | return 1; |
| 197962 | 73 | | } |
| | 74 | |
|
| | 75 | | /// <summary> |
| | 76 | | /// Create a clone of this object. |
| | 77 | | /// </summary> |
| | 78 | | /// <returns></returns> |
| | 79 | | public virtual ObjectInfo Clone() |
| 0 | 80 | | { |
| 0 | 81 | | return new ObjectInfo |
| | 82 | | { |
| | 83 | | CopyCount = CopyCount, |
| | 84 | | MemoryUsage = MemoryUsage, |
| | 85 | | Name = Name, |
| | 86 | | Reference = Reference, |
| | 87 | | TotalMemoryUsage = TotalMemoryUsage, |
| | 88 | | Type = Type |
| | 89 | | }; |
| 0 | 90 | | } |
| | 91 | |
|
| | 92 | | /// <summary> |
| | 93 | | /// Get additional information about the specific <see cref="Reference" />. |
| | 94 | | /// </summary> |
| | 95 | | /// <returns>A <see cref="string" /> of additional information.</returns> |
| | 96 | | public virtual string GetDetailedInformation(int maximumWidth) |
| 14722 | 97 | | { |
| 14722 | 98 | | return null; |
| 14722 | 99 | | } |
| | 100 | |
|
| | 101 | | /// <summary> |
| | 102 | | /// Populate an <see cref="ObjectInfo" /> from the <paramref name="targetObject" />. Optionally providing an |
| | 103 | | /// <paramref name="reference" /> created prior. |
| | 104 | | /// </summary> |
| | 105 | | /// <param name="targetObject">The <see cref="object" /> which to cache information about.</param> |
| | 106 | | /// <param name="reference">An existing <see cref="TransientReference" /> targeting the <paramref name="targetOb |
| | 107 | | public virtual void Populate(Object targetObject, TransientReference reference = null) |
| 17972 | 108 | | { |
| | 109 | | // Basic info |
| 17972 | 110 | | Name = targetObject.name; |
| 17972 | 111 | | Type = targetObject.GetType(); |
| | 112 | |
|
| | 113 | | // Assign initial memory usage stats |
| 17972 | 114 | | MemoryUsage = Profiler.GetRuntimeMemorySizeLong(targetObject); |
| 17972 | 115 | | TotalMemoryUsage = MemoryUsage; |
| | 116 | |
|
| | 117 | | // Assign or create the transient reference to the target object |
| 17972 | 118 | | Reference = reference != null ? reference : new TransientReference(targetObject); |
| | 119 | |
|
| | 120 | | // It's new, so there's only one. |
| 17972 | 121 | | CopyCount = 1; |
| 17972 | 122 | | } |
| | 123 | |
|
| | 124 | |
|
| | 125 | | public void Output(ResourceReportContext context, StringBuilder builder, bool stripUnicode = true) |
| 18094 | 126 | | { |
| 18094 | 127 | | string typeName = Type.Name.PadRight(context.ObjectTypeWidth); |
| 18094 | 128 | | if (typeName.Length > context.ObjectTypeWidth) |
| 1714 | 129 | | { |
| 1714 | 130 | | typeName = typeName.Substring(0, context.ObjectTypeWidth); |
| 1714 | 131 | | } |
| | 132 | |
|
| 18094 | 133 | | if (stripUnicode) |
| 18094 | 134 | | { |
| 18094 | 135 | | typeName = typeName.StripNonAscii(); |
| 18094 | 136 | | } |
| | 137 | |
|
| 18094 | 138 | | string objectName = Name.PadRight(context.ObjectNameWidth); |
| 18094 | 139 | | if (objectName.Length > context.ObjectNameWidth) |
| 936 | 140 | | { |
| 936 | 141 | | objectName = objectName.Substring(0, context.ObjectNameWidth); |
| 936 | 142 | | } |
| | 143 | |
|
| 18094 | 144 | | if (stripUnicode) |
| 18094 | 145 | | { |
| 18094 | 146 | | objectName = objectName.StripNonAscii(); |
| 18094 | 147 | | } |
| | 148 | |
|
| 18094 | 149 | | string sizeInfo = |
| | 150 | | $"{Localization.GetHumanReadableFileSize(MemoryUsage)} x {CopyCount.ToString()}".PadRight( |
| | 151 | | context.ObjectSizeWidth); |
| 18094 | 152 | | if (sizeInfo.Length > context.ObjectSizeWidth) |
| 0 | 153 | | { |
| 0 | 154 | | sizeInfo = sizeInfo.Substring(0, context.ObjectSizeWidth); |
| 0 | 155 | | } |
| | 156 | |
|
| | 157 | |
|
| | 158 | | // Additional information |
| 18094 | 159 | | string additionalInfo = GetDetailedInformation(context.ObjectInfoWidth); |
| | 160 | |
|
| | 161 | | // Add to builder |
| 18094 | 162 | | builder.AppendLine(additionalInfo != null |
| | 163 | | ? $"{typeName} {objectName} {sizeInfo} {additionalInfo}" |
| | 164 | | : $"{typeName} {objectName} {sizeInfo}"); |
| 18094 | 165 | | } |
| | 166 | | } |
| | 167 | | } |
| | 168 | | #endif // !UNITY_DOTSRUNTIME |