106 lines
3.4 KiB
C#
Raw Normal View History

2025-10-22 10:20:34 +08:00
using System;
using System.Collections.Generic;
using System.Text;
namespace UnityFileApi
{
public struct ExternalReference
{
public string Path;
public string Guid;
public ExternalReferenceType Type;
}
public class SerializedFile : IDisposable
{
Lazy<List<ExternalReference>> m_ExternalReferences;
Lazy<ObjectInfo[]> m_Objects;
Dictionary<IntPtr, TypeTreeNode> m_TypeTreeCache = new Dictionary<IntPtr, TypeTreeNode>();
internal SerializedFileHandle m_Handle;
public IReadOnlyList<ExternalReference> ExternalReferences => m_ExternalReferences.Value.AsReadOnly();
public IReadOnlyList<ObjectInfo> Objects => Array.AsReadOnly(m_Objects.Value);
internal SerializedFile()
{
m_ExternalReferences = new Lazy<List<ExternalReference>>(GetExternalReferences);
m_Objects = new Lazy<ObjectInfo[]>(GetObjects);
}
public TypeTreeNode GetTypeTreeRoot(long objectId)
{
var r = DllWrapper.GetTypeTree(m_Handle, objectId, out var typeTreeHandle);
UnityFileSystem.HandleErrors(r);
if (m_TypeTreeCache.TryGetValue(typeTreeHandle.Handle, out var node))
{
return node;
}
node = new TypeTreeNode(typeTreeHandle, 0);
m_TypeTreeCache.Add(typeTreeHandle.Handle, node);
return node;
}
public TypeTreeNode GetRefTypeTypeTreeRoot(string className, string namespaceName, string assemblyName)
{
var r = DllWrapper.GetRefTypeTypeTree(m_Handle, className, namespaceName, assemblyName, out var typeTreeHandle);
UnityFileSystem.HandleErrors(r);
if (m_TypeTreeCache.TryGetValue(typeTreeHandle.Handle, out var node))
{
return node;
}
node = new TypeTreeNode(typeTreeHandle, 0);
m_TypeTreeCache.Add(typeTreeHandle.Handle, node);
return node;
}
private List<ExternalReference> GetExternalReferences()
{
var r = DllWrapper.GetExternalReferenceCount(m_Handle, out var count);
UnityFileSystem.HandleErrors(r);
var externalReferences = new List<ExternalReference>(count);
var path = new StringBuilder(512);
var guid = new StringBuilder(32);
for (var i = 0; i < count; ++i)
{
DllWrapper.GetExternalReference(m_Handle, i, path, path.Capacity, guid, out var externalReferenceType);
UnityFileSystem.HandleErrors(r);
externalReferences.Add(new ExternalReference() { Path = path.ToString(), Guid = guid.ToString(), Type = externalReferenceType });
}
return externalReferences;
}
private ObjectInfo[] GetObjects()
{
var r = DllWrapper.GetObjectCount(m_Handle, out var count);
UnityFileSystem.HandleErrors(r);
if (count == 0)
return null;
var objs = new ObjectInfo[count];
DllWrapper.GetObjectInfo(m_Handle, objs, count);
UnityFileSystem.HandleErrors(r);
return objs;
}
public void Dispose()
{
if (m_Handle != null && !m_Handle.IsInvalid)
{
m_Handle.Dispose();
}
}
}
}