using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Core.Game { /// /// Scriptable object for Level configuration /// [CreateAssetMenu(fileName = "LevelList", menuName = "StarterKit/Create Level List", order = 1)] public class LevelList : ScriptableObject, IList, IDictionary, ISerializationCallbackReceiver { public LevelItem[] levels; /// /// Cached dictionary of levels by their IDs /// IDictionary m_LevelDictionary; /// /// Gets the number of levels /// public int Count { get { return levels.Length; } } /// /// Level list is always read-only /// public bool IsReadOnly { get { return true; } } /// /// Gets a level by index /// public LevelItem this[int i] { get { return levels[i]; } } /// /// Gets a level by id /// public LevelItem this[string key] { get { return m_LevelDictionary[key]; } } /// /// Gets a collection of all level keys /// public ICollection Keys { get { return m_LevelDictionary.Keys; } } /// /// Gets the index of a given level /// public int IndexOf(LevelItem item) { if (item == null) { return -1; } for (int i = 0; i < levels.Length; ++i) { if (levels[i] == item) { return i; } } return -1; } /// /// Gets whether this level exists in the list /// public bool Contains(LevelItem item) { return IndexOf(item) >= 0; } /// /// Gets whether a level of the given id exists /// public bool ContainsKey(string key) { return m_LevelDictionary.ContainsKey(key); } /// /// Try get a level with the given key /// public bool TryGetValue(string key, out LevelItem value) { return m_LevelDictionary.TryGetValue(key, out value); } /// /// Gets the associated with the given scene /// public LevelItem GetLevelByScene(string scene) { for (int i = 0; i < levels.Length; ++i) { LevelItem item = levels[i]; if (item != null && item.sceneName == scene) { return item; } } return null; } // Explicit interface implementations // Serialization listeners to create dictionary void ISerializationCallbackReceiver.OnBeforeSerialize() { } void ISerializationCallbackReceiver.OnAfterDeserialize() { m_LevelDictionary = levels.ToDictionary(l => l.id); } ICollection IDictionary.Values { get { return m_LevelDictionary.Values; } } LevelItem IList.this[int i] { get { return levels[i]; } set { throw new NotSupportedException("Level List is read only"); } } LevelItem IDictionary.this[string key] { get { return m_LevelDictionary[key]; } set { throw new NotSupportedException("Level List is read only"); } } void IList.Insert(int index, LevelItem item) { throw new NotSupportedException("Level List is read only"); } void IList.RemoveAt(int index) { throw new NotSupportedException("Level List is read only"); } void ICollection.Add(LevelItem item) { throw new NotSupportedException("Level List is read only"); } void ICollection>.Add(KeyValuePair item) { throw new NotSupportedException("Level List is read only"); } void ICollection>.Clear() { throw new NotSupportedException("Level List is read only"); } bool ICollection>.Contains(KeyValuePair item) { return m_LevelDictionary.Contains(item); } void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) { m_LevelDictionary.CopyTo(array, arrayIndex); } void ICollection.Clear() { throw new NotSupportedException("Level List is read only"); } void ICollection.CopyTo(LevelItem[] array, int arrayIndex) { levels.CopyTo(array, arrayIndex); } bool ICollection.Remove(LevelItem item) { throw new NotSupportedException("Level List is read only"); } public IEnumerator GetEnumerator() { return ((IList) levels).GetEnumerator(); } IEnumerator> IEnumerable>.GetEnumerator() { return m_LevelDictionary.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return levels.GetEnumerator(); } void IDictionary.Add(string key, LevelItem value) { throw new NotSupportedException("Level List is read only"); } bool ICollection>.Remove(KeyValuePair item) { throw new NotSupportedException("Level List is read only"); } bool IDictionary.Remove(string key) { throw new NotSupportedException("Level List is read only"); } } }