commit 2926ce5952a623e6340624db22042dee0e240350 Author: cneicy Date: Wed Aug 26 02:50:13 2026 +0800 chore: initialize standalone UPM package diff --git a/.gitea/workflows/publish.yml b/.gitea/workflows/publish.yml new file mode 100644 index 0000000..bd668b7 --- /dev/null +++ b/.gitea/workflows/publish.yml @@ -0,0 +1,49 @@ +name: Publish UPM package + +on: + push: + tags: + - 'v*' + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + env: + NODE_AUTH_TOKEN: ${{ secrets.SHRINKSDK_PACKAGE_TOKEN }} + steps: + - name: Fetch tagged revision + shell: bash + run: | + set -eu + ref="${{ gitea.sha }}" + test -n "$ref" + git init . + git remote add origin "https://git.crash.work/ShrinkSDK/ShrinkDataSaver.Integration.EventBus.git" + git fetch --depth=1 origin "$ref" + git checkout --detach FETCH_HEAD + + - name: Validate immutable release version + shell: bash + run: | + set -eu + tag="$(git describe --exact-match --tags HEAD)" + version="$(node -p "require('./package.json').version")" + test "$tag" = "v$version" + npm pack --dry-run + + - name: Publish to ShrinkSDK registry + shell: bash + run: | + set -eu + : "${NODE_AUTH_TOKEN:?SHRINKSDK_PACKAGE_TOKEN is required}" + npmrc="$HOME/.npmrc" + cleanup() { rm -f "$npmrc"; } + trap cleanup EXIT + printf '%s\n' \ + 'registry=https://git.crash.work/api/packages/ShrinkSDK/npm/' \ + '//git.crash.work/api/packages/ShrinkSDK/npm/:_authToken=${NODE_AUTH_TOKEN}' > "$npmrc" + npm publish --registry=https://git.crash.work/api/packages/ShrinkSDK/npm/ \ No newline at end of file diff --git a/.gitea/workflows/unity-verify.yml b/.gitea/workflows/unity-verify.yml new file mode 100644 index 0000000..a671f0d --- /dev/null +++ b/.gitea/workflows/unity-verify.yml @@ -0,0 +1,39 @@ +name: Verify standalone Unity package + +on: + workflow_dispatch: + +jobs: + editmode: + runs-on: unity-2022.3.62f3 + container: + image: docker.1panel.live/unityci/editor:ubuntu-2022.3.62f3-windows-mono-3 + volumes: + - /www/dk_project/bt-recovery/gitea/runner/seedskey-unity-license:/root/.local/share/unity3d/Unity + - /www/dk_project/bt-recovery/gitea/runner/seedskey-unity-entitlements:/root/.config/unity3d/Unity/licenses + steps: + - name: Fetch selected revision + shell: bash + run: | + set -eu + ref="${{ gitea.sha }}" + git init . + git remote add origin "https://git.crash.work/ShrinkSDK/ShrinkDataSaver.Integration.EventBus.git" + git fetch --depth=1 origin "$ref" + git checkout --detach FETCH_HEAD + + - name: Run package EditMode tests + shell: bash + run: | + set -eu + unity_bin="$(command -v unity-editor || command -v unity || command -v Unity || true)" + test -n "$unity_bin" + "$unity_bin" \ + -batchmode \ + -nographics \ + -quit \ + -projectPath "$PWD/Development~/UnityProject" \ + -runTests \ + -testPlatform EditMode \ + -testResults "$PWD/TestResults/editmode.xml" \ + -logFile "$PWD/TestResults/unity.log" \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..246935d --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +/Development~/UnityProject/[Ll]ibrary/ +/Development~/UnityProject/[Tt]emp/ +/Development~/UnityProject/[Oo]bj/ +/Development~/UnityProject/[Ll]ogs/ +/Development~/UnityProject/[Uu]ser[Ss]ettings/ +/Development~/UnityProject/TestResults/ +/Tools~/**/[Bb]in/ +/Tools~/**/[Oo]bj/ +*.user +*.DotSettings.user diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..700f03d --- /dev/null +++ b/.npmignore @@ -0,0 +1,8 @@ +.git/ +.gitea/ +Development~/ +Tools~/ +*.csproj +*.sln +*.user +*.DotSettings.user diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3296e96 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,15 @@ +# Changelog + +本文件记录 `ShrinkDataSaver.Integration.EventBus` 这个独立 UPM 包的变更。 + +## [2.1.0] - 2026-05-18 + +### Changed + +- 与 `ShrinkDataSaverRuntime` / `ShrinkApp` 接管初始化链路兼容,保留零配置桥接方式不变。 + +## [2.0.1] - 2026-04-06 + +### Changed + +- 添加了变更日志。 diff --git a/CHANGELOG.md.meta b/CHANGELOG.md.meta new file mode 100644 index 0000000..b09bf6a --- /dev/null +++ b/CHANGELOG.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 916d7f3a5759d4941823219888267177 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/DataSaverEventBusBridge.cs b/DataSaverEventBusBridge.cs new file mode 100644 index 0000000..2336742 --- /dev/null +++ b/DataSaverEventBusBridge.cs @@ -0,0 +1,107 @@ +#nullable enable + +using ShrinkEventBus; +using UnityEngine; + +namespace ShrinkDataSaver.Integration +{ + /// + /// DataSaver 原生事件到 EventBus 的显式桥接器。 + /// 生命周期由 ShrinkDataSaverEventBusComponent 管理,不再因程序集存在而全局自动接入。 + /// + public static class DataSaverEventBusBridge + { + private static bool _registered; + + public static bool IsRegistered => _registered; + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticState() + { + Unregister(); + _registered = false; + } + + public static void Register() + { + if (_registered) + return; + + ShrinkSettings.OnChanged += HandleSettingsChanged; + ShrinkSave.OnSaveStarted += HandleSaveStarted; + ShrinkSave.OnSaveCompleted += HandleSaveCompleted; + ShrinkSave.OnSaveFailed += HandleSaveFailed; + ShrinkSave.OnLoadStarted += HandleLoadStarted; + ShrinkSave.OnLoadCompleted += HandleLoadCompleted; + ShrinkSave.OnLoadFailed += HandleLoadFailed; + ShrinkSave.OnMigrationCompleted += HandleMigrationCompleted; + ShrinkSave.OnDeleteCompleted += HandleSlotDeleted; + _registered = true; + } + + public static void Unregister() + { + ShrinkSettings.OnChanged -= HandleSettingsChanged; + ShrinkSave.OnSaveStarted -= HandleSaveStarted; + ShrinkSave.OnSaveCompleted -= HandleSaveCompleted; + ShrinkSave.OnSaveFailed -= HandleSaveFailed; + ShrinkSave.OnLoadStarted -= HandleLoadStarted; + ShrinkSave.OnLoadCompleted -= HandleLoadCompleted; + ShrinkSave.OnLoadFailed -= HandleLoadFailed; + ShrinkSave.OnMigrationCompleted -= HandleMigrationCompleted; + ShrinkSave.OnDeleteCompleted -= HandleSlotDeleted; + _registered = false; + } + + private static void HandleSettingsChanged(string key, object value) => + EventBus.Post(new SettingsChangedEvent { Key = key, Value = value }); + + private static void HandleSaveStarted(SaveStartedEventArgs args) => + EventBus.Post(new SaveStartedEvent { SlotIndex = args.SlotIndex, Timestamp = args.Timestamp }); + + private static void HandleSaveCompleted(SaveCompletedEventArgs args) => + EventBus.Post(new SaveCompletedEvent + { + SlotIndex = args.SlotIndex, + ModuleNames = args.ModuleNames, + Timestamp = args.Timestamp + }); + + private static void HandleSaveFailed(SaveFailedEventArgs args) => + EventBus.Post(new SaveFailedEvent + { + SlotIndex = args.SlotIndex, + ErrorMessage = args.ErrorMessage + }); + + private static void HandleLoadStarted(LoadStartedEventArgs args) => + EventBus.Post(new LoadStartedEvent { SlotIndex = args.SlotIndex, Timestamp = args.Timestamp }); + + private static void HandleLoadCompleted(LoadCompletedEventArgs args) => + EventBus.Post(new LoadCompletedEvent + { + SlotIndex = args.SlotIndex, + ModuleNames = args.ModuleNames, + Version = args.Version, + Timestamp = args.Timestamp + }); + + private static void HandleLoadFailed(LoadFailedEventArgs args) => + EventBus.Post(new LoadFailedEvent + { + SlotIndex = args.SlotIndex, + ErrorMessage = args.ErrorMessage + }); + + private static void HandleMigrationCompleted(MigrationCompletedEventArgs args) => + EventBus.Post(new MigrationCompletedEvent + { + SlotIndex = args.SlotIndex, + FromVersion = args.FromVersion, + ToVersion = args.ToVersion + }); + + private static void HandleSlotDeleted(SlotDeletedEventArgs args) => + EventBus.Post(new SlotDeletedEvent { SlotIndex = args.SlotIndex }); + } +} diff --git a/DataSaverEventBusBridge.cs.meta b/DataSaverEventBusBridge.cs.meta new file mode 100644 index 0000000..1d621a1 --- /dev/null +++ b/DataSaverEventBusBridge.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d41cba0389b740dc80169c21db9eb259 +timeCreated: 1773053776 \ No newline at end of file diff --git a/DataSaverEvents.cs b/DataSaverEvents.cs new file mode 100644 index 0000000..0eb22e3 --- /dev/null +++ b/DataSaverEvents.cs @@ -0,0 +1,63 @@ +using System; +using ShrinkEventBus; + +namespace ShrinkDataSaver.Integration +{ + public class SettingsChangedEvent : IShrinkEvent + { + public string Key { get; internal set; } + public object Value { get; internal set; } + public T Get() => (T)Convert.ChangeType(Value, typeof(T)); + } + + public class SaveStartedEvent : IShrinkEvent + { + public int SlotIndex { get; internal set; } + public long Timestamp { get; internal set; } + } + + public class SaveCompletedEvent : IShrinkEvent + { + public int SlotIndex { get; internal set; } + public string[] ModuleNames { get; internal set; } + public long Timestamp { get; internal set; } + } + + public class SaveFailedEvent : IShrinkEvent + { + public int SlotIndex { get; internal set; } + public string ErrorMessage { get; internal set; } + } + + public class LoadStartedEvent : IShrinkEvent + { + public int SlotIndex { get; internal set; } + public long Timestamp { get; internal set; } + } + + public class LoadCompletedEvent : IShrinkEvent + { + public int SlotIndex { get; internal set; } + public string[] ModuleNames { get; internal set; } + public int Version { get; internal set; } + public long Timestamp { get; internal set; } + } + + public class LoadFailedEvent : IShrinkEvent + { + public int SlotIndex { get; internal set; } + public string ErrorMessage { get; internal set; } + } + + public class MigrationCompletedEvent : IShrinkEvent + { + public int SlotIndex { get; internal set; } + public int FromVersion { get; internal set; } + public int ToVersion { get; internal set; } + } + + public class SlotDeletedEvent : IShrinkEvent + { + public int SlotIndex { get; internal set; } + } +} diff --git a/DataSaverEvents.cs.meta b/DataSaverEvents.cs.meta new file mode 100644 index 0000000..aee6b96 --- /dev/null +++ b/DataSaverEvents.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 154ed134a6cb40c4be44560f08362a2a +timeCreated: 1773053752 \ No newline at end of file diff --git a/Development~/UnityProject/.gitignore b/Development~/UnityProject/.gitignore new file mode 100644 index 0000000..aa2eb00 --- /dev/null +++ b/Development~/UnityProject/.gitignore @@ -0,0 +1,6 @@ +[Ll]ibrary/ +[Tt]emp/ +[Oo]bj/ +[Ll]ogs/ +[Uu]ser[Ss]ettings/ +TestResults/ \ No newline at end of file diff --git a/Development~/UnityProject/Assets/.gitkeep b/Development~/UnityProject/Assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Development~/UnityProject/Packages/manifest.json b/Development~/UnityProject/Packages/manifest.json new file mode 100644 index 0000000..44255e2 --- /dev/null +++ b/Development~/UnityProject/Packages/manifest.json @@ -0,0 +1,15 @@ +{ + "scopedRegistries": [ + { + "name": "ShrinkSDK", + "url": "https://git.crash.work/api/packages/ShrinkSDK/npm/", + "scopes": [ + "com.cneicy" + ] + } + ], + "dependencies": { + "com.unity.test-framework": "1.1.33", + "com.cneicy.shrink-datasaver-integration-eventbus": "file:../../.." + } +} diff --git a/Development~/UnityProject/ProjectSettings/ProjectVersion.txt b/Development~/UnityProject/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..587f809 --- /dev/null +++ b/Development~/UnityProject/ProjectSettings/ProjectVersion.txt @@ -0,0 +1,2 @@ +m_EditorVersion: 2022.3.62f3 +m_EditorVersionWithRevision: 2022.3.62f3 (96770f904ca7) diff --git a/README.md b/README.md new file mode 100644 index 0000000..85275ae --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# ShrinkDataSaver.Integration.EventBus + +把 ShrinkDataSaver 的设置、保存、加载、迁移和删除生命周期发布为 ShrinkEventBus 2.0 事件。 + +ContextLoader 通过 `ShrinkDataSaverEventBusComponent` 管理桥生命周期;独立宿主调用 `DataSaverEventBusBridge.Register()`,退出时调用 `Unregister()`。 + +事件均实现 `IShrinkEvent`: + +- `SettingsChangedEvent` +- `SaveStartedEvent` / `SaveCompletedEvent` / `SaveFailedEvent` +- `LoadStartedEvent` / `LoadCompletedEvent` / `LoadFailedEvent` +- `MigrationCompletedEvent` +- `SlotDeletedEvent` + +订阅只使用 2.0 特性: + +```csharp +[ShrinkEventSubscriber(DefaultBus = "game")] +public sealed class SaveUiHandlers +{ + [ShrinkSubscribe] + private void OnSaved(SaveCompletedEvent value) + { + Debug.Log($"slot {value.SlotIndex} saved"); + } + + [ShrinkSubscribe(Priority = ShrinkEventPriority.Low)] + private void OnLoadFailed(LoadFailedEvent value) + { + Debug.LogError(value.ErrorMessage); + } +} + +using var binding = EventBus.Attach(new SaveUiHandlers()); +``` + +桥接方向是 DataSaver -> EventBus,发布使用 `EventBus.Post(...)`。没有手工 Delegate 注册或旧 Trigger API。 + +`SettingsChangedEvent.Get()` 内部使用 `Convert.ChangeType`,只应在设置值确实可转换时调用。 diff --git a/README.md.meta b/README.md.meta new file mode 100644 index 0000000..920e933 --- /dev/null +++ b/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d6a7cdf0e3e46ae418fd90acc11d6d48 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ShrinkDataSaver.Integration.EventBus.asmdef b/ShrinkDataSaver.Integration.EventBus.asmdef new file mode 100644 index 0000000..029f7ef --- /dev/null +++ b/ShrinkDataSaver.Integration.EventBus.asmdef @@ -0,0 +1,19 @@ +{ + "name": "ShrinkDataSaver.Integration.EventBus", + "rootNamespace": "ShrinkDataSaver.Integration", + "references": [ + "ShrinkDataSaver.Runtime", + "ShrinkContext.Core.Runtime", + "UniTask", + "ShrinkEventBus.Runtime" + ], + "optionalUnityReferences": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} diff --git a/ShrinkDataSaver.Integration.EventBus.asmdef.meta b/ShrinkDataSaver.Integration.EventBus.asmdef.meta new file mode 100644 index 0000000..498d1d4 --- /dev/null +++ b/ShrinkDataSaver.Integration.EventBus.asmdef.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d3277e39d0a8439db56bfb6774183165 +timeCreated: 1773053684 \ No newline at end of file diff --git a/ShrinkDataSaverEventBusComponent.cs b/ShrinkDataSaverEventBusComponent.cs new file mode 100644 index 0000000..6d6b573 --- /dev/null +++ b/ShrinkDataSaverEventBusComponent.cs @@ -0,0 +1,35 @@ +#nullable enable + +using System.Collections.Generic; +using Cysharp.Threading.Tasks; +using ShrinkContext; + +namespace ShrinkDataSaver.Integration +{ + /// 注入 DataSaver 服务键并把其原生事件显式接到 EventBus。 + public sealed class ShrinkDataSaverEventBusComponent : IShrinkComponent + { + public const string DataSaverServiceKey = "shrink.service.datasaver"; + public const string ProvideKey = "shrink.integration.datasaver-eventbus"; + + private static readonly string[] InjectKeys = { DataSaverServiceKey }; + private static readonly string[] ProvideKeys = { ProvideKey }; + + public string Name => "shrink.integration.datasaver-eventbus"; + public IReadOnlyList Inject => InjectKeys; + public IReadOnlyList Provide => ProvideKeys; + + public UniTask ApplyAsync(ShrinkCtx ctx, object? config) + { + _ = ctx.Get(DataSaverServiceKey); + DataSaverEventBusBridge.Register(); + ctx.EffectInverse(() => + { + DataSaverEventBusBridge.Unregister(); + return UniTask.CompletedTask; + }); + ctx.Set(ProvideKey, Name); + return UniTask.CompletedTask; + } + } +} diff --git a/ShrinkDataSaverEventBusComponent.cs.meta b/ShrinkDataSaverEventBusComponent.cs.meta new file mode 100644 index 0000000..6da8e30 --- /dev/null +++ b/ShrinkDataSaverEventBusComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee66c2e8bc4958946b7c0849b11545ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json new file mode 100644 index 0000000..b501de6 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "com.cneicy.shrink-datasaver-integration-eventbus", + "version": "2.1.0", + "displayName": "ShrinkDataSaver - EventBus Integration", + "description": "ShrinkDataSaver 与 ShrinkEventBus 的桥接层,自动将存档/设置事件映射到事件总线。", + "unity": "2022.3", + "documentationUrl": "https://git.crash.work/ShrinkSDK/ShrinkDataSaver.Integration.EventBus", + "changelogUrl": "https://git.crash.work/ShrinkSDK/ShrinkDataSaver.Integration.EventBus/src/branch/main/CHANGELOG.md", + "licensesUrl": "https://github.com/cneicy/ShrinkDataSaver.Integration.EventBus/blob/main/LICENSE", + "dependencies": { + "com.cneicy.shrink-datasaver": "2.2.0", + "com.cneicy.shrink-context-core": "0.1.0", + "com.cysharp.unitask": "2.5.10", + "com.cneicy.shrink-eventbus": "2.0.0" + }, + "keywords": [ + "save", + "eventbus", + "integration", + "bridge" + ], + "author": { + "name": "cneicy", + "url": "https://git.crash.work/ShrinkSDK" + } +} diff --git a/package.json.meta b/package.json.meta new file mode 100644 index 0000000..803aeed --- /dev/null +++ b/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3d8e28bc2bab56447aab597955ca683b +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: