using System; using System.Diagnostics.CodeAnalysis; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations; using Robust.Shared.Toolshed.TypeParsers; namespace Robust.Shared.Prototypes; /// /// Wrapper type for an with a given id. /// /// The id of the prototype. /// /// This will be automatically validated by if used in data fields. /// /// for a wrapper of other prototype kinds. [Serializable, NetSerializable] public readonly record struct EntProtoId(string Id) : IEquatable, IComparable, IAsType, IAsType> { public static implicit operator string(EntProtoId protoId) { return protoId.Id; } public static implicit operator EntProtoId(EntityPrototype proto) { return new EntProtoId(proto.ID); } public static implicit operator EntProtoId(string id) { return new EntProtoId(id); } public static implicit operator EntProtoId?(string? id) { return id == null ? default(EntProtoId?) : new EntProtoId(id); } public bool Equals(string? other) { return Id == other; } public int CompareTo(EntProtoId other) { return string.Compare(Id, other.Id, StringComparison.Ordinal); } string IAsType.AsType() => Id; ProtoId IAsType>.AsType() => new(Id); public override string ToString() => Id ?? string.Empty; } /// [Serializable] public readonly record struct EntProtoId(string Id) : IEquatable, IComparable where T : IComponent, new() { public static implicit operator string(EntProtoId protoId) { return protoId.Id; } public static implicit operator EntProtoId(EntProtoId protoId) { return new EntProtoId(protoId.Id); } public static implicit operator EntProtoId(string id) { return new EntProtoId(id); } public static implicit operator EntProtoId?(string? id) { return id == null ? default(EntProtoId?) : new EntProtoId(id); } public bool Equals(string? other) { return Id == other; } public int CompareTo(EntProtoId other) { return string.Compare(Id, other.Id, StringComparison.Ordinal); } public override string ToString() => Id ?? string.Empty; public T Get(IPrototypeManager? prototypes, IComponentFactory compFactory) { prototypes ??= IoCManager.Resolve(); var proto = prototypes.Index(this); if (!proto.TryGetComponent(out T? comp, compFactory)) { throw new ArgumentException($"{nameof(EntityPrototype)} {proto.ID} has no {nameof(T)}"); } return comp; } public bool TryGet([NotNullWhen(true)] out T? comp, IPrototypeManager? prototypes, IComponentFactory compFactory) { comp = default; prototypes ??= IoCManager.Resolve(); return prototypes.TryIndex(this, out var proto) && proto.TryGetComponent(out comp, compFactory); } }