78 lines
2.6 KiB
C#
78 lines
2.6 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Swan.Configuration;
|
|
|
|
namespace Swan.Collections {
|
|
/// <summary>
|
|
/// <para>Implements a collection of components.</para>
|
|
/// <para>Each component in the collection may be given a unique name for later retrieval.</para>
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of components in the collection.</typeparam>
|
|
/// <seealso cref="IComponentCollection{T}" />
|
|
public class ComponentCollection<T> : ConfiguredObject, IComponentCollection<T> {
|
|
private readonly List<T> _components = new List<T>();
|
|
|
|
private readonly List<(String, T)> _componentsWithSafeNames = new List<(String, T)>();
|
|
|
|
private readonly Dictionary<String, T> _namedComponents = new Dictionary<String, T>();
|
|
|
|
/// <inheritdoc />
|
|
public Int32 Count => this._components.Count;
|
|
|
|
/// <inheritdoc />
|
|
public IReadOnlyDictionary<String, T> Named => this._namedComponents;
|
|
|
|
/// <inheritdoc />
|
|
public IReadOnlyList<(String SafeName, T Component)> WithSafeNames => this._componentsWithSafeNames;
|
|
|
|
/// <inheritdoc />
|
|
public T this[Int32 index] => this._components[index];
|
|
|
|
/// <inheritdoc />
|
|
public T this[String key] => this._namedComponents[key];
|
|
|
|
/// <inheritdoc />
|
|
public IEnumerator<T> GetEnumerator() => this._components.GetEnumerator();
|
|
|
|
/// <inheritdoc />
|
|
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)this._components).GetEnumerator();
|
|
|
|
/// <inheritdoc />
|
|
/// <exception cref="InvalidOperationException">The collection is locked.</exception>
|
|
public void Add(String name, T component) {
|
|
this.EnsureConfigurationNotLocked();
|
|
|
|
if(name != null) {
|
|
if(name.Length == 0) {
|
|
throw new ArgumentException("Component name is empty.", nameof(name));
|
|
}
|
|
|
|
if(this._namedComponents.ContainsKey(name)) {
|
|
throw new ArgumentException("Duplicate component name.", nameof(name));
|
|
}
|
|
}
|
|
|
|
if(component == null) {
|
|
throw new ArgumentNullException(nameof(component));
|
|
}
|
|
|
|
if(this._components.Contains(component)) {
|
|
throw new ArgumentException("Component has already been added.", nameof(component));
|
|
}
|
|
|
|
this._components.Add(component);
|
|
this._componentsWithSafeNames.Add((name ?? $"<{component.GetType().Name}>", component));
|
|
|
|
if(name != null) {
|
|
this._namedComponents.Add(name, component);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Locks the collection, preventing further additions.
|
|
/// </summary>
|
|
public void Lock() => this.LockConfiguration();
|
|
}
|
|
}
|