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
@@ -82,10 +82,11 @@ Application.persistentDataPath/Mods
- `[ShrinkMod]` 模组声明
- `ShrinkModBase` 生命周期
- `EventBusSubscriber` 实例自动接入
- `[ShrinkEventSubscriber]` / `[ShrinkSubscribe]` 生成式实例接入 Mod Bus
- `ShrinkCommandSubscriber` 实例命令自动接入
- `ShrinkNetworkSubscriber` 实例网络处理自动接入
- `context.GetRegistry(...)` 注册内容
- `context.RegisterContent(...)` 使用 ModId namespace 注册内容
- `context.OverrideContent(...)` 以显式优先级覆盖已有内容
- `context.RegisterNetworkHandler(...)` 走模组网络抽象层
## 注意
@@ -94,6 +95,7 @@ Application.persistentDataPath/Mods
- 当前模板默认依赖当前仓库根目录下的:
- `ShrinkModFramework.Runtime.csproj`
- `ShrinkEventBus.Runtime.csproj`
- `DotNet/ShrinkEventBus.Generator/ShrinkEventBus.Generator.csproj`(作为 Roslyn analyzer
- `ShrinkCommand.Runtime.csproj`
- `ShrinkNetwork.Runtime.csproj`
- 如果你把模板工程移到别处,需要同步修正 `__PROJECT_NAME__.csproj` 里的 `ProjectReference`
@@ -16,6 +16,9 @@
<ItemGroup>
<ProjectReference Include="__SDK_ROOT_RELATIVE__\ShrinkModFramework.Runtime.csproj" />
<ProjectReference Include="__SDK_ROOT_RELATIVE__\ShrinkEventBus.Runtime.csproj" />
<ProjectReference Include="__SDK_ROOT_RELATIVE__\DotNet\ShrinkEventBus.Generator\ShrinkEventBus.Generator.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
<ProjectReference Include="__SDK_ROOT_RELATIVE__\ShrinkCommand.Runtime.csproj" />
<ProjectReference Include="__SDK_ROOT_RELATIVE__\ShrinkNetwork.Runtime.csproj" />
</ItemGroup>
@@ -5,7 +5,7 @@ using ShrinkNetwork;
namespace __ROOT_NAMESPACE__
{
public sealed class __PROJECT_NAME__Event : EventBase
public sealed class __PROJECT_NAME__Event : IShrinkEvent
{
public string Message { get; set; } = string.Empty;
}
@@ -8,10 +8,10 @@ using ShrinkNetwork;
namespace __ROOT_NAMESPACE__
{
[ShrinkMod("__MOD_ID__", "__DISPLAY_NAME__", "1.0.0")]
[EventBusSubscriber]
[ShrinkEventSubscriber(OwnerId = "__MOD_ID__", DefaultBus = "mod:__MOD_ID__")]
[ShrinkCommandSubscriber]
[ShrinkNetworkSubscriber]
public sealed class __PROJECT_NAME__Mod : ShrinkModBase
public sealed partial class __PROJECT_NAME__Mod : ShrinkModBase
{
private readonly RuntimeState _state = new();
@@ -22,11 +22,7 @@ namespace __ROOT_NAMESPACE__
public override void OnRegisterContent(ShrinkModContext context)
{
var registry = context.GetRegistry<string>("example.items");
registry.Register(
context.ModInfo.ModId,
context.ModInfo.ModId + ":example_item",
"__DISPLAY_NAME__ Item");
context.RegisterContent("example.items", "example_item", "__DISPLAY_NAME__ Item");
}
public override void OnInitialize(ShrinkModContext context)
@@ -38,7 +34,7 @@ namespace __ROOT_NAMESPACE__
});
}
[EventSubscribe]
[ShrinkSubscribe]
private void OnExampleEvent(__PROJECT_NAME__Event evt)
{
_state.LastEventMessage = evt.Message ?? string.Empty;
@@ -5,7 +5,7 @@ using ShrinkNetwork;
namespace __ROOT_NAMESPACE__
{
public sealed class __PROJECT_NAME__Event : EventBase
public sealed class __PROJECT_NAME__Event : IShrinkEvent
{
public string Message { get; set; } = string.Empty;
}
@@ -8,10 +8,10 @@ using ShrinkNetwork;
namespace __ROOT_NAMESPACE__
{
[ShrinkMod("__MOD_ID__", "__DISPLAY_NAME__", "1.0.0")]
[EventBusSubscriber]
[ShrinkEventSubscriber(OwnerId = "__MOD_ID__", DefaultBus = "mod:__MOD_ID__")]
[ShrinkCommandSubscriber]
[ShrinkNetworkSubscriber]
public sealed class __PROJECT_NAME__Mod : ShrinkModBase
public sealed partial class __PROJECT_NAME__Mod : ShrinkModBase
{
private readonly RuntimeState _state = new();
@@ -22,11 +22,7 @@ namespace __ROOT_NAMESPACE__
public override void OnRegisterContent(ShrinkModContext context)
{
var registry = context.GetRegistry<string>("example.items");
registry.Register(
context.ModInfo.ModId,
context.ModInfo.ModId + ":example_item",
"__DISPLAY_NAME__ Item");
context.RegisterContent("example.items", "example_item", "__DISPLAY_NAME__ Item");
}
public override void OnInitialize(ShrinkModContext context)
@@ -38,7 +34,7 @@ namespace __ROOT_NAMESPACE__
});
}
[EventSubscribe]
[ShrinkSubscribe]
private void OnExampleEvent(__PROJECT_NAME__Event evt)
{
_state.LastEventMessage = evt.Message ?? string.Empty;
@@ -20,6 +20,7 @@ public static class ShrinkModSdkExporter
{
"ShrinkModFramework.Runtime",
"ShrinkEventBus.Runtime",
"ShrinkEventBus.Generator",
"ShrinkCommand.Runtime",
"ShrinkCommand.Integration.EventBus",
"ShrinkCommand.Integration.Network",
@@ -43,6 +44,7 @@ public static class ShrinkModSdkExporter
{
var projectRoot = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
BuildSolution(projectRoot);
BuildEventBusGenerator(projectRoot);
var defaultOutputRoot = Path.Combine(projectRoot, DefaultOutputRootRelativePath);
Directory.CreateDirectory(defaultOutputRoot);
@@ -109,6 +111,30 @@ public static class ShrinkModSdkExporter
}
}
private static void BuildEventBusGenerator(string projectRoot)
{
var startInfo = new ProcessStartInfo
{
FileName = "dotnet",
Arguments = "build .\\DotNet\\ShrinkEventBus.Generator\\ShrinkEventBus.Generator.csproj -c Release /nr:false",
WorkingDirectory = projectRoot,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using var process = Process.Start(startInfo);
if (process == null)
throw new InvalidOperationException("无法启动 ShrinkEventBus.Generator 构建。");
var stdout = process.StandardOutput.ReadToEnd();
var stderr = process.StandardError.ReadToEnd();
process.WaitForExit();
if (process.ExitCode != 0)
throw new InvalidOperationException("构建 ShrinkEventBus.Generator 失败。\n" + stdout + "\n" + stderr);
}
private static void PrepareOutputDirectory(string outputRoot)
{
Directory.CreateDirectory(outputRoot);
@@ -135,6 +161,7 @@ public static class ShrinkModSdkExporter
Path.Combine(projectRoot, "Temp", "Bin", "Debug", "Assembly-CSharp"),
Path.Combine(projectRoot, "Temp", "Bin", "Debug", "ShrinkModFramework.Runtime"),
Path.Combine(projectRoot, "Temp", "Bin", "Debug", "ShrinkEventBus.Runtime"),
Path.Combine(projectRoot, "DotNet", "ShrinkEventBus.Generator", "bin", "Release", "netstandard2.0"),
Path.Combine(projectRoot, "Temp", "Bin", "Debug", "ShrinkCommand.Runtime"),
Path.Combine(projectRoot, "Temp", "Bin", "Debug", "ShrinkCommand.Integration.EventBus"),
Path.Combine(projectRoot, "Temp", "Bin", "Debug", "ShrinkCommand.Integration.Network"),
@@ -181,7 +208,7 @@ public static class ShrinkModSdkExporter
builder.AppendLine("## 内容");
builder.AppendLine();
builder.AppendLine("- `Libs/`");
builder.AppendLine(" - 已编译好的框架运行时 DLL、当前游戏 DLL,以及模板需要的基础依赖");
builder.AppendLine(" - 已编译好的框架运行时 DLL、EventBus 代码生成器、当前游戏 DLL,以及模板需要的基础依赖");
builder.AppendLine("- `Templates/ExternalMod/SampleShrinkMod/`");
builder.AppendLine(" - 可直接复制一份开始写外部模组的模板工程");
builder.AppendLine();
@@ -266,6 +293,8 @@ public static class ShrinkModSdkExporter
- `src/`
- 示例模组代码
EventBus handler 只使用 `[ShrinkEventSubscriber]` / `[ShrinkSubscribe]`。项目已把 `Libs/ShrinkEventBus.Generator.dll` 作为 Roslyn analyzer 引入,因此 Attach/Post 路径不依赖运行时反射。
## 推荐构建方式
双击或在命令行运行:
@@ -367,6 +396,10 @@ cmd /k";
builder.AppendLine(" </Reference>");
}
builder.AppendLine(" </ItemGroup>");
builder.AppendLine();
builder.AppendLine(" <ItemGroup>");
builder.AppendLine(" <Analyzer Include=\"..\\..\\..\\Libs\\ShrinkEventBus.Generator.dll\" />");
builder.AppendLine(" </ItemGroup>");
builder.AppendLine("</Project>");
return builder.ToString();
@@ -381,7 +414,7 @@ using ShrinkNetwork;
namespace SampleShrinkMod
{
public sealed class SampleShrinkModEvent : EventBase
public sealed class SampleShrinkModEvent : IShrinkEvent
{
public string Message { get; set; } = string.Empty;
}
@@ -413,10 +446,10 @@ using ShrinkNetwork;
namespace SampleShrinkMod
{
[ShrinkMod(""sample.shrink.mod"", ""Sample Shrink Mod"", ""1.0.0"")]
[EventBusSubscriber]
[ShrinkEventSubscriber(OwnerId = ""sample.shrink.mod"", DefaultBus = ""mod:sample.shrink.mod"")]
[ShrinkCommandSubscriber]
[ShrinkNetworkSubscriber]
public sealed class SampleShrinkModMod : ShrinkModBase
public sealed partial class SampleShrinkModMod : ShrinkModBase
{
private readonly RuntimeState _state = new();
@@ -427,11 +460,7 @@ namespace SampleShrinkMod
public override void OnRegisterContent(ShrinkModContext context)
{
var registry = context.GetRegistry<string>(""example.items"");
registry.Register(
context.ModInfo.ModId,
context.ModInfo.ModId + "":example_item"",
""Sample Shrink Mod Item"");
context.RegisterContent(""example.items"", ""example_item"", ""Sample Shrink Mod Item"");
}
public override void OnInitialize(ShrinkModContext context)
@@ -443,7 +472,7 @@ namespace SampleShrinkMod
});
}
[EventSubscribe]
[ShrinkSubscribe]
private void OnExampleEvent(SampleShrinkModEvent evt)
{
_state.LastEventMessage = evt.Message ?? string.Empty;