Files
RobustToolbox/Robust.Shared/Utility/PrototypeFlags.cs
metalgearsloth 3014d9880e Fix prototype flag add not actually working (#5376)
tryindex was inverted and causing issues with tools.
2024-08-25 20:03:09 +10:00

180 lines
5.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using Robust.Shared.Prototypes;
namespace Robust.Shared.Utility
{
/// <summary>
/// Data structure for storing prototype IDs, and ensuring that all stored IDs resolve to valid prototypes.
/// </summary>
/// <typeparam name="T">The prototype variant.</typeparam>
public sealed class PrototypeFlags<T> : IReadOnlyPrototypeFlags<T>
where T : class, IPrototype
{
private readonly HashSet<string> _flags;
#region Constructors
public PrototypeFlags()
{
_flags = new HashSet<string>();
}
public PrototypeFlags(params string[] flags)
{
_flags = new HashSet<string>(flags);
}
public PrototypeFlags(IEnumerable<string> flags)
{
_flags = new HashSet<string>(flags);
}
#endregion
#region API
public int Count => _flags.Count;
/// <summary>
/// Adds a prototype flag, but only if it's valid.
/// </summary>
/// <param name="flag">The prototype identifier.</param>
/// <param name="prototypeManager">The prototype manager containing the prototype.</param>
/// <returns>Whether the flag was added or not.</returns>
public bool Add(string flag, IPrototypeManager prototypeManager)
{
return prototypeManager.HasIndex<T>(flag) && _flags.Add(flag);
}
internal void UnionWith(PrototypeFlags<T> flags)
{
_flags.UnionWith(flags._flags);
}
/// <summary>
/// Checks whether a specific flag is contained here or not.
/// </summary>
public bool Contains(string flag)
{
return _flags.Contains(flag);
}
/// <summary>
/// Checks whether all specified flags are contained here or not.
/// </summary>
public bool ContainsAll(IEnumerable<string> flags)
{
foreach (var flag in flags)
{
if (!Contains(flag))
{
return false;
}
}
return true;
}
/// <summary>
/// Checks whether all specified flags are contained here or not.
/// </summary>
public bool ContainsAll(params string[] flags)
{
return ContainsAll((IEnumerable<string>) flags);
}
/// <summary>
/// Checks whether any of the specified flags are contained here or not.
/// </summary>
public bool ContainsAny(IEnumerable<string> flags)
{
foreach (var flag in flags)
{
if (Contains(flag))
{
return true;
}
}
return false;
}
/// <summary>
/// Checks whether any of the specified flags are contained here or not.
/// </summary>
public bool ContainsAny(params string[] flags)
{
return ContainsAny((IEnumerable<string>) flags);
}
/// <summary>
/// Removes a flag, if present.
/// </summary>
/// <param name="flag">The flag to be removed.</param>
/// <returns>Whether the prototype flag was successfully removed.</returns>
public bool Remove(string flag)
{
return _flags.Remove(flag);
}
/// <summary>
/// Empties the collection of all prototype flags.
/// </summary>
public void Clear()
{
_flags.Clear();
}
#endregion
#region Enumeration
public IEnumerable<T> GetPrototypes(IPrototypeManager prototypeManager)
{
foreach (var prototype in _flags)
{
yield return prototypeManager.Index<T>(prototype);
}
}
public IEnumerator<string> GetEnumerator()
{
return _flags.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
public interface IReadOnlyPrototypeFlags<T> : IEnumerable<string>
where T : class, IPrototype
{
int Count { get; }
bool Contains(string flag);
bool ContainsAll(IEnumerable<string> flags);
bool ContainsAll(params string[] flags);
bool ContainsAny(IEnumerable<string> flags);
bool ContainsAny(params string[] flags);
/// <summary>
/// Enumerates all prototype flags and returns their actual prototype instances.
/// </summary>
/// <param name="prototypeManager">The prototype manager where the prototypes are stored.</param>
/// <exception cref="InvalidOperationException">Thrown if prototypes in the <see cref="IPrototypeManager"/>
/// haven't been loaded yet.
/// </exception>
/// <exception cref="UnknownPrototypeException">Thrown if any of the prototype flags in this class does not
/// correspond to a valid, known prototype in the <see cref="IPrototypeManager"/>.
/// </exception>
/// <returns>The prototype instances for all prototype flags in this object.</returns>
IEnumerable<T> GetPrototypes(IPrototypeManager prototypeManager);
}
}