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:
@@ -0,0 +1,213 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace ShrinkEventBus
|
||||
{
|
||||
/// <summary>Marker shared by managed, Unity and ECS event payloads.</summary>
|
||||
public interface IShrinkEvent
|
||||
{
|
||||
}
|
||||
|
||||
public interface IShrinkCancelableEvent : IShrinkEvent
|
||||
{
|
||||
bool IsCanceled { get; }
|
||||
void SetCanceled(bool value);
|
||||
}
|
||||
|
||||
public interface IShrinkResultEvent<TResult> : IShrinkEvent
|
||||
{
|
||||
TResult Result { get; }
|
||||
void SetResult(TResult result);
|
||||
}
|
||||
|
||||
public enum ShrinkEventPriority
|
||||
{
|
||||
Highest = 0,
|
||||
High = 1,
|
||||
Normal = 2,
|
||||
Low = 3,
|
||||
Lowest = 4,
|
||||
Monitor = 5
|
||||
}
|
||||
|
||||
public enum ShrinkDispatchMode
|
||||
{
|
||||
Ordered = 0,
|
||||
Parallel = 1
|
||||
}
|
||||
|
||||
public enum ShrinkBusSchedulerKind
|
||||
{
|
||||
Inline = 0,
|
||||
MainThread = 1,
|
||||
DedicatedThread = 2,
|
||||
TaskPool = 3
|
||||
}
|
||||
|
||||
public enum ShrinkQueueOverflowPolicy
|
||||
{
|
||||
Reject = 0,
|
||||
DropNewest = 1,
|
||||
DropOldest = 2,
|
||||
Wait = 3
|
||||
}
|
||||
|
||||
public enum ShrinkPostFailure
|
||||
{
|
||||
None = 0,
|
||||
BusStopped = 1,
|
||||
QueueFull = 2,
|
||||
Canceled = 3,
|
||||
HandlerException = 4,
|
||||
InvalidEvent = 5
|
||||
}
|
||||
|
||||
public readonly struct ShrinkPostResult
|
||||
{
|
||||
private const int AcceptedMask = 1 << 0;
|
||||
private const int HandledMask = 1 << 1;
|
||||
private const int CanceledMask = 1 << 2;
|
||||
private const int FailureShift = 8;
|
||||
private readonly int _value;
|
||||
|
||||
public ShrinkPostResult(bool accepted, bool handled, bool canceled,
|
||||
ShrinkPostFailure failure = ShrinkPostFailure.None)
|
||||
{
|
||||
_value = (accepted ? AcceptedMask : 0) |
|
||||
(handled ? HandledMask : 0) |
|
||||
(canceled ? CanceledMask : 0) |
|
||||
((int)failure << FailureShift);
|
||||
}
|
||||
|
||||
public bool Accepted => (_value & AcceptedMask) != 0;
|
||||
public bool Handled => (_value & HandledMask) != 0;
|
||||
public bool Canceled => (_value & CanceledMask) != 0;
|
||||
public ShrinkPostFailure Failure => (ShrinkPostFailure)((uint)_value >> FailureShift);
|
||||
public bool Succeeded => Accepted && Failure == ShrinkPostFailure.None;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ShrinkPostResult Rejected(ShrinkPostFailure failure) =>
|
||||
new(false, false, false, failure);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ShrinkPostResult Completed(bool handled, bool canceled = false) =>
|
||||
new(true, handled, canceled);
|
||||
}
|
||||
|
||||
public readonly struct ShrinkBusKey : IEquatable<ShrinkBusKey>
|
||||
{
|
||||
public ShrinkBusKey(string scope, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(scope))
|
||||
throw new ArgumentException("Bus scope must not be empty.", nameof(scope));
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
throw new ArgumentException("Bus name must not be empty.", nameof(name));
|
||||
|
||||
Scope = scope.Trim().ToLowerInvariant();
|
||||
Name = name.Trim();
|
||||
}
|
||||
|
||||
public string Scope { get; }
|
||||
public string Name { get; }
|
||||
public string Id => Scope == "game" && Name == "default" ? "game" : $"{Scope}:{Name}";
|
||||
|
||||
public static ShrinkBusKey Game => new("game", "default");
|
||||
public static ShrinkBusKey Server => new("server", "default");
|
||||
public static ShrinkBusKey Scene(string sceneId) => new("scene", sceneId);
|
||||
public static ShrinkBusKey Mod(string modId) => new("mod", modId);
|
||||
public static ShrinkBusKey World(string worldId) => new("world", worldId);
|
||||
|
||||
public static ShrinkBusKey Parse(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value) || string.Equals(value.Trim(), "game", StringComparison.OrdinalIgnoreCase))
|
||||
return Game;
|
||||
|
||||
var normalized = value.Trim();
|
||||
var separator = normalized.IndexOf(':');
|
||||
return separator <= 0 || separator == normalized.Length - 1
|
||||
? new ShrinkBusKey("custom", normalized)
|
||||
: new ShrinkBusKey(normalized.Substring(0, separator), normalized.Substring(separator + 1));
|
||||
}
|
||||
|
||||
public bool Equals(ShrinkBusKey other) =>
|
||||
string.Equals(Scope, other.Scope, StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(Name, other.Name, StringComparison.Ordinal);
|
||||
|
||||
public override bool Equals(object? obj) => obj is ShrinkBusKey other && Equals(other);
|
||||
public override int GetHashCode() => HashCode.Combine(Scope.ToLowerInvariant(), Name);
|
||||
public override string ToString() => Id;
|
||||
public static bool operator ==(ShrinkBusKey left, ShrinkBusKey right) => left.Equals(right);
|
||||
public static bool operator !=(ShrinkBusKey left, ShrinkBusKey right) => !left.Equals(right);
|
||||
}
|
||||
|
||||
public sealed class ShrinkBusOptions
|
||||
{
|
||||
public ShrinkBusSchedulerKind Scheduler { get; set; } = ShrinkBusSchedulerKind.Inline;
|
||||
public ShrinkDispatchMode DispatchMode { get; set; } = ShrinkDispatchMode.Ordered;
|
||||
public int QueueCapacity { get; set; } = 4096;
|
||||
public int MaxConcurrency { get; set; } = Math.Max(1, Environment.ProcessorCount);
|
||||
public ShrinkQueueOverflowPolicy OverflowPolicy { get; set; } = ShrinkQueueOverflowPolicy.Reject;
|
||||
public bool DrainOnShutdown { get; set; } = true;
|
||||
public TimeSpan ShutdownTimeout { get; set; } = TimeSpan.FromSeconds(5);
|
||||
|
||||
public static ShrinkBusOptions Inline(ShrinkDispatchMode mode = ShrinkDispatchMode.Ordered) =>
|
||||
new() { Scheduler = ShrinkBusSchedulerKind.Inline, DispatchMode = mode };
|
||||
|
||||
public static ShrinkBusOptions MainThread(int queueCapacity = 4096) =>
|
||||
new() { Scheduler = ShrinkBusSchedulerKind.MainThread, QueueCapacity = queueCapacity };
|
||||
|
||||
public static ShrinkBusOptions DedicatedThread(int queueCapacity = 4096) =>
|
||||
new() { Scheduler = ShrinkBusSchedulerKind.DedicatedThread, QueueCapacity = queueCapacity };
|
||||
|
||||
public static ShrinkBusOptions TaskPool(int maxConcurrency = 0, int queueCapacity = 4096) =>
|
||||
new()
|
||||
{
|
||||
Scheduler = ShrinkBusSchedulerKind.TaskPool,
|
||||
DispatchMode = ShrinkDispatchMode.Parallel,
|
||||
QueueCapacity = queueCapacity,
|
||||
MaxConcurrency = maxConcurrency > 0 ? maxConcurrency : Math.Max(1, Environment.ProcessorCount)
|
||||
};
|
||||
|
||||
internal ShrinkBusOptions CloneValidated()
|
||||
{
|
||||
if (QueueCapacity <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(QueueCapacity));
|
||||
if (MaxConcurrency <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(MaxConcurrency));
|
||||
if (ShutdownTimeout < TimeSpan.Zero)
|
||||
throw new ArgumentOutOfRangeException(nameof(ShutdownTimeout));
|
||||
if (OverflowPolicy == ShrinkQueueOverflowPolicy.Wait && Scheduler == ShrinkBusSchedulerKind.Inline)
|
||||
throw new InvalidOperationException("Inline buses do not have a queue and cannot use Wait overflow policy.");
|
||||
|
||||
return new ShrinkBusOptions
|
||||
{
|
||||
Scheduler = Scheduler,
|
||||
DispatchMode = DispatchMode,
|
||||
QueueCapacity = QueueCapacity,
|
||||
MaxConcurrency = MaxConcurrency,
|
||||
OverflowPolicy = OverflowPolicy,
|
||||
DrainOnShutdown = DrainOnShutdown,
|
||||
ShutdownTimeout = ShutdownTimeout
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct ShrinkSubscribeDescriptor
|
||||
{
|
||||
public ShrinkSubscribeDescriptor(string? bus, ShrinkEventPriority priority,
|
||||
int numericPriority, bool receiveCanceled)
|
||||
{
|
||||
Bus = bus ?? string.Empty;
|
||||
Priority = priority;
|
||||
NumericPriority = numericPriority;
|
||||
ReceiveCanceled = receiveCanceled;
|
||||
}
|
||||
|
||||
public string Bus { get; }
|
||||
public ShrinkEventPriority Priority { get; }
|
||||
public int NumericPriority { get; }
|
||||
public bool ReceiveCanceled { get; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user