// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved. // This code can only be used under the standard Unity Asset Store End User License Agreement // A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; // ReSharper disable MemberCanBePrivate.Global namespace Doozy.Runtime.Common { /// List database of key and value pairs /// Key type /// Value type [SuppressMessage("ReSharper", "InconsistentNaming")] [Serializable] public class ListDatabase : IListDatabase { private readonly Type m_keyType; private readonly Type m_valueType; /// Database of keys and lists of values public Dictionary> Database { get; } /// All the keys in the database public Dictionary>.KeyCollection Keys => Database.Keys; /// All the values in the database public Dictionary>.ValueCollection Values => Database.Values; public ListDatabase() { m_keyType = typeof(TKey); m_valueType = typeof(TValue); Database = new Dictionary>(); } /// Add a new key to the database with the default value /// New key public void Add(TKey key) { if (Database.ContainsKey(key)) return; Database.Add(key, new List()); } /// Add a new key to the database with the given value /// New key /// New value public void Add(TKey key, TValue value) { if (ContainsKey(key)) { if (ContainsValue(key, value)) return; if (Database[key] == null) Database[key] = new List(); Database[key].Add(value); return; } Database.Add(key, new List {value}); } /// Clear the database public void Clear() => Database.Clear(); /// Check if the database contains the given key /// Key to search for /// True or False public bool ContainsKey(TKey key) => Database.ContainsKey(key); /// Check if the database contains the given key and value pair /// Key to search for /// Value to search for /// True or False public bool ContainsValue(TKey key, TValue value) => ContainsKey(key) && Database[key].Contains(value); /// Check if the database contains the given value /// Value to search for /// True or False public bool ContainsValue(TValue value) => Database.Keys.Any(key => Database[key].Contains(value)); /// Get the number of keys in the database /// Number of keys in the database public int CountKeys() => Database.Keys.Count; /// Get the number of values for the given key /// Key to search for /// Number of values for the given key public int CountValues(TKey key) => Database.ContainsKey(key) ? Database[key].Count : 0; /// Get a list of all the values for the given key /// Key to search for /// A new List with all the values for the given key public List GetValues(TKey key) => key == null || !ContainsKey(key) || Database[key] == null ? new List() : Database[key].ToList(); /// Get a list of all the keys in the database /// A new list with all the keys in the database public List GetKeys() => Keys.ToList(); /// Remove the given key from the database /// Key to remove public void Remove(TKey key) { if (!ContainsKey(key)) return; Database.Remove(key); } /// Remove the value from the given key /// Key to search for /// Value to remove /// If TRUE and the list of values is empty, the key will be removed as well public void Remove(TKey key, TValue value, bool deleteEmptyKey = true) { if (!ContainsValue(key, value)) return; Database[key].Remove(value); if (!deleteEmptyKey) return; if (Database[key].Count == 0) Database.Remove(key); } /// Remove the value from the database /// Value to remove /// If TRUE and the list of values is empty, the key will be removed as well public void Remove(TValue value, bool deleteEmptyKey = true) { if (!ContainsValue(value)) return; var keysToRemove = new List(); foreach (TKey key in Database.Keys.Where(key => Database[key].Contains(value))) { Database[key].Remove(value); if (!deleteEmptyKey) continue; if (Database[key].Count == 0) keysToRemove.Add(key); } if (!deleteEmptyKey) return; foreach (TKey key in keysToRemove) Database.Remove(key); } /// Validate the database by removing null entries /// If TRUE and empty keys are found, they will be removed public void Validate(bool deleteEmptyKeys = true) { var keysToRemove = new List(); foreach (TKey key in Database.Keys) { for (int i = Database[key].Count - 1; i >= 0; i--) { TValue value = Database[key][i]; if (value != null) continue; Database[key].RemoveAt(i); } if (!deleteEmptyKeys) continue; if (Database[key].Count == 0) keysToRemove.Add(key); } if (!deleteEmptyKeys) return; foreach (TKey key in keysToRemove) Database.Remove(key); } } }