~johannes-rudolph/do/main

« back to all changes in this revision

Viewing changes to Do/src/Do.Core/UniverseManager.cs

  • Committer: Jason Smith
  • Date: 2009-06-26 01:11:55 UTC
  • mfrom: (1254.2.2 trunk)
  • Revision ID: jason@t500-20090626011155-49m00yweh54t2ks1
Merge clear universe branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
using Do.Universe;
29
29
using Do.Universe.Safe;
30
30
 
 
31
using UniverseCollection = System.Collections.Generic.Dictionary<string, Do.Universe.Item>;
 
32
 
31
33
namespace Do.Core
32
34
{
33
35
        
35
37
        {
36
38
 
37
39
                Thread update_thread;
38
 
                Dictionary<string, Item> universe;
 
40
                UniverseCollection universe;
39
41
                EventHandler initialized;
 
42
                object universe_lock;
40
43
                
41
44
                const float epsilon = 0.00001f;
42
45
                
75
78
                
76
79
                public UniverseManager ()
77
80
                {
78
 
                        universe = new Dictionary<string, Item> ();
 
81
                        universe = new UniverseCollection ();
 
82
                        universe_lock = new object ();
79
83
 
80
84
                        update_thread = new Thread (new ThreadStart (UniverseUpdateLoop));
81
85
                        update_thread.IsBackground = true;
117
121
                
118
122
                public IEnumerable<Item> Search (string query, IEnumerable<Type> filter, Item other)
119
123
                {
120
 
                        lock (universe) 
 
124
                        lock (universe_lock) 
121
125
                                return Search (query, filter, universe.Values, other);
122
126
                }
123
127
                
158
162
                void UniverseUpdateLoop ()
159
163
                {
160
164
                        Random rand = new Random ();
161
 
                        DateTime startUpdate = DateTime.Now;
 
165
                        DateTime startUpdate = DateTime.UtcNow;
162
166
 
163
167
                        while (true) {
164
168
                                Thread.Sleep (UpdateTimeout);
165
169
                                if (Do.Controller.IsSummoned) continue;
166
 
                                startUpdate = DateTime.Now;
 
170
                                startUpdate = DateTime.UtcNow;
167
171
                                
168
172
                                if (rand.Next (10) == 0) {
169
 
                                        ReloadActions ();
 
173
                                        ReloadActions (universe);
170
174
                                }
171
175
                                
172
176
                                foreach (ItemSource source in PluginManager.ItemSources) {
173
 
                                        ReloadSource (source);
174
 
                                        if (UpdateRunTime < DateTime.Now - startUpdate) {
 
177
                                        ReloadSource (source, universe);
 
178
                                        
 
179
                                        if (UpdateRunTime < DateTime.UtcNow - startUpdate) {
175
180
                                                Thread.Sleep (UpdateTimeout);
176
 
                                                startUpdate = DateTime.Now;
 
181
                                                // sleeping for a bit
 
182
                                                startUpdate = DateTime.UtcNow;
177
183
                                        }
178
184
                                }
179
185
                        }
182
188
                /// <summary>
183
189
                /// Reloads all actions in the universe.
184
190
                /// </summary>
185
 
                void ReloadActions ()
 
191
                void ReloadActions (UniverseCollection universe)
186
192
                {
187
193
                        Log<UniverseManager>.Debug ("Reloading actions...");
188
 
                        lock (universe) {
 
194
                        lock (universe_lock) {
189
195
                                foreach (Act action in PluginManager.Actions) {
190
196
                                        if (universe.ContainsKey (action.UniqueId))
191
197
                                                universe.Remove (action.UniqueId);
200
206
                /// not be called on the main thread to avoid blocking the UI if the
201
207
                /// item source takes a long time to update.
202
208
                /// </summary>
203
 
                void ReloadSource (ItemSource source)
 
209
                void ReloadSource (ItemSource source, UniverseCollection universe)
204
210
                {
205
211
                        SafeItemSource safeSource;
206
212
                        IEnumerable<Item> oldItems, newItems;
215
221
                        safeSource.UpdateItems ();
216
222
                        newItems = safeSource.Items;
217
223
                        
218
 
                        lock (universe) {
 
224
                        lock (universe_lock) {
219
225
                                foreach (Item item in oldItems) {
220
226
                                        if (universe.ContainsKey (item.UniqueId))
221
227
                                                universe.Remove (item.UniqueId);
229
235
                void ReloadUniverse ()
230
236
                {
231
237
                        Log<UniverseManager>.Info ("Reloading universe...");
232
 
                        ReloadActions ();
233
 
                        PluginManager.ItemSources.ForEach (ReloadSource);
 
238
                        
 
239
                        // A new temporary universe is created so that searches made during the reload (as threaded 
 
240
                        // searches are allowed will not see an interuption in available items). Additionally this 
 
241
                        // serves to clear out unused items that are orphaned from their item service.
 
242
                        UniverseCollection tmpUniverse = new UniverseCollection ();
 
243
                        ReloadActions (tmpUniverse);
 
244
                        PluginManager.ItemSources.ForEach (source => ReloadSource (source, tmpUniverse));
 
245
                        
 
246
                        // Clearing the old universe is not needed and considered harmful as enumerables in existence
 
247
                        // already will be based off the old universe. Clearing it may cause an exception to be thrown.
 
248
                        // Once those enumerables are destroyed, so too will the old universe.
 
249
                        universe = tmpUniverse;
234
250
                        Log<UniverseManager>.Info ("Universe contains {0} items.", universe.Count);
235
251
                }
236
252
                
242
258
                /// </param>
243
259
                public void AddItems (IEnumerable<Item> items)
244
260
                {
245
 
                        lock (universe) {
 
261
                        lock (universe_lock) {
246
262
                                foreach (Item item in items) {
247
263
                                        if (universe.ContainsKey (item.UniqueId)) continue;
248
264
                                        universe [item.UniqueId] = item;
259
275
                /// </param>
260
276
                public void DeleteItems (IEnumerable<Item> items)
261
277
                {
262
 
                        lock (universe) {
 
278
                        lock (universe_lock) {
263
279
                                foreach (Item item in items) {
264
280
                                        universe.Remove (item.UniqueId);
265
281
                                }
277
293
                /// </param>
278
294
                public bool TryGetItemForUniqueId (string uid, out Item element)
279
295
                {
280
 
                        lock (universe) {
 
296
                        lock (universe_lock) {
281
297
                                if (universe.ContainsKey (uid)) {
282
298
                                        element = universe [uid];
283
299
                                } else {