Files
ShrinkNetwork/Runtime/Routing/ShrinkNetworkMessageRegistry.cs
T
cneicy 93c2b8520b
Publish UPM package / publish (push) Successful in 2s
Publish NuGet packages / publish (push) Successful in 3m5s
feat(network)!: add v2 framing, pooled buffers and bounded dispatch
2026-09-29 10:14:47 +08:00

65 lines
2.8 KiB
C#

#nullable enable
using System;
using System.Collections.Generic;
namespace ShrinkNetwork
{
public sealed class ShrinkNetworkMessageRegistry
{
private readonly Dictionary<int, ShrinkNetworkMessageMeta> _opcodeToMeta = new();
private readonly Dictionary<Type, ShrinkNetworkMessageMeta> _typeToMeta = new();
private readonly HashSet<string> _routes = new(StringComparer.Ordinal);
public IReadOnlyCollection<ShrinkNetworkMessageMeta> Registrations => _typeToMeta.Values;
public void Register<TMessage>(int opcode, string? route = null) where TMessage : IShrinkNetworkMessage
=> Register(typeof(TMessage), opcode, route);
public void Register(Type messageType, int opcode, string? route = null)
{
if (messageType == null)
throw new ArgumentNullException(nameof(messageType));
if (!typeof(IShrinkNetworkMessage).IsAssignableFrom(messageType))
throw new ArgumentException($"Type {messageType.FullName} is not a network message.", nameof(messageType));
if (_opcodeToMeta.ContainsKey(opcode))
throw new InvalidOperationException($"Opcode {opcode} is already registered.");
if (_typeToMeta.ContainsKey(messageType))
throw new InvalidOperationException($"Message type {messageType.FullName} is already registered.");
route = string.IsNullOrWhiteSpace(route) ? null : route.Trim();
if (route != null && !_routes.Add(route)) throw new InvalidOperationException($"SHRINK002 Route '{route}' is already registered.");
var meta = new ShrinkNetworkMessageMeta(opcode, messageType, route);
_opcodeToMeta.Add(opcode, meta);
_typeToMeta.Add(messageType, meta);
}
public bool TryGetMeta(int opcode, out ShrinkNetworkMessageMeta? meta) => _opcodeToMeta.TryGetValue(opcode, out meta);
public bool TryGetMeta(Type type, out ShrinkNetworkMessageMeta? meta) => _typeToMeta.TryGetValue(type, out meta);
public ShrinkNetworkMessageMeta GetMeta<TMessage>() where TMessage : IShrinkNetworkMessage => GetMeta(typeof(TMessage));
public ShrinkNetworkMessageMeta GetMeta(Type type)
{
if (_typeToMeta.TryGetValue(type, out var meta))
return meta;
throw new KeyNotFoundException($"Message type {type.FullName} is not registered.");
}
}
public sealed class ShrinkNetworkMessageMeta
{
public int Opcode { get; }
public Type MessageType { get; }
public string? Route { get; }
public ShrinkNetworkMessageMeta(int opcode, Type messageType, string? route)
{
Opcode = opcode;
MessageType = messageType;
Route = route;
}
}
}