using QFSW.QC.Utilities; using System; using System.Collections.Generic; using System.Linq; namespace QFSW.QC { public static class QuantumRegistry { private static readonly Dictionary> _objectRegistry = new Dictionary>(); private static bool IsNull(object x) { if (x is UnityEngine.Object u) { return !u; } return x is null; } /// Adds the object to the registry. /// The object to add to the registry. /// The type of the object to add to the registry. [Command("register-object", "Adds the object to the registry to be used by commands with MonoTargetType = Registry")] public static void RegisterObject(T obj) where T : class { RegisterObject(typeof(T), obj); } /// Adds the object to the registry. /// The type of the object to add to the registry. /// The object to add to the registry. public static void RegisterObject(Type type, object obj) { if (!type.IsClass) { throw new Exception("Registry may only contain class types"); } lock (_objectRegistry) { if (_objectRegistry.ContainsKey(type)) { if (_objectRegistry[type].Contains(obj)) { throw new ArgumentException($"Could not register object '{obj}' of type {type.GetDisplayName()} as it was already registered."); } _objectRegistry[type].Add(obj); } else { _objectRegistry.Add(type, new List() { obj }); } } } /// Removes the object from the registry. /// The object to remove from the registry. /// The type of the object to remove from the registry. [Command("deregister-object", "Removes the object to the registry to be used by commands with MonoTargetType = Registry")] public static void DeregisterObject(T obj) where T : class { DeregisterObject(typeof(T), obj); } /// Removes the object to the registry. /// The type of the object to remove from the registry. /// The object to remove from the registry. public static void DeregisterObject(Type type, object obj) { if (!type.IsClass) { throw new Exception("Registry may only contain class types"); } lock (_objectRegistry) { if (_objectRegistry.ContainsKey(type) && _objectRegistry[type].Contains(obj)) { _objectRegistry[type].Remove(obj); } else { throw new ArgumentException($"Could not deregister object '{obj}' of type {type.GetDisplayName()} as it was not found in the registry."); } } } /// Gets the size of the specified registry. /// The registry size. /// The registry to query. public static int GetRegistrySize() where T : class { return GetRegistrySize(typeof(T)); } /// Gets the size of the specified registry. /// The registry size. /// The registry to query. public static int GetRegistrySize(Type type) { return GetRegistryContents(type).Count(); } /// Gets the contents of the specified registry. /// The registry contents. /// The registry to query. public static IEnumerable GetRegistryContents() where T : class { foreach (object obj in GetRegistryContents(typeof(T))) { yield return (T)obj; } } /// Gets the contents of the specified registry. /// The registry contents. /// The registry to query. public static IEnumerable GetRegistryContents(Type type) { if (!type.IsClass) { throw new Exception("Registry may only contain class types"); } lock (_objectRegistry) { if (_objectRegistry.ContainsKey(type)) { List registry = _objectRegistry[type]; registry.RemoveAll(IsNull); return registry; } return Enumerable.Empty(); } } /// clears the contents of the specified registry. /// The registry to clear. public static void ClearRegistryContents() where T : class { ClearRegistryContents(typeof(T)); } /// clears the contents of the specified registry. /// The registry to clear. public static void ClearRegistryContents(Type type) { if (!type.IsClass) { throw new Exception("Registry may only contain class types"); } lock (_objectRegistry) { if (_objectRegistry.ContainsKey(type)) { _objectRegistry.Clear(); } } } [Command("display-registry", "Displays the contents of the specified registry")] private static string DisplayRegistry([CommandParameterDescription("Full namespace qualified name of the type of the registry.")]Type type) { int registrySize = GetRegistrySize(type); if (registrySize < 1) { return $"registry '{type.GetDisplayName()}' was empty"; } else { return string.Join("\n", GetRegistryContents(type).Select(x => x.ToString())); } } } }