[gnome-builder/wip/libide] libide: port core search engine to libide



commit a2f55de15f299d2027ac0124c235cf1139425636
Author: Christian Hergert <christian hergert me>
Date:   Mon Feb 16 00:29:16 2015 -0800

    libide: port core search engine to libide

 libide/ide-internal.h        |    4 +
 libide/ide-search-context.c  |  186 ++++++++++++++++++++++++++++++++++--------
 libide/ide-search-context.h  |   17 +++-
 libide/ide-search-engine.c   |  127 ++++++++++++++++++++---------
 libide/ide-search-engine.h   |   10 ++-
 libide/ide-search-provider.c |  100 +++++++++++------------
 libide/ide-search-provider.h |   21 +++++-
 7 files changed, 330 insertions(+), 135 deletions(-)
---
diff --git a/libide/ide-internal.h b/libide/ide-internal.h
index 4a70e33..bf5faa7 100644
--- a/libide/ide-internal.h
+++ b/libide/ide-internal.h
@@ -54,6 +54,10 @@ void           _ide_diagnostic_take_range (IdeDiagnostic         *self,
 void           _ide_diagnostic_add_range  (IdeDiagnostic         *self,
                                            IdeSourceRange        *range);
 
+void _ide_search_context_add_provider (IdeSearchContext  *context,
+                                       IdeSearchProvider *provider,
+                                       gsize              max_results);
+
 IdeSourceRange *_ide_source_range_new (IdeSourceLocation *begin,
                                        IdeSourceLocation *end);
 
diff --git a/libide/ide-search-context.c b/libide/ide-search-context.c
index 787136b..bec7430 100644
--- a/libide/ide-search-context.c
+++ b/libide/ide-search-context.c
@@ -17,64 +17,140 @@
  */
 
 #include "ide-search-context.h"
+#include "ide-search-provider.h"
+#include "ide-search-result.h"
 
-typedef struct
+struct _IdeSearchContext
 {
-  void *foo;
-} IdeSearchContextPrivate;
+  IdeObject     parent_instance;
 
-G_DEFINE_TYPE_WITH_PRIVATE (IdeSearchContext, ide_search_context, IDE_TYPE_OBJECT)
+  GCancellable *cancellable;
+  GList        *providers;
+  guint         executed : 1;
+};
+
+G_DEFINE_TYPE (IdeSearchContext, ide_search_context, IDE_TYPE_OBJECT)
 
 enum {
-  PROP_0,
-  LAST_PROP
+  COUNT_SET,
+  RESULT_ADDED,
+  RESULT_REMOVED,
+  LAST_SIGNAL
 };
 
-static GParamSpec *gParamSpecs [LAST_PROP];
+static guint gSignals [LAST_SIGNAL];
 
-IdeSearchContext *
-ide_search_context_new (void)
+/**
+ * ide_search_context_get_providers:
+ *
+ * Retrieve the list of providers for the search context.
+ *
+ * Returns: (transfer none) (element-type IdeSearchProvider*): A #GList of
+ *   #IdeSearchProvider.
+ */
+const GList *
+ide_search_context_get_providers (IdeSearchContext *self)
 {
-  return g_object_new (IDE_TYPE_SEARCH_CONTEXT, NULL);
+  g_return_val_if_fail (IDE_IS_SEARCH_CONTEXT (self), NULL);
+
+  return self->providers;
 }
 
-static void
-ide_search_context_finalize (GObject *object)
+void
+ide_search_context_add_result (IdeSearchContext  *self,
+                               IdeSearchProvider *provider,
+                               IdeSearchResult   *result)
 {
-  IdeSearchContext *self = (IdeSearchContext *)object;
-  IdeSearchContextPrivate *priv = ide_search_context_get_instance_private (self);
+  g_return_if_fail (IDE_IS_SEARCH_CONTEXT (self));
+  g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
+  g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
 
-  G_OBJECT_CLASS (ide_search_context_parent_class)->finalize (object);
+  g_signal_emit (self, gSignals [RESULT_ADDED], 0, provider, result);
 }
 
