chenxin
2020-12-11 31f0c1761b37dfd47408a93df9ed18468b50ef40
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
 
namespace Core.Game
{
    /// <summary>
    /// Scriptable object for Level configuration
    /// </summary>
    [CreateAssetMenu(fileName = "LevelList", menuName = "StarterKit/Create Level List", order = 1)]
    public class LevelList : ScriptableObject, IList<LevelItem>,
                             IDictionary<string, LevelItem>, 
                             ISerializationCallbackReceiver
    {
        public LevelItem[] levels;
 
        /// <summary>
        /// Cached dictionary of levels by their IDs
        /// </summary>
        IDictionary<string, LevelItem> m_LevelDictionary;
 
        /// <summary>
        /// Gets the number of levels
        /// </summary>
        public int Count
        {
            get { return levels.Length; }
        }
 
        /// <summary>
        /// Level list is always read-only
        /// </summary>
        public bool IsReadOnly
        {
            get { return true; }
        }
 
        /// <summary>
        /// Gets a level by index
        /// </summary>
        public LevelItem this[int i]
        {
            get { return levels[i]; }
        }
 
        /// <summary>
        /// Gets a level by id
        /// </summary>
        public LevelItem this[string key]
        {
            get { return m_LevelDictionary[key]; }
        }
 
        /// <summary>
        /// Gets a collection of all level keys
        /// </summary>
        public ICollection<string> Keys
        {
            get { return m_LevelDictionary.Keys; }
        }
 
        /// <summary>
        /// Gets the index of a given level
        /// </summary>
        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;
        }
 
        /// <summary>
        /// Gets whether this level exists in the list
        /// </summary>
        public bool Contains(LevelItem item)
        {
            return IndexOf(item) >= 0;
        }
 
        /// <summary>
        /// Gets whether a level of the given id exists
        /// </summary>
        public bool ContainsKey(string key)
        {
            return m_LevelDictionary.ContainsKey(key);
        }
 
        /// <summary>
        /// Try get a level with the given key
        /// </summary>
        public bool TryGetValue(string key, out LevelItem value)
        {
            return m_LevelDictionary.TryGetValue(key, out value);
        }
 
        /// <summary>
        /// Gets the <see cref="LevelItem"/> associated with the given scene
        /// </summary>
        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<LevelItem> IDictionary<string, LevelItem>.Values
        {
            get { return m_LevelDictionary.Values; }
        }
 
        LevelItem IList<LevelItem>.this[int i]
        {
            get { return levels[i]; }
            set { throw new NotSupportedException("Level List is read only"); }
        }
 
        LevelItem IDictionary<string, LevelItem>.this[string key]
        {
            get { return m_LevelDictionary[key]; }
            set { throw new NotSupportedException("Level List is read only"); }
        }
 
        void IList<LevelItem>.Insert(int index, LevelItem item)
        {
            throw new NotSupportedException("Level List is read only");
        }
 
        void IList<LevelItem>.RemoveAt(int index)
        {
            throw new NotSupportedException("Level List is read only");
        }
 
        void ICollection<LevelItem>.Add(LevelItem item)
        {
            throw new NotSupportedException("Level List is read only");
        }
 
        void ICollection<KeyValuePair<string, LevelItem>>.Add(KeyValuePair<string, LevelItem> item)
        {
            throw new NotSupportedException("Level List is read only");
        }
 
        void ICollection<KeyValuePair<string, LevelItem>>.Clear()
        {
            throw new NotSupportedException("Level List is read only");
        }
 
        bool ICollection<KeyValuePair<string, LevelItem>>.Contains(KeyValuePair<string, LevelItem> item)
        {
            return m_LevelDictionary.Contains(item);
        }
 
        void ICollection<KeyValuePair<string, LevelItem>>.CopyTo(KeyValuePair<string, LevelItem>[] array, int arrayIndex)
        {
            m_LevelDictionary.CopyTo(array, arrayIndex);
        }
 
        void ICollection<LevelItem>.Clear()
        {
            throw new NotSupportedException("Level List is read only");
        }
 
        void ICollection<LevelItem>.CopyTo(LevelItem[] array, int arrayIndex)
        {
            levels.CopyTo(array, arrayIndex);
        }
 
        bool ICollection<LevelItem>.Remove(LevelItem item)
        {
            throw new NotSupportedException("Level List is read only");
        }
 
        public IEnumerator<LevelItem> GetEnumerator()
        {
            return ((IList<LevelItem>) levels).GetEnumerator();
        }
 
        IEnumerator<KeyValuePair<string, LevelItem>> IEnumerable<KeyValuePair<string, LevelItem>>.GetEnumerator()
        {
            return m_LevelDictionary.GetEnumerator();
        }
 
        IEnumerator IEnumerable.GetEnumerator()
        {
            return levels.GetEnumerator();
        }
 
        void IDictionary<string, LevelItem>.Add(string key, LevelItem value)
        {
            throw new NotSupportedException("Level List is read only");
        }
 
        bool ICollection<KeyValuePair<string, LevelItem>>.Remove(KeyValuePair<string, LevelItem> item)
        {
            throw new NotSupportedException("Level List is read only");
        }
 
        bool IDictionary<string, LevelItem>.Remove(string key)
        {
            throw new NotSupportedException("Level List is read only");
        }
    }
}