Refactoring instant query

This commit is contained in:
bao-qian
2015-11-03 00:34:27 +00:00
parent cd0d9052e8
commit fc6ac662cd
6 changed files with 38 additions and 68 deletions

View File

@@ -200,11 +200,7 @@ namespace Wox.Plugin.CMD
return context.API.GetTranslation("wox_plugin_cmd_plugin_description"); return context.API.GetTranslation("wox_plugin_cmd_plugin_description");
} }
public bool IsInstantQuery(string query) public bool IsInstantQuery(string query) => false;
{
if (query.StartsWith(">")) return true;
return false;
}
public bool IsExclusiveQuery(Query query) public bool IsExclusiveQuery(Query query)
{ {

View File

@@ -120,19 +120,16 @@ namespace Wox.Plugin.WebSearch
return context.API.GetTranslation("wox_plugin_websearch_plugin_description"); return context.API.GetTranslation("wox_plugin_websearch_plugin_description");
} }
public bool IsInstantQuery(string query) public bool IsInstantQuery(string query) => false;
public bool IsExclusiveQuery(Query query)
{ {
var strings = query.Split(' '); var strings = query.RawQuery.Split(' ');
if (strings.Length > 1) if (strings.Length > 1)
{ {
return WebSearchStorage.Instance.WebSearches.Exists(o => o.ActionWord == strings[0] && o.Enabled); return WebSearchStorage.Instance.WebSearches.Exists(o => o.ActionWord == strings[0] && o.Enabled);
} }
return false; return false;
} }
public bool IsExclusiveQuery(Query query)
{
return IsInstantQuery(query.RawQuery);
}
} }
} }

View File

@@ -21,7 +21,7 @@ namespace Wox.Core.Plugin
{ {
public const string DirectoryName = "Plugins"; public const string DirectoryName = "Plugins";
private static List<PluginMetadata> pluginMetadatas; private static List<PluginMetadata> pluginMetadatas;
private static IEnumerable<PluginPair> instantSearches; private static IEnumerable<PluginPair> instantQueryPlugins;
private static IEnumerable<PluginPair> exclusiveSearchPlugins; private static IEnumerable<PluginPair> exclusiveSearchPlugins;
private static IEnumerable<PluginPair> contextMenuPlugins; private static IEnumerable<PluginPair> contextMenuPlugins;
private static List<PluginPair> plugins; private static List<PluginPair> plugins;
@@ -135,14 +135,14 @@ namespace Wox.Core.Plugin
private static void QueryDispatch(Query query) private static void QueryDispatch(Query query)
{ {
var nonSystemPlugin = GetNonSystemPlugin(query); var pluginPairs = GetNonSystemPlugin(query) != null ?
var pluginPairs = nonSystemPlugin != null ? new List<PluginPair> { nonSystemPlugin } : GetSystemPlugins(); new List<PluginPair> { GetNonSystemPlugin(query) } : GetSystemPlugins();
foreach (var plugin in pluginPairs) foreach (var plugin in pluginPairs)
{ {
var customizedPluginConfig = UserSettingStorage.Instance. var customizedPluginConfig = UserSettingStorage.Instance.
CustomizedPluginConfigs.FirstOrDefault(o => o.ID == plugin.Metadata.ID); CustomizedPluginConfigs.FirstOrDefault(o => o.ID == plugin.Metadata.ID);
if (customizedPluginConfig != null && customizedPluginConfig.Disabled) return; if (customizedPluginConfig != null && customizedPluginConfig.Disabled) return;
if (query.IsIntantQuery && IsInstantSearchPlugin(plugin.Metadata)) if (IsInstantQueryPlugin(plugin))
{ {
using (new Timeit($"Plugin {plugin.Metadata.Name} is executing instant search")) using (new Timeit($"Plugin {plugin.Metadata.Name} is executing instant search"))
{ {
@@ -163,7 +163,7 @@ namespace Wox.Core.Plugin
{ {
try try
{ {
using (var time = new Timeit("Preload programs")) using (var time = new Timeit($"Query For {pair.Metadata.Name}"))
{ {
var results = pair.Plugin.Query(query) ?? new List<Result>(); var results = pair.Plugin.Query(query) ?? new List<Result>();
results.ForEach(o => { o.PluginID = pair.Metadata.ID; }); results.ForEach(o => { o.PluginID = pair.Metadata.ID; });
@@ -199,22 +199,18 @@ namespace Wox.Core.Plugin
return metadata.ActionKeyword == Query.WildcardSign; return metadata.ActionKeyword == Query.WildcardSign;
} }
public static bool IsInstantQuery(string query) private static bool IsInstantQueryPlugin(PluginPair plugin)
{ {
return GetInstantSearchesPlugins().Any(o => ((IInstantQuery)o.Plugin).IsInstantQuery(query)); //any plugin that takes more than 200ms for AvgQueryTime won't be treated as IInstantQuery plugin anymore.
} return plugin.AvgQueryTime < 200 &&
plugin.Metadata.Language.ToUpper() == AllowedLanguage.CSharp &&
private static bool IsInstantSearchPlugin(PluginMetadata pluginMetadata) GetInstantSearchesPlugins().Any(p => p.Metadata.ID == plugin.Metadata.ID);
{
//todo:to improve performance, any instant search plugin that takes long than 200ms will not consider a instant plugin anymore
return pluginMetadata.Language.ToUpper() == AllowedLanguage.CSharp &&
GetInstantSearchesPlugins().Any(o => o.Metadata.ID == pluginMetadata.ID);
} }
private static IEnumerable<PluginPair> GetInstantSearchesPlugins() private static IEnumerable<PluginPair> GetInstantSearchesPlugins()
{ {
instantSearches = instantSearches ?? GetPlugins<IInstantQuery>(); instantQueryPlugins = instantQueryPlugins ?? GetPlugins<IInstantQuery>();
return instantSearches; return instantQueryPlugins;
} }
/// <summary> /// <summary>
@@ -242,7 +238,7 @@ namespace Wox.Core.Plugin
private static PluginPair GetActionKeywordPlugin(Query query) private static PluginPair GetActionKeywordPlugin(Query query)
{ {
//if a query doesn't contain a vaild action keyword, it should not be a action keword plugin query //if a query doesn't contain a vaild action keyword, it should not be a action keword plugin query
if (String.IsNullOrEmpty(query.ActionKeyword)) return null; if (string.IsNullOrEmpty(query.ActionKeyword)) return null;
return AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.ActionKeyword); return AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.ActionKeyword);
} }

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System;
namespace Wox.Plugin namespace Wox.Plugin
{ {
@@ -20,6 +21,7 @@ namespace Wox.Plugin
/// </summary> /// </summary>
public interface IInstantQuery : IFeatures public interface IInstantQuery : IFeatures
{ {
[Obsolete("Empty interface is enough. it will be removed in v1.3.0 and possibly replaced by attribute")]
bool IsInstantQuery(string query); bool IsInstantQuery(string query);
} }

View File

@@ -34,8 +34,6 @@ namespace Wox.Plugin
internal string ActionKeyword { get; set; } internal string ActionKeyword { get; set; }
internal bool IsIntantQuery { get; set; }
/// <summary> /// <summary>
/// Return first search split by space if it has /// Return first search split by space if it has
/// </summary> /// </summary>

View File

@@ -347,7 +347,7 @@ namespace Wox
{ {
//double if to omit calling win32 function //double if to omit calling win32 function
if (UserSettingStorage.Instance.IgnoreHotkeysOnFullscreen) if (UserSettingStorage.Instance.IgnoreHotkeysOnFullscreen)
if(WindowIntelopHelper.IsWindowFullscreen()) if (WindowIntelopHelper.IsWindowFullscreen())
return true; return true;
return false; return false;
@@ -455,50 +455,31 @@ namespace Wox
queryHasReturn = false; queryHasReturn = false;
Query query = new Query(tbQuery.Text); Query query = new Query(tbQuery.Text);
lastQuery = query.RawQuery; lastQuery = query.RawQuery;
int searchDelay = GetSearchDelay(lastQuery);
query.IsIntantQuery = searchDelay == 0;
Dispatcher.DelayInvoke("UpdateSearch", Dispatcher.DelayInvoke("ClearResults", () =>
() => {
// Delay the invocation of clear method of pnlResult, minimize the time-span between clear results and add new results.
// So this will reduce splash issues. After waiting 100ms, if there still no results added, we
// must clear the result. otherwise, it will be confused why the query changed, but the results
// didn't.
if (pnlResult.Dirty) pnlResult.Clear();
}, TimeSpan.FromMilliseconds(100));
Query(query);
Dispatcher.DelayInvoke("ShowProgressbar", () =>
{
if (!queryHasReturn && !string.IsNullOrEmpty(lastQuery))
{ {
Dispatcher.DelayInvoke("ClearResults", () => StartProgress();
{ }
// Delay the invocation of clear method of pnlResult, minimize the time-span between clear results and add new results. }, TimeSpan.FromMilliseconds(150));
// So this will reduce splash issues. After waiting 100ms, if there still no results added, we //reset query history index after user start new query
// must clear the result. otherwise, it will be confused why the query changed, but the results ResetQueryHistoryIndex();
// didn't.
if (pnlResult.Dirty) pnlResult.Clear();
}, TimeSpan.FromMilliseconds(100));
Query(query);
Dispatcher.DelayInvoke("ShowProgressbar", () =>
{
if (!queryHasReturn && !string.IsNullOrEmpty(lastQuery))
{
StartProgress();
}
}, TimeSpan.FromMilliseconds(150));
//reset query history index after user start new query
ResetQueryHistoryIndex();
}, TimeSpan.FromMilliseconds(searchDelay));
} }
private void ResetQueryHistoryIndex() private void ResetQueryHistoryIndex()
{ {
QueryHistoryStorage.Instance.Reset(); QueryHistoryStorage.Instance.Reset();
} }
private int GetSearchDelay(string query)
{
if (!string.IsNullOrEmpty(query) && PluginManager.IsInstantQuery(query))
{
Debug.WriteLine("execute query without delay");
return 0;
}
Debug.WriteLine("execute query with 200ms delay");
return 200;
}
private void Query(Query q) private void Query(Query q)
{ {
PluginManager.QueryForAllPlugins(q); PluginManager.QueryForAllPlugins(q);