-static void
-ide_search_context_get_property (GObject    *object,
-                                 guint       prop_id,
-                                 GValue     *value,
-                                 GParamSpec *pspec)
+void
+ide_search_context_remove_result (IdeSearchContext  *self,
+                                  IdeSearchProvider *provider,
+                                  IdeSearchResult   *result)
 {
-  IdeSearchContext *self = IDE_SEARCH_CONTEXT (object);
+  g_return_if_fail (IDE_IS_SEARCH_CONTEXT (self));
+  g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
+  g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
+
+  g_signal_emit (self, gSignals [RESULT_REMOVED], 0, provider, result);
+}
+
+void
+ide_search_context_set_provider_count (IdeSearchContext  *self,
+                                       IdeSearchProvider *provider,
+                                       guint64            count)
+{
+  g_return_if_fail (IDE_IS_SEARCH_CONTEXT (self));
+  g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
+
+  g_signal_emit (self, gSignals [COUNT_SET], 0, provider, count);
+}
+
+void
+ide_search_context_execute (IdeSearchContext *self,
+                            const gchar      *search_terms)
+{
+  GList *iter;
+
+  g_return_if_fail (IDE_IS_SEARCH_CONTEXT (self));
+  g_return_if_fail (!self->executed);
+  g_return_if_fail (search_terms);
+
+  self->executed = TRUE;
 
-  switch (prop_id)
+  for (iter = self->providers; iter; iter = iter->next)
     {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      gsize max_results = 0;
+
+      /* TODO: Get the max results for this provider */
+
+      ide_search_provider_populate (iter->data,
+                                    self,
+                                    search_terms,
+                                    max_results,
+                                    self->cancellable);
     }
 }
 
+void
+ide_search_context_cancel (IdeSearchContext *self)
+{
+  g_return_if_fail (IDE_IS_SEARCH_CONTEXT (self));
+
+  if (!g_cancellable_is_cancelled (self->cancellable))
+    g_cancellable_cancel (self->cancellable);
+}
+
+void
+_ide_search_context_add_provider (IdeSearchContext  *self,
+                                  IdeSearchProvider *provider,
+                                  gsize              max_results)
+{
+  g_return_if_fail (IDE_IS_SEARCH_CONTEXT (self));
+  g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
+  g_return_if_fail (!self->executed);
+
+  self->providers = g_list_append (self->providers, g_object_ref (provider));
+}
+
 static void
-ide_search_context_set_property (GObject      *object,
-                                 guint         prop_id,
-                                 const GValue *value,
-                                 GParamSpec   *pspec)
+ide_search_context_finalize (GObject *object)
 {
-  IdeSearchContext *self = IDE_SEARCH_CONTEXT (object);
+  IdeSearchContext *self = (IdeSearchContext *)object;
+  GList *copy;
 
-  switch (prop_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  copy = self->providers, self->providers = NULL;
+  g_list_foreach (copy, (GFunc)g_object_unref, NULL);
+  g_list_free (copy);
+
+  g_clear_object (&self->cancellable);
+
+  G_OBJECT_CLASS (ide_search_context_parent_class)->finalize (object);
 }
 
 static void
@@ -83,11 +159,49 @@ ide_search_context_class_init (IdeSearchContextClass *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   object_class->finalize = ide_search_context_finalize;
-  object_class->get_property = ide_search_context_get_property;
-  object_class->set_property = ide_search_context_set_property;
+
+  gSignals [COUNT_SET] =
+    g_signal_new ("count-set",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL,
+                  NULL,
+                  g_cclosure_marshal_generic,
+                  G_TYPE_NONE,
+                  2,
+                  IDE_TYPE_SEARCH_PROVIDER,
+                  G_TYPE_UINT64);
+
+  gSignals [RESULT_ADDED] =
+    g_signal_new ("result-added",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL,
+                  NULL,
+                  g_cclosure_marshal_generic,
+                  G_TYPE_NONE,
+                  2,
+                  IDE_TYPE_SEARCH_PROVIDER,
+                  IDE_TYPE_SEARCH_RESULT);
+
+  gSignals [RESULT_REMOVED] =
+    g_signal_new ("result-removed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL,
+                  NULL,
+                  g_cclosure_marshal_generic,
+                  G_TYPE_NONE,
+                  2,
+                  IDE_TYPE_SEARCH_PROVIDER,
+                  IDE_TYPE_SEARCH_RESULT);
 }
 
 static void
 ide_search_context_init (IdeSearchContext *self)
 {
+  self->cancellable = g_cancellable_new ();
 }
diff --git a/libide/ide-search-context.h b/libide/ide-search-context.h
index 7718322..6fdf83e 100644
--- a/libide/ide-search-context.h
+++ b/libide/ide-search-context.h
@@ -27,10 +27,19 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (IdeSearchContext, ide_search_context, IDE, SEARCH_CONTEXT, IdeObject)
 
-struct _IdeSearchContext
-{
-  IdeObject parent_instance;
-};
+const GList *ide_search_context_get_providers      (IdeSearchContext  *self);
+void         ide_search_context_add_result         (IdeSearchContext  *self,
+                                                    IdeSearchProvider *provider,
+                                                    IdeSearchResult   *result);
+void         ide_search_context_remove_result      (IdeSearchContext  *self,
+                                                    IdeSearchProvider *provider,
+                                                    IdeSearchResult   *result);
+void         ide_search_context_cancel             (IdeSearchContext  *self);
+void         ide_search_context_execute            (IdeSearchContext  *self,
+                                                    const gchar       *search_terms);
+void         ide_search_context_set_provider_count (IdeSearchContext  *self,
+                                                    IdeSearchProvider *provider,
+                                                    guint64            count);
 
 G_END_DECLS
 
diff --git a/libide/ide-search-engine.c b/libide/ide-search-engine.c
index f6d3967..cd4d0bd 100644
--- a/libide/ide-search-engine.c
+++ b/libide/ide-search-engine.c
@@ -18,67 +18,106 @@
 
 #include <glib/gi18n.h>
 
+#include "ide-internal.h"
+#include "ide-search-context.h"
 #include "ide-search-engine.h"
 #include "ide-search-provider.h"
 #include "ide-search-result.h"
 
-typedef struct
+struct _IdeSearchEngine
 {
-  GPtrArray *providers;
-} IdeSearchEnginePrivate;
+  IdeObject  parent_instance;
+  GList     *providers;
+};
 
