Skip to content

Commit

Permalink
Generate Events
Browse files Browse the repository at this point in the history
  • Loading branch information
ds5678 committed Sep 14, 2024
1 parent 89b8d31 commit 4fc7e2a
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 6 deletions.
10 changes: 7 additions & 3 deletions Il2CppInterop.Generator/Contexts/FieldRewriteContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ private string UnmangleFieldName(FieldDefinition field, GeneratorOptions options

if (!field.Name.IsObfuscated(options))
{
if (!field.Name.IsInvalidInSource())
return field.Name!;
return field.Name.FilterInvalidInSourceChars();
string name = !field.Name.IsInvalidInSource() ? field.Name! : field.Name.FilterInvalidInSourceChars();
while (field.DeclaringType!.Events.Any(e => e.Name == name)
|| field.DeclaringType!.Fields.Any(f => f.Name == name && f != field))
{
name += "_"; // Backing fields for events have the same name as the event.
}
return name;
}

if (renamedFieldCounts == null) throw new ArgumentNullException(nameof(renamedFieldCounts));
Expand Down
9 changes: 6 additions & 3 deletions Il2CppInterop.Generator/Extensions/StringEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,11 @@ public static string FilterInvalidInSourceChars(this Utf8String? str)
return str?.Value.FilterInvalidInSourceChars() ?? "";
}

public static bool IsInvalidInSource(this string str)
public static bool IsInvalidInSource([NotNullWhen(true)] this string? str)
{
if (str is null)
return false;

for (var i = 0; i < str.Length; i++)
{
var it = str[i];
Expand All @@ -73,9 +76,9 @@ public static bool IsInvalidInSource(this string str)
return false;
}

public static bool IsInvalidInSource(this Utf8String? str)
public static bool IsInvalidInSource([NotNullWhen(true)] this Utf8String? str)
{
return IsInvalidInSource(str?.Value ?? "");
return IsInvalidInSource(str?.Value);
}

public static bool IsObfuscated([NotNullWhen(true)] this string? str, GeneratorOptions options)
Expand Down
60 changes: 60 additions & 0 deletions Il2CppInterop.Generator/Passes/Pass71GenerateEvents.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using AsmResolver.DotNet;
using Il2CppInterop.Generator.Contexts;
using Il2CppInterop.Generator.Extensions;

namespace Il2CppInterop.Generator.Passes;

public static class Pass71GenerateEvents
{
public static void DoPass(RewriteGlobalContext context)
{
foreach (var assemblyContext in context.Assemblies)
foreach (var typeContext in assemblyContext.Types)
{
var type = typeContext.OriginalType;
var eventCountsByName = new Dictionary<string, int>();

foreach (var oldEvent in type.Events)
{
var unmangledEventName = UnmangleEventName(assemblyContext, oldEvent, typeContext.NewType, eventCountsByName);

var eventType = assemblyContext.RewriteTypeRef(oldEvent.EventType?.ToTypeSignature());
var @event = new EventDefinition(unmangledEventName, oldEvent.Attributes, eventType.ToTypeDefOrRef());

typeContext.NewType.Events.Add(@event);

@event.SetSemanticMethods(
oldEvent.AddMethod is null ? null : typeContext.GetMethodByOldMethod(oldEvent.AddMethod).NewMethod,
oldEvent.RemoveMethod is null ? null : typeContext.GetMethodByOldMethod(oldEvent.RemoveMethod).NewMethod,
oldEvent.FireMethod is null ? null : typeContext.GetMethodByOldMethod(oldEvent.FireMethod).NewMethod);
}
}
}

private static string UnmangleEventName(AssemblyRewriteContext assemblyContext, EventDefinition @event,
ITypeDefOrRef declaringType, Dictionary<string, int> countsByBaseName)
{
if (assemblyContext.GlobalContext.Options.PassthroughNames ||
!@event.Name.IsObfuscated(assemblyContext.GlobalContext.Options)) return @event.Name!;

var baseName = "event_" + assemblyContext.RewriteTypeRef(@event.EventType?.ToTypeSignature()).GetUnmangledName(@event.DeclaringType);

countsByBaseName.TryGetValue(baseName, out var index);
countsByBaseName[baseName] = index + 1;

var unmangleEventName = baseName + "_" + index;

if (assemblyContext.GlobalContext.Options.RenameMap.TryGetValue(
declaringType.GetNamespacePrefix() + "." + declaringType.Name + "::" + unmangleEventName, out var newNameByType))
{
unmangleEventName = newNameByType;
}
else if (assemblyContext.GlobalContext.Options.RenameMap.TryGetValue(
declaringType.GetNamespacePrefix() + "::" + unmangleEventName, out var newName))
{
unmangleEventName = newName;
}

return unmangleEventName;
}
}
25 changes: 25 additions & 0 deletions Il2CppInterop.Generator/Passes/Pass80UnstripMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ public static void DoPass(RewriteGlobalContext context)
var property = GetOrCreateProperty(unityMethod, newMethod);
property.SetMethod = newMethod;
}
else if (unityMethod.IsAddMethod)
{
var @event = GetOrCreateEvent(unityMethod, newMethod);
@event.AddMethod = newMethod;
}
else if (unityMethod.IsRemoveMethod)
{
var @event = GetOrCreateEvent(unityMethod, newMethod);
@event.RemoveMethod = newMethod;
}

var paramsMethod = context.CreateParamsMethod(unityMethod, newMethod, imports,
type => ResolveTypeInNewAssemblies(context, type, imports));
Expand Down Expand Up @@ -171,6 +181,21 @@ private static PropertyDefinition GetOrCreateProperty(MethodDefinition unityMeth
return newProperty;
}

private static EventDefinition GetOrCreateEvent(MethodDefinition unityMethod, MethodDefinition newMethod)
{
var unityEvent =
unityMethod.DeclaringType!.Events.Single(
it => it.AddMethod == unityMethod || it.RemoveMethod == unityMethod);
var newEvent = newMethod.DeclaringType!.Events.SingleOrDefault(it => it.Name == unityEvent.Name);
if (newEvent == null)
{
newEvent = new EventDefinition(unityEvent.Name, unityEvent.Attributes, newMethod.Signature!.ParameterTypes.Single().ToTypeDefOrRef());
newMethod.DeclaringType.Events.Add(newEvent);
}

return newEvent;
}

internal static TypeSignature? ResolveTypeInNewAssemblies(RewriteGlobalContext context, TypeSignature? unityType,
RuntimeAssemblyReferences imports)
{
Expand Down
5 changes: 5 additions & 0 deletions Il2CppInterop.Generator/Runners/InteropAssemblyGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ public void Run(GeneratorOptions options)
Pass70GenerateProperties.DoPass(rewriteContext);
}

using (new TimingCookie("Creating events"))
{
Pass71GenerateEvents.DoPass(rewriteContext);
}

if (options.UnityBaseLibsDir != null)
{
using (new TimingCookie("Unstripping types"))
Expand Down

0 comments on commit 4fc7e2a

Please sign in to comment.