~ubuntu-branches/ubuntu/precise/gnome-do/precise-backports

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2009-06-27 10:40:45 UTC
  • mfrom: (1.1.8 upstream) (0.1.5 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090627104045-7st10y1cqr6dpz37
* New upstream release
  + No longer uses a plugin repository.  Fixes many plugin-
    related issues. (LP: #343096, LP: #330025, LP #345001)
  + No longer blocks on "About Do" (LP: #361679)
  + Reacts correctly when a Composite manager is enabled/
    disabled at runtime. (LP: #346347, LP: #390150)
  + Fixes for space reserved by Docky blocking drag and 
    drop operations. (LP: #354729, LP: #347052, LP: #382843)
  + Properly sets "Hidden" key on autostart files in response to 
    "Start on login" option.  (Closes: #526023) (LP: #369988)
* debian/patches/10_application_search_path:
  + Drop; included upstream
* debian/patches/10_sk_translation_update:
  + Import sk translation update from Debian BTS.
    (Closes: #531779)
* debian/patches/11_fix_autostart_when_directory_does_not_exist:
  + Patch from upstream.  Fixes the "Start on login" option when the 
    ~/.config/autostart directory does not exist. (LP: #393729)
* debian/control:
  + Update standards version to 3.8.2; no changes required.
  + Add libtool to Build-Depends; required for autoreconf.
  + Add Recommends: on new gnome-do-docklets package.
* debian/gnome-do.1
  + Fix spelling: GNOME-Do => GNOME Do.
  + Miscelaneous lintian fixes; NAME section, escaping minus signs with \-
* debian/copyright:
  + Update for new copyright holders.
  + Minor update to DEP-5 format

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, Element> 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, Element> ();
 
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;
82
86
                        update_thread.Priority = ThreadPriority.Lowest;
 
87
                        
 
88
                        Services.Network.StateChanged += OnNetworkStateChanged;
 
89
                }
 
90
 
 
91
                void OnNetworkStateChanged (object sender, NetworkStateChangedEventArgs e)
 
92
                {
 
93
                        Reload ();
83
94
                }
84
95
                        
85
96
                public void Initialize ()
93
104
                        ReloadUniverse ();
94
105
 
95
106
                        // Notify subscribers that the universe has been loaded.
96
 
                        Gtk.Application.Invoke ((sender, e) => {
 
107
                        Services.Application.RunOnMainThread (() => {
97
108
                                BuildCompleted = true;
98
109
                                if (initialized != null)
99
110
                                        initialized (this, EventArgs.Empty);
103
114
                        update_thread.Start ();
104
115
                }
105
116
 
106
 
                public IEnumerable<Element> Search (string query, IEnumerable<Type> filter)
 
117
                public IEnumerable<Item> Search (string query, IEnumerable<Type> filter)
107
118
                {       
108
 
                        return Search (query, filter, (Element) null);
 
119
                        return Search (query, filter, (Item) null);
109
120
                }
110
121
                
111
 
                public IEnumerable<Element> Search (string query, IEnumerable<Type> filter, Element other)
 
122
                public IEnumerable<Item> Search (string query, IEnumerable<Type> filter, Item other)
112
123
                {
113
 
                        if (filter.Count () == 1 && filter.First () == typeof (Act))
114
 
                                return Search (query, filter, PluginManager.Actions.OfType<Element> (), other);
115
 
                        else
116
 
                                lock (universe) 
117
 
                                        return Search (query, filter, universe.Values, other);
 
124
                        lock (universe_lock) 
 
125
                                return Search (query, filter, universe.Values, other);
118
126
                }
119
127
                
120
 
                public IEnumerable<Element> Search (string query, IEnumerable<Type> filter, IEnumerable<Element> objects)
 
128
                public IEnumerable<Item> Search (string query, IEnumerable<Type> filter, IEnumerable<Item> objects)
121
129
                {
122
130
                        return Search (query, filter, objects, null);
123
131
                }
124
132
                
125
 
                public IEnumerable<Element> Search (string query, IEnumerable<Type> filter, IEnumerable<Element> elements, Element other)
 
133
                public IEnumerable<Item> Search (string query, IEnumerable<Type> filter, IEnumerable<Item> elements, Item other)
126
134
                {
127
 
                        Element text = new ImplicitTextItem (query);
128
 
 
 
135
                        Item text = new ImplicitTextItem (query);
129
136
                        string lquery = query.ToLower ();
130
137
 
131
 
                        foreach (Element element in elements)
132
 
                                element.UpdateRelevance (lquery, other);
133
 
 
134
138
                        return elements
135
 
                                .Where (element => epsilon < Math.Abs (element.Relevance) && element.PassesTypeFilter (filter))
 
139
                                .Where (element => element.PassesTypeFilter (filter) && epsilon < Math.Abs (element.UpdateRelevance (lquery, other)))
136
140
                                .OrderByDescending (element => element.Relevance)
137
 
                                .Concat (text.PassesTypeFilter (filter)
138
 
                                                ? new [] { text }
139
 
                                                : Enumerable.Empty<Element> ()
140
 
                                )
 
141
                                .Concat (text.PassesTypeFilter (filter) ? new [] { text } : Enumerable.Empty<Item> ())
141
142
                                .ToArray ();
142
143
                }
143
144
                
145
146
                /// Returns if an object likely contains children.
146
147
                /// </summary>
147
148
                /// <param name="o">
148
 
                /// A <see cref="Element"/>
 
149
                /// A <see cref="Item"/>
149
150
                /// </param>
150
151
                /// <returns>
151
152
                /// A <see cref="System.Boolean"/>
152
153
                /// </returns>
153
 
                public bool ElementHasChildren (Element element)
 
154
                public bool ItemHasChildren (Item item)
154
155
                {
155
 
                        return element is Item && (element as Item).HasChildren ();
 
156
                        return item.HasChildren ();
156
157
                }
157
158
                
158
159
                /// <summary>
161
162
                void UniverseUpdateLoop ()
162
163
                {
163
164
                        Random rand = new Random ();
164
 
                        DateTime startUpdate = DateTime.Now;
 
165
                        DateTime startUpdate = DateTime.UtcNow;
165
166
 
166
167
                        while (true) {
167
168
                                Thread.Sleep (UpdateTimeout);
168
169
                                if (Do.Controller.IsSummoned) continue;
169
 
                                startUpdate = DateTime.Now;
 
170
                                startUpdate = DateTime.UtcNow;
170
171
                                
171
172
                                if (rand.Next (10) == 0) {
172
 
                                        ReloadActions ();
 
173
                                        ReloadActions (universe);
173
174
                                }
174
175
                                
175
176
                                foreach (ItemSource source in PluginManager.ItemSources) {
176
 
                                        ReloadSource (source);
177
 
                                        if (UpdateRunTime < DateTime.Now - startUpdate) {
 
177
                                        ReloadSource (source, universe);
 
178
                                        
 
179
                                        if (UpdateRunTime < DateTime.UtcNow - startUpdate) {
178
180
                                                Thread.Sleep (UpdateTimeout);
179
 
                                                startUpdate = DateTime.Now;
 
181
                                                // sleeping for a bit
 
182
                                                startUpdate = DateTime.UtcNow;
180
183
                                        }
181
184
                                }
182
185
                        }
185
188
                /// <summary>
186
189
                /// Reloads all actions in the universe.
187
190
                /// </summary>
188
 
                void ReloadActions ()
 
191
                void ReloadActions (UniverseCollection universe)
189
192
                {
190
193
                        Log<UniverseManager>.Debug ("Reloading actions...");
191
 
                        lock (universe) {
192
 
                                foreach (Act action in PluginManager.Actions) {
193
 
                                        universe.Remove (action.UniqueId);
194
 
                                }
195
 
                                foreach (Act action in PluginManager.Actions) {
196
 
                                                universe [action.UniqueId] = action;                    
197
 
                                }
 
194
                        lock (universe_lock) {
 
195
                                foreach (Act action in PluginManager.Actions) {
 
196
                                        if (universe.ContainsKey (action.UniqueId))
 
197
                                                universe.Remove (action.UniqueId);
 
198
                                }
 
199
                                foreach (Act action in PluginManager.Actions)
 
200
                                        universe [action.UniqueId] = action;
198
201
                        }
199
202
                }
200
203
                
203
206
                /// not be called on the main thread to avoid blocking the UI if the
204
207
                /// item source takes a long time to update.
205
208
                /// </summary>
206
 
                void ReloadSource (ItemSource source)
 
209
                void ReloadSource (ItemSource source, UniverseCollection universe)
207
210
                {
208
211
                        SafeItemSource safeSource;
209
212
                        IEnumerable<Item> oldItems, newItems;
211
214
                        if (source == null) throw new ArgumentNullException ("source");
212
215
                        
213
216
                        safeSource = source.RetainSafe ();
214
 
                        Log<UniverseManager>.Debug ("Reloading item source \"{0}\"...", safeSource.Name);
215
217
                        oldItems = safeSource.Items;
216
218
                        // We call UpdateItems outside of the lock so as not to block other
217
219
                        // threads in contention for the lock if UpdateItems blocks.
 
220
                        Log<UniverseManager>.Debug ("Reloading item source \"{0}\"...", safeSource.Name);
218
221
                        safeSource.UpdateItems ();
219
222
                        newItems = safeSource.Items;
220
223
                        
221
 
                        lock (universe) {
 
224
                        lock (universe_lock) {
222
225
                                foreach (Item item in oldItems) {
223
226
                                        if (universe.ContainsKey (item.UniqueId))
224
227
                                                universe.Remove (item.UniqueId);
232
235
                void ReloadUniverse ()
233
236
                {
234
237
                        Log<UniverseManager>.Info ("Reloading universe...");
235
 
                        ReloadActions ();
236
 
                        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;
237
250
                        Log<UniverseManager>.Info ("Universe contains {0} items.", universe.Count);
238
251
                }
239
252
                
245
258
                /// </param>
246
259
                public void AddItems (IEnumerable<Item> items)
247
260
                {
248
 
                        lock (universe) {
 
261
                        lock (universe_lock) {
249
262
                                foreach (Item item in items) {
250
263
                                        if (universe.ContainsKey (item.UniqueId)) continue;
251
264
                                        universe [item.UniqueId] = item;
262
275
                /// </param>
263
276
                public void DeleteItems (IEnumerable<Item> items)
264
277
                {
265
 
                        lock (universe) {
 
278
                        lock (universe_lock) {
266
279
                                foreach (Item item in items) {
267
280
                                        universe.Remove (item.UniqueId);
268
281
                                }
270
283
                }
271
284
 
272
285
                /// <summary>
273
 
                /// Attempts to get an Element for a given UniqueId.
 
286
                /// Attempts to get an Item for a given UniqueId.
274
287
                /// </summary>
275
288
                /// <param name="UniqueId">
276
289
                /// A <see cref="System.String"/>
277
290
                /// </param>
278
291
                /// <param name="item">
279
 
                /// A <see cref="Element"/>
 
292
                /// A <see cref="Item"/>
280
293
                /// </param>
281
 
                public bool TryGetElementForUniqueId (string uid, out Element element)
 
294
                public bool TryGetItemForUniqueId (string uid, out Item element)
282
295
                {
283
 
                        lock (universe) {
 
296
                        lock (universe_lock) {
284
297
                                if (universe.ContainsKey (uid)) {
285
298
                                        element = universe [uid];
286
299
                                } else {