-G_DEFINE_TYPE_WITH_PRIVATE (IdeSearchEngine, ide_search_engine, IDE_TYPE_OBJECT)
+G_DEFINE_TYPE (IdeSearchEngine, ide_search_engine, IDE_TYPE_OBJECT)
 
 enum {
-  PROP_0,
-  LAST_PROP
+  PROVIDER_ADDED,
+  LAST_SIGNAL
 };
 
-static GParamSpec *gParamSpecs [LAST_PROP];
+static guint gSignals [LAST_SIGNAL];
 
-IdeSearchEngine *
-ide_search_engine_new (void)
+/**
+ * ide_search_engine_search:
+ * @providers: (allow-none) (element-type IdeSearchProvider*): Optional list
+ *   of specific providers to use when searching.
+ * @search_terms: The search terms.
+ *
+ * Begins a query against the requested search providers.
+ *
+ * If @providers is %NULL, all registered providers will be used.
+ *
+ * Returns: (transfer full) (nullable): An #IdeSearchContext or %NULL if no
+ *   providers could be loaded.
+ */
+IdeSearchContext *
+ide_search_engine_search (IdeSearchEngine *self,
+                          const GList     *providers,
+                          const gchar     *search_terms)
 {
-  return g_object_new (IDE_TYPE_SEARCH_ENGINE, NULL);
+  IdeSearchContext *context;
+  const GList *iter;
+
+  g_return_val_if_fail (IDE_IS_SEARCH_ENGINE (self), NULL);
+  g_return_val_if_fail (search_terms, NULL);
+
+  if (!providers)
+    providers = self->providers;
+
+  if (!providers)
+    return NULL;
+
+  context = g_object_new (IDE_TYPE_SEARCH_CONTEXT,
+                          "context", context,
+                          NULL);
+
+  for (iter = providers; iter; iter = iter->next)
+    _ide_search_context_add_provider (context, iter->data, 0);
+
+  return context;
 }
 
-static void
-ide_search_engine_finalize (GObject *object)
+/**
+ * ide_search_engine_get_providers:
+ *
+ * Returns the list of registered search providers.
+ *
+ * Returns: (transfer none) (element-type IdeSearchProvider*): A #GList of
+ *   #IdeSearchProvider.
+ */
+GList *
+ide_search_engine_get_providers (IdeSearchEngine *self)
 {
-  IdeSearchEngine *self = (IdeSearchEngine *)object;
-  IdeSearchEnginePrivate *priv = ide_search_engine_get_instance_private (self);
+  g_return_val_if_fail (IDE_IS_SEARCH_ENGINE (self), NULL);
 
-  G_OBJECT_CLASS (ide_search_engine_parent_class)->finalize (object);
+  return self->providers;
 }
 
