#nullable enable using System; using Godot; using ShrinkEventBus; public partial class WorldDemoWorld : Node { private IDisposable? _binding; private bool _restoring = true; private readonly DemoWorldSubscriber _subscriber = new(); public ShrinkBusKey Key { get; } = ShrinkBusKey.World(Guid.NewGuid().ToString("N")); public IShrinkEventBus Bus { get; private set; } = null!; public int ReadyCount => _subscriber.ReadyCount; public int EffectCount => _subscriber.EffectCount; public override void _EnterTree() { Bus = EventBus.CreateBus(Key, new ShrinkBusOptions { Scheduler = ShrinkBusSchedulerKind.MainThread, DispatchMode = ShrinkDispatchMode.Ordered, QueueCapacity = 32 }); _binding = EventBus.Attach(_subscriber, Key); } public void Restore(bool fail) { Post(new DemoEffect()); if (fail) throw new InvalidOperationException("Candidate restore failed."); } public void Commit() { _restoring = false; Post(new DemoWorldReady()); } private void Post(T value) where T : IShrinkEvent { if (!_restoring) Bus.Post(value); } public override void _ExitTree() { _binding?.Dispose(); _binding = null; EventBus.RemoveBus(Key); } } public readonly struct DemoWorldReady : IShrinkEvent { } public readonly struct DemoEffect : IShrinkEvent { } [ShrinkEventSubscriber] public sealed class DemoWorldSubscriber { public int ReadyCount { get; private set; } public int EffectCount { get; private set; } [ShrinkSubscribe] private void OnReady(DemoWorldReady value) => ReadyCount++; [ShrinkSubscribe] private void OnEffect(DemoEffect value) => EffectCount++; }