mirror of
https://github.com/StarBeat/UnityDependencyAnalyzer.git
synced 2026-03-08 05:35:27 +08:00
196 lines
6.0 KiB
C#
196 lines
6.0 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Text;
|
|||
|
|
|
|||
|
|
namespace UnityFileApi
|
|||
|
|
{
|
|||
|
|
// A TypeTreeNode represents how a property of a serialized object was written to disk.
|
|||
|
|
// See the TextDumper library for an example.
|
|||
|
|
public class TypeTreeNode
|
|||
|
|
{
|
|||
|
|
int m_FirstChildNodeIndex;
|
|||
|
|
int m_NextNodeIndex;
|
|||
|
|
TypeTreeHandle m_Handle;
|
|||
|
|
Lazy<List<TypeTreeNode>> m_Children;
|
|||
|
|
Lazy<Type> m_CSharpType;
|
|||
|
|
Lazy<bool> m_hasConstantSize;
|
|||
|
|
|
|||
|
|
// The type of the property (basic type like int or float or class names for objects)
|
|||
|
|
public readonly string Type;
|
|||
|
|
// The name of the property (e.g. m_IndexBuffer for a Mesh or m_Width for a Texture)
|
|||
|
|
public readonly string Name;
|
|||
|
|
// The size of the property (for basic types only, otherwise -1)
|
|||
|
|
public readonly int Size;
|
|||
|
|
// The offset of the property (mostly useless).
|
|||
|
|
public readonly int Offset;
|
|||
|
|
// Flags used for different things (e.g. field is an array, data alignment, etc.)
|
|||
|
|
public readonly TypeTreeFlags Flags;
|
|||
|
|
public readonly TypeTreeMetaFlags MetaFlags;
|
|||
|
|
|
|||
|
|
// Child nodes container.
|
|||
|
|
public List<TypeTreeNode> Children => m_Children.Value;
|
|||
|
|
|
|||
|
|
// True if the field has no child.
|
|||
|
|
public bool IsLeaf => m_FirstChildNodeIndex == 0;
|
|||
|
|
|
|||
|
|
// True if the field is a basic type. (int, float, char, etc.)
|
|||
|
|
public bool IsBasicType => IsLeaf && Size > 0;
|
|||
|
|
|
|||
|
|
// True if the field is an array.
|
|||
|
|
public bool IsArray => ((int)Flags & (int)TypeTreeFlags.IsArray) != 0;
|
|||
|
|
|
|||
|
|
// True if the field is a ManagedReferenceRegistry
|
|||
|
|
public bool IsManagedReferenceRegistry => ((int)Flags & (int)TypeTreeFlags.IsManagedReferenceRegistry) != 0;
|
|||
|
|
|
|||
|
|
// C# type corresponding to the node type
|
|||
|
|
public Type CSharpType => m_CSharpType.Value;
|
|||
|
|
|
|||
|
|
// True if the node has a constant size (it contains no array or other containers with variable size).
|
|||
|
|
public bool HasConstantSize => m_hasConstantSize.Value;
|
|||
|
|
|
|||
|
|
[ThreadStatic]
|
|||
|
|
static StringBuilder s_NodeType;
|
|||
|
|
[ThreadStatic]
|
|||
|
|
static StringBuilder s_NodeName;
|
|||
|
|
|
|||
|
|
// Properties are required to initialize the ThreadStatic members.
|
|||
|
|
static StringBuilder NodeTypeBuilder
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
if (s_NodeType == null)
|
|||
|
|
{
|
|||
|
|
s_NodeType = new StringBuilder(512);
|
|||
|
|
}
|
|||
|
|
return s_NodeType;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static StringBuilder NodeNameBuilder
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
if (s_NodeName == null)
|
|||
|
|
{
|
|||
|
|
s_NodeName = new StringBuilder(512);
|
|||
|
|
}
|
|||
|
|
return s_NodeName;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
internal TypeTreeNode(TypeTreeHandle typeTreeHandle, int nodeIndex)
|
|||
|
|
{
|
|||
|
|
m_Handle = typeTreeHandle;
|
|||
|
|
|
|||
|
|
var r = DllWrapper.GetTypeTreeNodeInfo(m_Handle, nodeIndex, NodeTypeBuilder, NodeTypeBuilder.Capacity, NodeNameBuilder, NodeNameBuilder.Capacity, out Offset, out Size, out Flags, out MetaFlags, out m_FirstChildNodeIndex, out m_NextNodeIndex);
|
|||
|
|
UnityFileSystem.HandleErrors(r);
|
|||
|
|
|
|||
|
|
Type = NodeTypeBuilder.ToString();
|
|||
|
|
Name = NodeNameBuilder.ToString();
|
|||
|
|
|
|||
|
|
m_Children = new Lazy<List<TypeTreeNode>>(GetChildren);
|
|||
|
|
m_CSharpType = new Lazy<Type>(GetCSharpType);
|
|||
|
|
m_hasConstantSize = new Lazy<bool>(GetHasConstantSize);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
internal List<TypeTreeNode> GetChildren()
|
|||
|
|
{
|
|||
|
|
var children = new List<TypeTreeNode>();
|
|||
|
|
var current = m_FirstChildNodeIndex;
|
|||
|
|
|
|||
|
|
while (current != 0)
|
|||
|
|
{
|
|||
|
|
var child = new TypeTreeNode(m_Handle, current);
|
|||
|
|
children.Add(child);
|
|||
|
|
current = child.m_NextNodeIndex;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return children;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool GetHasConstantSize()
|
|||
|
|
{
|
|||
|
|
if (IsArray || CSharpType == typeof(string))
|
|||
|
|
return false;
|
|||
|
|
|
|||
|
|
foreach (var child in Children)
|
|||
|
|
{
|
|||
|
|
if (!child.HasConstantSize)
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Type GetCSharpType()
|
|||
|
|
{
|
|||
|
|
switch (Type)
|
|||
|
|
{
|
|||
|
|
case "int":
|
|||
|
|
case "SInt32":
|
|||
|
|
case "TypePtr":
|
|||
|
|
return typeof(int);
|
|||
|
|
|
|||
|
|
case "unsigned int":
|
|||
|
|
case "UInt32":
|
|||
|
|
return typeof(uint);
|
|||
|
|
|
|||
|
|
case "float":
|
|||
|
|
return typeof(float);
|
|||
|
|
|
|||
|
|
case "double":
|
|||
|
|
return typeof(double);
|
|||
|
|
|
|||
|
|
case "SInt16":
|
|||
|
|
return typeof(short);
|
|||
|
|
|
|||
|
|
case "UInt16":
|
|||
|
|
return typeof(ushort);
|
|||
|
|
|
|||
|
|
case "SInt64":
|
|||
|
|
return typeof(long);
|
|||
|
|
|
|||
|
|
case "FileSize":
|
|||
|
|
case "UInt64":
|
|||
|
|
return typeof(ulong);
|
|||
|
|
|
|||
|
|
case "SInt8":
|
|||
|
|
return typeof(sbyte);
|
|||
|
|
|
|||
|
|
case "UInt8":
|
|||
|
|
case "char":
|
|||
|
|
return typeof(byte);
|
|||
|
|
|
|||
|
|
case "bool":
|
|||
|
|
return typeof(bool);
|
|||
|
|
|
|||
|
|
case "string":
|
|||
|
|
return typeof(string);
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
{
|
|||
|
|
if (Size == 8)
|
|||
|
|
{
|
|||
|
|
return typeof(long);
|
|||
|
|
}
|
|||
|
|
else if (Size == 4)
|
|||
|
|
{
|
|||
|
|
return typeof(int);
|
|||
|
|
}
|
|||
|
|
else if (Size == 2)
|
|||
|
|
{
|
|||
|
|
return typeof(short);
|
|||
|
|
}
|
|||
|
|
else if (Size == 1)
|
|||
|
|
{
|
|||
|
|
return typeof(sbyte);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return typeof(object);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
throw new Exception($"Unknown type {Type}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|