-static void
-ide_search_engine_get_property (GObject    *object,
-                                guint       prop_id,
-                                GValue     *value,
-                                GParamSpec *pspec)
+void
+ide_search_engine_add_provider (IdeSearchEngine   *self,
+                                IdeSearchProvider *provider)
 {
-  IdeSearchEngine *self = IDE_SEARCH_ENGINE (object);
+  g_return_if_fail (IDE_IS_SEARCH_ENGINE (self));
+  g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
 
-  switch (prop_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  self->providers = g_list_append (self->providers, g_object_ref (provider));
+  g_signal_emit (self, gSignals [PROVIDER_ADDED], 0, provider);
 }
 
 static void
-ide_search_engine_set_property (GObject      *object,
-                                guint         prop_id,
-                                const GValue *value,
-                                GParamSpec   *pspec)
+ide_search_engine_dispose (GObject *object)
 {
-  IdeSearchEngine *self = IDE_SEARCH_ENGINE (object);
+  IdeSearchEngine *self = (IdeSearchEngine *)object;
+  GList *copy;
+
+  copy = self->providers;
+  self->providers = NULL;
+  g_list_foreach (copy, (GFunc)g_object_unref, NULL);
+  g_list_free (copy);
 
-  switch (prop_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  G_OBJECT_CLASS (ide_search_engine_parent_class)->dispose (object);
 }
 
 static void
@@ -86,9 +125,19 @@ ide_search_engine_class_init (IdeSearchEngineClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = ide_search_engine_finalize;
-  object_class->get_property = ide_search_engine_get_property;
-  object_class->set_property = ide_search_engine_set_property;
+  object_class->dispose = ide_search_engine_dispose;
+
+  gSignals [PROVIDER_ADDED] =
+    g_signal_new ("provider-added",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL,
+                  NULL,
+                  g_cclosure_marshal_generic,
+                  G_TYPE_NONE,
+                  1,
+                  IDE_TYPE_SEARCH_PROVIDER);
 }
 
 static void
diff --git a/libide/ide-search-engine.h b/libide/ide-search-engine.h
index d2035b3..718047c 100644
--- a/libide/ide-search-engine.h
+++ b/libide/ide-search-engine.h
@@ -27,10 +27,12 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (IdeSearchEngine, ide_search_engine, IDE, SEARCH_ENGINE, IdeObject)
 
-struct _IdeSearchEngine
-{
-  IdeObject parent_instance;
-};
+GList            *ide_search_engine_get_providers (IdeSearchEngine   *self);
+void              ide_search_engine_add_provider  (IdeSearchEngine   *self,
+                                                   IdeSearchProvider *provider);
+IdeSearchContext *ide_search_engine_search        (IdeSearchEngine   *self,
+                                                   const GList       *providers,
+                                                   const gchar       *search_terms);
 
 G_END_DECLS
 
diff --git a/libide/ide-search-provider.c b/libide/ide-search-provider.c
index a37f76e..cc4347b 100644
--- a/libide/ide-search-provider.c
+++ b/libide/ide-search-provider.c
@@ -16,78 +16,76 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "ide-search-context.h"
 #include "ide-search-provider.h"
 
-typedef struct
-{
-  gchar *name;
-} IdeSearchProviderPrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE (IdeSearchProvider, ide_search_provider, IDE_TYPE_OBJECT)
-
-enum {
-  PROP_0,
-  LAST_PROP
-};
-
-static GParamSpec *gParamSpecs [LAST_PROP];
+G_DEFINE_ABSTRACT_TYPE (IdeSearchProvider, ide_search_provider, IDE_TYPE_OBJECT)
 
-IdeSearchProvider *
-ide_search_provider_new (void)
+static void
+ide_search_provider_class_init (IdeSearchProviderClass *klass)
 {
-  return g_object_new (IDE_TYPE_SEARCH_PROVIDER, NULL);
 }
 
 static void
-ide_search_provider_finalize (GObject *object)
+ide_search_provider_init (IdeSearchProvider *self)
 {
-  IdeSearchProvider *self = (IdeSearchProvider *)object;
-  IdeSearchProviderPrivate *priv = ide_search_provider_get_instance_private (self);
-
-  G_OBJECT_CLASS (ide_search_provider_parent_class)->finalize (object);
 }
 
-static void
-ide_search_provider_get_property (GObject    *object,
-                                  guint       prop_id,
-                                  GValue     *value,
-                                  GParamSpec *pspec)
+const gchar *
+ide_search_provider_get_verb (IdeSearchProvider *provider)
 {
-  IdeSearchProvider *self = IDE_SEARCH_PROVIDER (object);
+  g_return_val_if_fail (IDE_IS_SEARCH_PROVIDER (provider), NULL);
 
-  switch (prop_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  if (IDE_SEARCH_PROVIDER_GET_CLASS (provider)->get_verb)
+    return IDE_SEARCH_PROVIDER_GET_CLASS (provider)->get_verb (provider);
+
+  return NULL;
 }
 
-static void
-ide_search_provider_set_property (GObject      *object,
-                                  guint         prop_id,
-                                  const GValue *value,
-                                  GParamSpec   *pspec)
+gint
+ide_search_provider_get_priority (IdeSearchProvider *provider)
 {
-  IdeSearchProvider *self = IDE_SEARCH_PROVIDER (object);
+  g_return_val_if_fail (IDE_IS_SEARCH_PROVIDER (provider), NULL);
 
-  switch (prop_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  if (IDE_SEARCH_PROVIDER_GET_CLASS (provider)->get_priority)
+    return IDE_SEARCH_PROVIDER_GET_CLASS (provider)->get_priority (provider);
+
+  return G_MAXINT;
 }
 
-static void
-ide_search_provider_class_init (IdeSearchProviderClass *klass)
+gunichar
+ide_search_provider_get_prefix (IdeSearchProvider *provider)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  g_return_val_if_fail (IDE_IS_SEARCH_PROVIDER (provider), NULL);
+
+  if (IDE_SEARCH_PROVIDER_GET_CLASS (provider)->get_prefix)
+    return IDE_SEARCH_PROVIDER_GET_CLASS (provider)->get_prefix (provider);
 
-  object_class->finalize = ide_search_provider_finalize;
-  object_class->get_property = ide_search_provider_get_property;
-  object_class->set_property = ide_search_provider_set_property;
+  return '\0';
 }
 
-static void
-ide_search_provider_init (IdeSearchProvider *self)
+void
+ide_search_provider_populate (IdeSearchProvider *provider,
+                             IdeSearchContext  *context,
+                             const gchar      *search_terms,
+                             gsize             max_results,
+                             GCancellable     *cancellable)
 {
+  g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
+  g_return_if_fail (IDE_IS_SEARCH_CONTEXT (context));
+  g_return_if_fail (search_terms);
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  if (IDE_SEARCH_PROVIDER_GET_CLASS (provider)->populate)
+    {
+      IDE_SEARCH_PROVIDER_GET_CLASS (provider)->populate (provider,
+                                                         context,
+                                                         search_terms,
+                                                         max_results,
+                                                         cancellable);
+      return;
+    }
+
+  g_warning ("%s does not implement populate vfunc",
+             g_type_name (G_TYPE_FROM_INSTANCE (provider)));
 }
diff --git a/libide/ide-search-provider.h b/libide/ide-search-provider.h
index 9483699..c8c3194 100644
--- a/libide/ide-search-provider.h
+++ b/libide/ide-search-provider.h
@@ -25,13 +25,32 @@ G_BEGIN_DECLS
 
 #define IDE_TYPE_SEARCH_PROVIDER (ide_search_provider_get_type())
 
-G_DECLARE_DERIVABLE_TYPE (IdeSearchProvider, ide_search_provider, IDE, SEARCH_PROVIDER, IdeObject)
+G_DECLARE_DERIVABLE_TYPE (IdeSearchProvider, ide_search_provider,
+                          IDE, SEARCH_PROVIDER, IdeObject)
 
 struct _IdeSearchProviderClass
 {
   IdeObjectClass parent_class;
+
+  gunichar     (*get_prefix)   (IdeSearchProvider *provider);
+  gint         (*get_priority) (IdeSearchProvider *provider);
+  const gchar *(*get_verb)     (IdeSearchProvider *provider);
+  void         (*populate)     (IdeSearchProvider *provider,
+                                IdeSearchContext  *context,
+                                const gchar       *search_terms,
+                                gsize              max_results,
+                                GCancellable      *cancellable);
 };
 
+gunichar     ide_search_provider_get_prefix   (IdeSearchProvider *provider);
+gint         ide_search_provider_get_priority (IdeSearchProvider *provider);
+const gchar *ide_search_provider_get_verb     (IdeSearchProvider *provider);
+void         ide_search_provider_populate     (IdeSearchProvider *provider,
+                                               IdeSearchContext  *context,
+                                               const gchar       *search_terms,
+                                               gsize              max_results,
+                                               GCancellable      *cancellable);
+
 G_END_DECLS
 
 #endif /* IDE_SEARCH_PROVIDER_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]