2025-09-17 16:40:02 -07:00

81 lines
3.2 KiB
C#

using AssetRipper.AssemblyDumper.Types;
using AssetRipper.AssemblyDumper.Utils;
namespace AssetRipper.AssemblyDumper.Passes;
internal static class Pass009_CreateGroups
{
public static void DoPass()
{
foreach ((int id, VersionedList<UniversalClass> list) in SharedState.Instance.ClassInformation)
{
ClassGroup group = CreateClasses(list, id);
SharedState.Instance.ClassGroups.Add(id, group);
}
foreach ((string name, VersionedList<UniversalClass> list) in SharedState.Instance.SubclassInformation)
{
SubclassGroup group = CreateSubclasses(list, name);
SharedState.Instance.SubclassGroups.Add(name, group);
}
}
private static ClassGroup CreateClasses(VersionedList<UniversalClass> loadedClasses, int id)
{
TypeDefinition @interface = InterfaceCreator.CreateEmptyInterface(SharedState.Instance.Module, null, null);
ClassGroup group = new ClassGroup(id, @interface);
CreateTypeDefinitionsAndInitializeGroup(loadedClasses, group);
return group;
}
private static SubclassGroup CreateSubclasses(VersionedList<UniversalClass> loadedClasses, string name)
{
TypeDefinition @interface = InterfaceCreator.CreateEmptyInterface(SharedState.Instance.Module, null, null);
SubclassGroup group = new SubclassGroup(name, @interface);
CreateTypeDefinitionsAndInitializeGroup(loadedClasses, group);
return group;
}
private static void CreateTypeDefinitionsAndInitializeGroup(VersionedList<UniversalClass> loadedClasses, ClassGroupBase group)
{
int nonNullCount = loadedClasses.Values.Count(c => c != null);
if (nonNullCount == 0)
{
throw new ArgumentException("Must have at least one class", nameof(loadedClasses));
}
else if (nonNullCount == 1)
{
KeyValuePair<UnityVersion, UniversalClass?> pair = loadedClasses.Single(c => c.Value != null);
UniversalClass universalClass = pair.Value!;
string typeName = universalClass.Name;
UnityVersion endVersion = loadedClasses.Count == 2 && loadedClasses[1].Value == null ? loadedClasses[1].Key : UnityVersion.MaxVersion;
CreateType(universalClass, pair.Key, endVersion, typeName, group);
}
else
{
for (int i = 0; i < loadedClasses.Count; i++)
{
KeyValuePair<UnityVersion, UniversalClass?> pair = loadedClasses[i];
UnityVersion endVersion = i + 1 < loadedClasses.Count ? loadedClasses[i + 1].Key : UnityVersion.MaxVersion;
UniversalClass? universalClass = pair.Value;
if (universalClass is not null)
{
string typeName = $"{universalClass.Name}_{pair.Key.ToCleanString('_')}";
CreateType(universalClass, pair.Key, endVersion, typeName, group);
}
}
}
group.InitializeHistory(SharedState.Instance.HistoryFile);
}
private static void CreateType(UniversalClass universalClass, UnityVersion startVersion, UnityVersion endVersion, string typeName, ClassGroupBase group)
{
TypeDefinition type = new TypeDefinition(group.Namespace, typeName, TypeAttributes.Public | TypeAttributes.BeforeFieldInit);
SharedState.Instance.Module.TopLevelTypes.Add(type);
GeneratedClassInstance instance = new GeneratedClassInstance(group, universalClass, type, startVersion, endVersion);
group.Instances.Add(instance);
SharedState.Instance.TypesToGroups.Add(type, group);
SharedState.Instance.TypesToInstances.Add(type, instance);
}
}