commit b00f0b36844f8c340ec7e3aad43df5a95eca5529 Author: cneicy Date: Wed Aug 26 02:50:01 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..a393d0f --- /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/ShrinkContext.EventBusAdapter.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..2eea434 --- /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/ShrinkContext.EventBusAdapter.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/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..55d2a44 --- /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-context-eventbus-adapter": "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/Runtime.meta b/Runtime.meta new file mode 100644 index 0000000..1877da6 --- /dev/null +++ b/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: edcdd81338c534f4295d12a1db2cb2bc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ShrinkContext.EventBusAdapter.Runtime.asmdef b/Runtime/ShrinkContext.EventBusAdapter.Runtime.asmdef new file mode 100644 index 0000000..bd54130 --- /dev/null +++ b/Runtime/ShrinkContext.EventBusAdapter.Runtime.asmdef @@ -0,0 +1,14 @@ +{ + "name": "ShrinkContext.EventBusAdapter.Runtime", + "rootNamespace": "ShrinkContext.EventBusAdapter", + "references": [ + "ShrinkContext.Core.Runtime", + "ShrinkEventBus.Runtime", + "UniTask" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "autoReferenced": false +} \ No newline at end of file diff --git a/Runtime/ShrinkContext.EventBusAdapter.Runtime.asmdef.meta b/Runtime/ShrinkContext.EventBusAdapter.Runtime.asmdef.meta new file mode 100644 index 0000000..0996a23 --- /dev/null +++ b/Runtime/ShrinkContext.EventBusAdapter.Runtime.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: edea41497d7034e4c970a7368a156da4 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ShrinkEventBusEffects.cs b/Runtime/ShrinkEventBusEffects.cs new file mode 100644 index 0000000..b7323ad --- /dev/null +++ b/Runtime/ShrinkEventBusEffects.cs @@ -0,0 +1,33 @@ +#nullable enable +using System; +using Cysharp.Threading.Tasks; +using ShrinkContext; +using ShrinkEventBus; + +namespace ShrinkContext.EventBusAdapter +{ + /// + /// 把生成的 ShrinkEventBus 绑定包装为可逆效应。 + /// + public static class ShrinkEventBusEffects + { + /// + /// 激活生成的 [ShrinkSubscribe] 绑定,并在 Context 回滚时统一释放。 + /// + public static ShrinkEffectHandle EffectAttach(this ShrinkCtx ctx, object target, + ShrinkBusKey? defaultBus = null) + { + if (ctx == null) + throw new ArgumentNullException(nameof(ctx)); + if (target == null) + throw new ArgumentNullException(nameof(target)); + + var binding = EventBus.Attach(target, defaultBus); + return ctx.EffectInverse(() => + { + binding.Dispose(); + return UniTask.CompletedTask; + }); + } + } +} diff --git a/Runtime/ShrinkEventBusEffects.cs.meta b/Runtime/ShrinkEventBusEffects.cs.meta new file mode 100644 index 0000000..4b49b9a --- /dev/null +++ b/Runtime/ShrinkEventBusEffects.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e897f289a1563c34eb3c992463f66fbc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests.meta b/Tests.meta new file mode 100644 index 0000000..767845e --- /dev/null +++ b/Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0bede8304f5d8c2488e6c0a4c3fce9a8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/EventBusEffectTests.cs b/Tests/EventBusEffectTests.cs new file mode 100644 index 0000000..7de509e --- /dev/null +++ b/Tests/EventBusEffectTests.cs @@ -0,0 +1,106 @@ +#nullable enable +using System.Collections.Generic; +using Cysharp.Threading.Tasks; +using NUnit.Framework; +using ShrinkContext; +using ShrinkEventBus; +using UnityEngine; + +namespace ShrinkContext.EventBusAdapter.Tests +{ + public sealed class PingEvent : IShrinkEvent + { + public int Value { get; set; } + } + + /// + /// EventBus 订阅/注册即效应:组件停用时自动退订,无需手写卸载路径。 + /// + public class EventBusEffectTests + { + private ShrinkContextRuntime _runtime = null!; + private ShrinkCtx _ctx = null!; + + [SetUp] + public void SetUp() + { + _runtime = new ShrinkContextRuntime(); + _ctx = _runtime.RootContext; + } + + [TearDown] + public void TearDown() + { + _runtime.ShutdownAsync().GetAwaiter().GetResult(); + } + + [Test] + public void EffectAttach_ReceivesEvents_AndAutoUnsubscribesOnContextDispose() + { + var received = new List(); + var subscriber = new InstanceSubscriber(received); + _ctx.EffectAttach(subscriber); + + EventBus.Post(new PingEvent { Value = 1 }); + EventBus.Post(new PingEvent { Value = 2 }); + CollectionAssert.AreEqual(new[] { 1, 2 }, received); + + _ctx.DisposeAsync().GetAwaiter().GetResult(); + + EventBus.Post(new PingEvent { Value = 3 }); + CollectionAssert.AreEqual(new[] { 1, 2 }, received, + "上下文回滚后 EventBus binding 必须通过 IDisposable.Dispose 自动退订"); + } + + [Test] + public void EffectAttach_ManualDispose_OnlyUnsubscribesOwn() + { + var first = new List(); + var second = new List(); + _ctx.EffectAttach(new InstanceSubscriber(first)); + var handle = _ctx.EffectAttach(new InstanceSubscriber(second)); + + handle.DisposeAsync().GetAwaiter().GetResult(); + + EventBus.Post(new PingEvent { Value = 7 }); + CollectionAssert.AreEqual(new[] { 7 }, first, "手动退订只影响自己的订阅"); + Assert.IsEmpty(second); + } + + [Test] + public void EffectAttach_ObjectSubscribers_AutoUnregisterOnContextDispose() + { + var values = new List(); + var subscriber = new InstanceSubscriber(values); + _ctx.EffectAttach(subscriber); + + EventBus.Post(new PingEvent { Value = 5 }); + Assert.AreEqual(5, subscriber.LastValue); + + _ctx.DisposeAsync().GetAwaiter().GetResult(); + + EventBus.Post(new PingEvent { Value = 6 }); + Assert.AreEqual(5, subscriber.LastValue, "实例注册随上下文回滚自动注销"); + } + + [ShrinkEventSubscriber(DefaultBus = "game")] + private sealed class InstanceSubscriber + { + private readonly List _values; + + public InstanceSubscriber(List values) + { + _values = values; + } + + public int LastValue { get; private set; } + + [ShrinkSubscribe] + public void OnPing(PingEvent e) + { + LastValue = e.Value; + _values.Add(e.Value); + } + } + } +} diff --git a/Tests/EventBusEffectTests.cs.meta b/Tests/EventBusEffectTests.cs.meta new file mode 100644 index 0000000..cddb080 --- /dev/null +++ b/Tests/EventBusEffectTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 675a7f1a5e7d2974d81a29504efd1367 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/ShrinkContext.EventBusAdapter.Tests.asmdef b/Tests/ShrinkContext.EventBusAdapter.Tests.asmdef new file mode 100644 index 0000000..993dd83 --- /dev/null +++ b/Tests/ShrinkContext.EventBusAdapter.Tests.asmdef @@ -0,0 +1,24 @@ +{ + "name": "ShrinkContext.EventBusAdapter.Tests", + "rootNamespace": "ShrinkContext.EventBusAdapter.Tests", + "references": [ + "ShrinkContext.EventBusAdapter.Runtime", + "ShrinkContext.Core.Runtime", + "ShrinkEventBus.Runtime", + "UniTask", + "UnityEngine.TestRunner", + "UnityEditor.TestRunner" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Tests/ShrinkContext.EventBusAdapter.Tests.asmdef.meta b/Tests/ShrinkContext.EventBusAdapter.Tests.asmdef.meta new file mode 100644 index 0000000..ad704c3 --- /dev/null +++ b/Tests/ShrinkContext.EventBusAdapter.Tests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ca6bd51b2cb359840a7d8cc5ceb8831b +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json new file mode 100644 index 0000000..4e8f7df --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "com.cneicy.shrink-context-eventbus-adapter", + "version": "0.1.0", + "displayName": "ShrinkContext - EventBus Adapter", + "description": "把 ShrinkEventBus 订阅/注册包装为 ShrinkContext 可逆效应:订阅即效应,停用自动退订。", + "unity": "2022.3", + "dependencies": { + "com.cneicy.shrink-context-core": "0.1.0", + "com.cneicy.shrink-eventbus": "2.0.0", + "com.cysharp.unitask": "2.5.10" + }, + "keywords": [ + "context", + "cordis", + "eventbus", + "effect" + ], + "author": { + "name": "cneicy", + "url": "https://git.crash.work/ShrinkSDK" + }, + "documentationUrl": "https://git.crash.work/ShrinkSDK/ShrinkContext.EventBusAdapter" +} diff --git a/package.json.meta b/package.json.meta new file mode 100644 index 0000000..6f811d8 --- /dev/null +++ b/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3da06949de60a124e8b50d3ed14401ed +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: