[gnome-clocks] search-provider: rewrite to be stateless
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-clocks] search-provider: rewrite to be stateless
- Date: Thu, 5 May 2016 02:37:54 +0000 (UTC)
commit c6681f8c69fe8b5df5b8f57d81ca0de2f13b226d
Author: Cosimo Cecchi <cosimo endlessm com>
Date: Mon May 2 14:29:45 2016 +0800
search-provider: rewrite to be stateless
Currently the search provider carries state between searches. This is
a source of bugs, as sometimes search results are not consistent or not
returned at all for certain searches.
This commit uses gweather_location_serialize()/deserialize() to make
the provider stateless.
https://bugzilla.gnome.org/show_bug.cgi?id=737387
src/search-provider.vala | 118 ++++++++++++++++++++++++++-------------------
1 files changed, 68 insertions(+), 50 deletions(-)
---
diff --git a/src/search-provider.vala b/src/search-provider.vala
index 090d294..a98ecdf 100644
--- a/src/search-provider.vala
+++ b/src/search-provider.vala
@@ -24,9 +24,6 @@ public class SearchProvider : Object {
[DBus (visible = false)]
public signal void activate (uint32 timestamp);
- private HashTable<string, GWeather.Location> matches;
- private int count; // Used to make up id strings
-
private string[] normalize_terms (string[] terms) {
var normalized_terms = new GenericArray<string> ();
foreach (string t in terms) {
@@ -53,80 +50,101 @@ public class SearchProvider : Object {
return true;
}
- private async void search_locations (GWeather.Location location, string[] normalized_terms) {
+ private string serialize_location (GWeather.Location location) {
+ return location.serialize().print(false);
+ }
+
+ private GWeather.Location? deserialize_location (string str) {
+ Variant? variant;
+
+ try {
+ variant = Variant.parse(new VariantType ("(uv)"), str, null, null);
+ } catch (GLib.VariantParseError e) {
+ warning ("Malformed variant: %s", e.message);
+ return null;
+ }
+
+ var world = GWeather.Location.get_world ();
+ return world.deserialize(variant);
+ }
+
+ private async void search_locations_recurse (GWeather.Location location, string[] normalized_terms,
+ GenericArray<GWeather.Location> matches) {
GWeather.Location? []locations = location.get_children ();
if (locations != null) {
for (int i = 0; i < locations.length; i++) {
if (locations[i].get_level () == GWeather.LocationLevel.CITY) {
if (location_matches(locations[i], normalized_terms)) {
- matches.insert (count.to_string (), locations[i]);
- count++;
+ matches.add (locations[i]);
}
}
- yield search_locations (locations[i], normalized_terms);
+ yield search_locations_recurse (locations[i], normalized_terms, matches);
}
}
}
- public async string[] get_initial_result_set (string[] terms) {
- // clear the cache
- matches = new HashTable<string, GWeather.Location> (str_hash, str_equal);
- count = 0;
+ private async string[] search_locations (string[] normalized_terms) {
+ var world = GWeather.Location.get_world ();
+ var matches = new GenericArray<GWeather.Location> ();
- yield search_locations (GWeather.Location.get_world (), normalize_terms (terms));
+ yield search_locations_recurse (world, normalized_terms, matches);
- var result = new GenericArray<string> ();
- matches.foreach ((id, location) => {
- result.add (id);
+ string[] result = {};
+ matches.foreach ((location) => {
+ // HACK: the search provider interface does not currently allow variants as result IDs
+ result += serialize_location (location);
});
- return result.data;
+ return result;
+ }
+
+ public async string[] get_initial_result_set (string[] terms) {
+ return yield search_locations (normalize_terms (terms));
}
public async string[] get_subsearch_result_set (string[] previous_results, string[] terms) {
- var result = new GenericArray<string> ();
-
- // It looks like the shell sometimes calls get_subsearch directly
- // without calling get_initial first... not sure whether this is a
- // gnome-shell bug or if it is by design in some condition that
- // eludes me. Either way, if that happens, let's just fall back to
- // a full initial search
- if (matches == null) {
- yield get_initial_result_set (terms);
- matches.foreach ((id, location) => {
- result.add (id);
- });
- } else {
- var normalized_terms = normalize_terms (terms);
-
- foreach (var id in previous_results) {
- var location = matches.get (id);
- if (location != null && location_matches (location, normalized_terms)) {
- result.add (id);
- }
+ var normalized_terms = normalize_terms (terms);
+
+ if (previous_results.length == 0) {
+ return yield search_locations (normalized_terms);
+ }
+
+ string[] result = {};
+ foreach (var str in previous_results) {
+ var location = deserialize_location (str);
+
+ if (location != null && location_matches (location, normalized_terms)) {
+ result += (str);
}
}
- return result.data;
+ return result;
}
public HashTable<string, Variant>[] get_result_metas (string[] results) {
var result = new GenericArray<HashTable<string, Variant>> ();
- foreach (var id in results) {
- var meta = new HashTable<string, Variant> (str_hash, str_equal);;
- var location = matches.get (id);
- if (location != null) {
- var item = new World.Item (location);
- string time_label = item.time_label;
- string day = item.day_label;
- if (day != null) {
- time_label += " " + day;
- }
- meta.insert ("id", id);
- meta.insert ("name", time_label);
- meta.insert ("description", item.name);
+ int count = 0;
+
+ foreach (var str in results) {
+ var location = deserialize_location (str);
+
+ if (location == null) {
+ continue;
}
+
+ var meta = new HashTable<string, Variant> (str_hash, str_equal);
+ var item = new World.Item (location);
+ string time_label = item.time_label;
+ string day = item.day_label;
+ if (day != null) {
+ time_label += " " + day;
+ }
+ count++;
+ meta.insert ("id", count.to_string());
+ meta.insert ("name", time_label);
+ meta.insert ("description", item.name);
+
result.add (meta);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]