From 57bc1f2032e46d3ef602ecbe292fcb9e380fe3d6 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Thu, 18 Dec 2014 19:22:47 +0800 Subject: [PATCH] Preload top used images. --- Wox.Infrastructure/Storage/BinaryStorage.cs | 1 + Wox.Plugin.SystemPlugins/CMD/CMDStorage.cs | 1 + Wox/Converters/ImagePathConverter.cs | 2 +- Wox/ImageLoader/ImageCacheStroage.cs | 54 +++++++++++++++++++++ Wox/{Helper => ImageLoader}/ImageLoader.cs | 44 ++++++++++++++--- Wox/MainWindow.xaml.cs | 20 ++++++-- Wox/SettingWindow.xaml.cs | 4 +- Wox/Wox.csproj | 3 +- 8 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 Wox/ImageLoader/ImageCacheStroage.cs rename Wox/{Helper => ImageLoader}/ImageLoader.cs (83%) diff --git a/Wox.Infrastructure/Storage/BinaryStorage.cs b/Wox.Infrastructure/Storage/BinaryStorage.cs index a04434c80d..ccdd82903c 100644 --- a/Wox.Infrastructure/Storage/BinaryStorage.cs +++ b/Wox.Infrastructure/Storage/BinaryStorage.cs @@ -10,6 +10,7 @@ namespace Wox.Infrastructure.Storage /// /// Stroage object using binary data /// Normally, it has better performance, but not readable + /// You MUST mark implement class as Serializable /// [Serializable] public abstract class BinaryStorage : BaseStorage where T : class, IStorage, new() diff --git a/Wox.Plugin.SystemPlugins/CMD/CMDStorage.cs b/Wox.Plugin.SystemPlugins/CMD/CMDStorage.cs index cfb3a5ddc3..3695ead3c7 100644 --- a/Wox.Plugin.SystemPlugins/CMD/CMDStorage.cs +++ b/Wox.Plugin.SystemPlugins/CMD/CMDStorage.cs @@ -29,5 +29,6 @@ namespace Wox.Plugin.SystemPlugins.CMD } Save(); } + } } diff --git a/Wox/Converters/ImagePathConverter.cs b/Wox/Converters/ImagePathConverter.cs index 4468a3acd0..20843a6864 100644 --- a/Wox/Converters/ImagePathConverter.cs +++ b/Wox/Converters/ImagePathConverter.cs @@ -18,7 +18,7 @@ namespace Wox.Converters return null; } - return ImageLoader.Load(value.ToString()); + return ImageLoader.ImageLoader.Load(value.ToString()); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) diff --git a/Wox/ImageLoader/ImageCacheStroage.cs b/Wox/ImageLoader/ImageCacheStroage.cs new file mode 100644 index 0000000000..88526e3e45 --- /dev/null +++ b/Wox/ImageLoader/ImageCacheStroage.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Wox.Infrastructure.Storage; + +namespace Wox.ImageLoader +{ + [Serializable] + public class ImageCacheStroage : BinaryStorage + { + public int counter = 0; + public const int maxCached = 200; + public Dictionary TopUsedImages = new Dictionary(); + + protected override string ConfigName + { + get { return "ImageCache"; } + } + + public void Add(string path) + { + if (TopUsedImages.ContainsKey(path)) + { + TopUsedImages[path] = TopUsedImages[path] + 1 ; + } + else + { + TopUsedImages.Add(path, 1); + } + + if (TopUsedImages.Count > maxCached) + { + TopUsedImages = TopUsedImages.OrderByDescending(o => o.Value) + .Take(maxCached) + .ToDictionary(i => i.Key, i => i.Value); + } + + if (++counter == 30) + { + counter = 0; + Save(); + } + } + + public void Remove(string path) + { + if (TopUsedImages.ContainsKey(path)) + { + TopUsedImages.Remove(path); + } + } + } +} diff --git a/Wox/Helper/ImageLoader.cs b/Wox/ImageLoader/ImageLoader.cs similarity index 83% rename from Wox/Helper/ImageLoader.cs rename to Wox/ImageLoader/ImageLoader.cs index bd01a230d6..5eccebb2b0 100644 --- a/Wox/Helper/ImageLoader.cs +++ b/Wox/ImageLoader/ImageLoader.cs @@ -1,17 +1,14 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Drawing; -using System.Globalization; using System.IO; -using System.Linq; using System.Runtime.InteropServices; -using System.Text; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; +using Wox.Infrastructure; -namespace Wox.Helper +namespace Wox.ImageLoader { public class ImageLoader { @@ -53,9 +50,42 @@ namespace Wox.Helper return null; } - public static ImageSource Load(string path) + public static void PreloadImages() + { + //ImageCacheStroage.Instance.TopUsedImages can be changed during foreach, so we need to make a copy + var imageList = new Dictionary(ImageCacheStroage.Instance.TopUsedImages); + using (new Timeit(string.Format("Preload {0} images",imageList.Count))) + { + foreach (var image in imageList) + { + ImageSource img = Load(image.Key, false); + if (img != null) + { + img.Freeze(); //to make it copy to UI thread + if (!imageCache.ContainsKey(image.Key)) + { + lock (locker) + { + if (!imageCache.ContainsKey(image.Key)) + { + KeyValuePair copyedImg = image; + App.Window.Dispatcher.Invoke(new Action(() => imageCache.Add(copyedImg.Key, img))); + } + } + } + } + } + } + } + + public static ImageSource Load(string path,bool addToCache = true) { if (string.IsNullOrEmpty(path)) return null; + if (addToCache) + { + ImageCacheStroage.Instance.Add(path); + } + if (imageCache.ContainsKey(path)) { return imageCache[path]; @@ -78,7 +108,7 @@ namespace Wox.Helper } - if (img != null) + if (img != null && addToCache) { if (!imageCache.ContainsKey(path)) { diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index cfc220ff9b..753a528f4e 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -16,6 +16,7 @@ using NHotkey; using NHotkey.Wpf; using Wox.Commands; using Wox.Helper; +using Wox.ImageLoader; using Wox.Infrastructure; using Wox.Infrastructure.Storage; using Wox.Infrastructure.Storage.UserSettings; @@ -188,9 +189,22 @@ namespace Wox Closing += MainWindow_Closing; //since MainWIndow implement IPublicAPI, so we need to finish ctor MainWindow object before //PublicAPI invoke in plugin init methods. E.g FolderPlugin - ThreadPool.QueueUserWorkItem(o => Plugins.Init()); + ThreadPool.QueueUserWorkItem(o => + { + Thread.Sleep(50); + Plugins.Init(); + }); + ThreadPool.QueueUserWorkItem(o => + { + Thread.Sleep(50); + PreLoadImages(); + }); + ThreadPool.QueueUserWorkItem(o => CheckUpdate()); + } - ThreadPool.QueueUserWorkItem(o => checkUpdate()); + private void PreLoadImages() + { + ImageLoader.ImageLoader.PreloadImages(); } void pnlResult_RightMouseClickEvent(Result result) @@ -198,7 +212,7 @@ namespace Wox ShowContextMenu(result); } - void checkUpdate() + void CheckUpdate() { Release release = new UpdateChecker().CheckUpgrade(); if (release != null && !UserSettingStorage.Instance.DontPromptUpdateMsg) diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index 6fa6b28410..4c752ad13c 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -482,7 +482,7 @@ namespace Wox pluginAuthor.Text = "By: " + pair.Metadata.Author; pluginSubTitle.Text = pair.Metadata.Description; pluginId = pair.Metadata.ID; - pluginIcon.Source = ImageLoader.Load(pair.Metadata.FullIcoPath); + pluginIcon.Source = ImageLoader.ImageLoader.Load(pair.Metadata.FullIcoPath); } else { @@ -499,7 +499,7 @@ namespace Wox tbOpenPluginDirecoty.Visibility = Visibility.Collapsed; pluginActionKeywordTitle.Visibility = Visibility.Collapsed; pluginTitle.Cursor = Cursors.Arrow; - pluginIcon.Source = ImageLoader.Load(sys.FullIcoPath); + pluginIcon.Source = ImageLoader.ImageLoader.Load(sys.FullIcoPath); } } diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 0d571690fc..0dd51d0540 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -104,6 +104,7 @@ + NewVersionWindow.xaml @@ -136,7 +137,7 @@ - +