feat(sdk): migrate to EventBus 2.0

Replace the legacy EventBase runtime with generated multi-bus bindings and explicit scheduling. Migrate app, data, network, demo, and mod consumers; add generated network-event registration and owner-scoped mod content overrides.
This commit is contained in:
2026-08-26 01:15:48 +08:00
parent 67d32795c4
commit ad5a7b68a3
129 changed files with 5071 additions and 5584 deletions
@@ -37,7 +37,6 @@ namespace ShrinkShared.CodeGen
try
{
InjectEventBusAutoRegister(module);
InjectShrinkCommandRegistry(module);
InjectShrinkNetworkRegistry(module);
InjectShrinkAppRegistry(module);
@@ -75,56 +74,6 @@ namespace ShrinkShared.CodeGen
AddAssemblyTypeArrayAttribute(module, registryCtor, subscriberTypes);
}
private void InjectEventBusAutoRegister(ModuleDefinition module)
{
var subscriberType = FindType(module, "ShrinkEventBus.EventBusSubscriberAttribute", "ShrinkEventBus.Runtime");
var eventBusType = FindType(module, "ShrinkEventBus.EventBus", "ShrinkEventBus.Runtime");
var subscribeAttributeType = FindType(module, "ShrinkEventBus.EventSubscribeAttribute", "ShrinkEventBus.Runtime");
var staticRegistryCtor = FindTypeArrayConstructor(module,
"ShrinkEventBus.EventBusStaticRegistryAttribute",
"ShrinkEventBus.Runtime");
if (subscriberType == null || eventBusType == null)
return;
var eventBusTypeDef = eventBusType.Resolve();
var autoRegisterMethod = eventBusTypeDef?.Methods.FirstOrDefault(method =>
method.Name == "AutoRegister" &&
method.IsStatic &&
method.Parameters.Count == 1);
var unregisterMethod = eventBusTypeDef?.Methods.FirstOrDefault(method =>
method.Name == "UnregisterInstance" &&
method.IsStatic &&
method.Parameters.Count == 1);
if (autoRegisterMethod == null || unregisterMethod == null)
return;
var autoRegisterMethodRef = module.ImportReference(autoRegisterMethod);
var unregisterMethodRef = module.ImportReference(unregisterMethod);
foreach (var type in module.Types)
{
if (!HasAttribute(type, subscriberType) || !InheritsFromMonoBehaviour(type))
continue;
if (subscribeAttributeType != null && !HasInstanceSubscribeMethod(type, subscribeAttributeType))
continue;
InjectAutoRegister(type, module, autoRegisterMethodRef);
InjectAutoUnregister(type, module, unregisterMethodRef);
}
if (subscribeAttributeType != null && staticRegistryCtor != null)
{
var staticSubscriberTypes = module.Types
.Where(type => HasAttribute(type, subscriberType))
.Where(type => type.Methods.Any(method => method.IsStatic && HasAttribute(method, subscribeAttributeType)))
.Select(type => module.ImportReference(type))
.ToArray();
if (staticSubscriberTypes.Length > 0)
AddAssemblyTypeArrayAttribute(module, staticRegistryCtor, staticSubscriberTypes);
}
}
private void InjectShrinkNetworkRegistry(ModuleDefinition module)
{
var messageAttributeType = FindType(module, "ShrinkNetwork.ShrinkNetworkMessageAttribute", "ShrinkNetwork.Runtime");
@@ -180,164 +129,6 @@ namespace ShrinkShared.CodeGen
return provider.CustomAttributes.Any(attribute => attribute.AttributeType.FullName == expectedAttributeType.FullName);
}
private static bool HasInstanceSubscribeMethod(TypeDefinition type, TypeReference subscribeAttributeType)
{
var current = type;
while (current != null && current.Name != "MonoBehaviour")
{
if (current.Methods.Any(method => !method.IsStatic && HasAttribute(method, subscribeAttributeType)))
return true;
var baseTypeRef = current.BaseType;
if (baseTypeRef == null)
return false;
TypeDefinition? resolvedBase;
try
{
resolvedBase = baseTypeRef.Resolve();
}
catch
{
return true;
}
if (resolvedBase == null)
return true;
current = resolvedBase;
}
return false;
}
private static bool InheritsFromMonoBehaviour(TypeDefinition type)
{
var current = type.BaseType;
while (current != null)
{
if (current.Name == "MonoBehaviour")
return true;
try
{
current = current.Resolve()?.BaseType;
}
catch
{
break;
}
}
return false;
}
private static void InjectAutoRegister(TypeDefinition type, ModuleDefinition module, MethodReference autoRegisterMethodRef)
{
var awake = type.Methods.FirstOrDefault(method => method.Name == "Awake" && !method.IsStatic);
if (awake == null)
{
var baseAwakeRef = FindBaseMethodReference(type, "Awake", module);
if (baseAwakeRef != null)
{
awake = new MethodDefinition("Awake",
MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual,
module.TypeSystem.Void);
var il = awake.Body.GetILProcessor();
il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
il.Emit(Mono.Cecil.Cil.OpCodes.Call, baseAwakeRef);
il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
il.Emit(Mono.Cecil.Cil.OpCodes.Call, autoRegisterMethodRef);
il.Emit(Mono.Cecil.Cil.OpCodes.Ret);
type.Methods.Add(awake);
return;
}
awake = new MethodDefinition("Awake",
MethodAttributes.Private | MethodAttributes.HideBySig,
module.TypeSystem.Void);
var retIl = awake.Body.GetILProcessor();
retIl.Emit(Mono.Cecil.Cil.OpCodes.Ret);
type.Methods.Add(awake);
}
var processor = awake.Body.GetILProcessor();
var instructions = new List<Mono.Cecil.Cil.Instruction>
{
processor.Create(Mono.Cecil.Cil.OpCodes.Ldarg_0),
processor.Create(Mono.Cecil.Cil.OpCodes.Call, autoRegisterMethodRef),
processor.Create(Mono.Cecil.Cil.OpCodes.Nop)
};
instructions.Reverse();
instructions.ForEach(instruction => processor.Body.Instructions.Insert(0, instruction));
}
private static void InjectAutoUnregister(TypeDefinition type, ModuleDefinition module, MethodReference unregisterMethodRef)
{
var onDestroy = type.Methods.FirstOrDefault(method => method.Name == "OnDestroy" && !method.IsStatic);
if (onDestroy == null)
{
var baseOnDestroyRef = FindBaseMethodReference(type, "OnDestroy", module);
if (baseOnDestroyRef != null)
{
onDestroy = new MethodDefinition("OnDestroy",
MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual,
module.TypeSystem.Void);
var il = onDestroy.Body.GetILProcessor();
il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
il.Emit(Mono.Cecil.Cil.OpCodes.Call, unregisterMethodRef);
il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
il.Emit(Mono.Cecil.Cil.OpCodes.Call, baseOnDestroyRef);
il.Emit(Mono.Cecil.Cil.OpCodes.Ret);
type.Methods.Add(onDestroy);
return;
}
onDestroy = new MethodDefinition("OnDestroy",
MethodAttributes.Private | MethodAttributes.HideBySig,
module.TypeSystem.Void);
var retIl = onDestroy.Body.GetILProcessor();
retIl.Emit(Mono.Cecil.Cil.OpCodes.Ret);
type.Methods.Add(onDestroy);
}
var processor = onDestroy.Body.GetILProcessor();
var instructions = new List<Mono.Cecil.Cil.Instruction>
{
processor.Create(Mono.Cecil.Cil.OpCodes.Ldarg_0),
processor.Create(Mono.Cecil.Cil.OpCodes.Call, unregisterMethodRef),
processor.Create(Mono.Cecil.Cil.OpCodes.Nop)
};
instructions.Reverse();
instructions.ForEach(instruction => processor.Body.Instructions.Insert(0, instruction));
}
private static MethodReference? FindBaseMethodReference(TypeDefinition type, string methodName, ModuleDefinition module)
{
try
{
var baseTypeRef = type.BaseType;
while (baseTypeRef != null)
{
var baseTypeDef = baseTypeRef.Resolve();
if (baseTypeDef == null)
break;
var method = baseTypeDef.Methods.FirstOrDefault(candidate =>
candidate.Name == methodName && !candidate.IsStatic && candidate.IsVirtual);
if (method != null)
return module.ImportReference(method);
baseTypeRef = baseTypeDef.BaseType;
}
}
catch
{
}
return null;
}
private static void AddAssemblyTypeArrayAttribute(ModuleDefinition module, MethodReference ctor, TypeReference[] types)
{
var attribute = new CustomAttribute(ctor);