[retro-gtk/wip/aplazas/port-module-query: 24/24] Port ModuleIterator to C



commit a76345f4ed292c6904d5f68ec7519b981ea12929
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Fri Sep 15 13:27:42 2017 +0200

    Port ModuleIterator to C

 retro-gtk/Makefile.am                    |    3 +
 retro-gtk/retro-module-iterator-extern.c |  457 ++++++++++++++++++++++++++++++
 retro-gtk/retro-module-iterator.vala     |   66 +----
 3 files changed, 471 insertions(+), 55 deletions(-)
---
diff --git a/retro-gtk/Makefile.am b/retro-gtk/Makefile.am
index 0af09a4..d2c38e3 100644
--- a/retro-gtk/Makefile.am
+++ b/retro-gtk/Makefile.am
@@ -50,6 +50,7 @@ libretro_gtk_la_SOURCES = \
        retro-module.c \
        retro-module-query.c \
        retro-module-iterator.vala \
+       retro-module-iterator-extern.c \
        retro-option.c \
        retro-options.c \
        retro-pa-player.c \
@@ -77,6 +78,8 @@ retro-log.c: retro-gtk-internal.h
 
 retro-module.c: retro-gtk-internal.h
 
+retro-module-iterator-extern.c: retro-gtk-internal.h
+
 retro-module-query.c: retro-gtk-internal.h
 
 retro-pa-player.c: retro-gtk-internal.h
diff --git a/retro-gtk/retro-module-iterator-extern.c b/retro-gtk/retro-module-iterator-extern.c
new file mode 100644
index 0000000..eaba3ee
--- /dev/null
+++ b/retro-gtk/retro-module-iterator-extern.c
@@ -0,0 +1,457 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#include "retro-gtk-internal.h"
+
+/* #include <glib.h> */
+/* #include <glib-object.h> */
+/* #include <stdlib.h> */
+/* #include <string.h> */
+/* #include <gio/gio.h> */
+/* #include <gobject/gvaluecollector.h> */
+
+/* #define RETRO_TYPE_MODULE_ITERATOR (retro_module_iterator_get_type ()) */
+/* #define RETRO_MODULE_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RETRO_TYPE_MODULE_ITERATOR, 
RetroModuleIterator)) */
+/* #define RETRO_MODULE_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RETRO_TYPE_MODULE_ITERATOR, 
RetroModuleIteratorClass)) */
+/* #define RETRO_IS_MODULE_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RETRO_TYPE_MODULE_ITERATOR)) */
+/* #define RETRO_IS_MODULE_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
RETRO_TYPE_MODULE_ITERATOR)) */
+/* #define RETRO_MODULE_ITERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), 
RETRO_TYPE_MODULE_ITERATOR, RetroModuleIteratorClass)) */
+
+/* typedef struct _RetroModuleIterator RetroModuleIterator; */
+/* typedef struct _RetroModuleIteratorClass RetroModuleIteratorClass; */
+/* typedef struct _RetroModuleIteratorPrivate RetroModuleIteratorPrivate; */
+
+/* #define RETRO_TYPE_CORE_DESCRIPTOR (retro_core_descriptor_get_type ()) */
+/* #define RETRO_CORE_DESCRIPTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RETRO_TYPE_CORE_DESCRIPTOR, 
RetroCoreDescriptor)) */
+/* #define RETRO_CORE_DESCRIPTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RETRO_TYPE_CORE_DESCRIPTOR, 
RetroCoreDescriptorClass)) */
+/* #define RETRO_IS_CORE_DESCRIPTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RETRO_TYPE_CORE_DESCRIPTOR)) */
+/* #define RETRO_IS_CORE_DESCRIPTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
RETRO_TYPE_CORE_DESCRIPTOR)) */
+/* #define RETRO_CORE_DESCRIPTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), 
RETRO_TYPE_CORE_DESCRIPTOR, RetroCoreDescriptorClass)) */
+
+/* typedef struct _RetroCoreDescriptor RetroCoreDescriptor; */
+/* typedef struct _RetroCoreDescriptorClass RetroCoreDescriptorClass; */
+/* enum  { */
+/*   RETRO_MODULE_ITERATOR_DUMMY_PROPERTY, */
+/*   RETRO_MODULE_ITERATOR_LAST_PROPERTY */
+/* }; */
+/* static GParamSpec* retro_module_iterator_properties[RETRO_MODULE_ITERATOR_LAST_PROPERTY]; */
+/* #define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) */
+/* #define _retro_module_iterator_unref0(var) ((var == NULL) ? NULL : (var = (retro_module_iterator_unref 
(var), NULL))) */
+/* #define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL))) */
+/* #define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) */
+/* #define _g_free0(var) (var = (g_free (var), NULL)) */
+/* typedef struct _RetroParamSpecModuleIterator RetroParamSpecModuleIterator; */
+
+/* struct _RetroModuleIterator { */
+/*   GTypeInstance parent_instance; */
+/*   volatile int ref_count; */
+/*   RetroModuleIteratorPrivate *priv; */
+/* }; */
+
+/* struct _RetroModuleIteratorClass { */
+/*   GTypeClass parent_class; */
+/*   void (*finalize) (RetroModuleIterator *self); */
+/* }; */
+
+/* struct _RetroModuleIteratorPrivate { */
+/*   gchar** directories; */
+/*   gint directories_length1; */
+/*   gint _directories_size_; */
+/*   gboolean recursive; */
+/*   gint current_directory; */
+/*   GFileEnumerator* file_enumerator; */
+/*   RetroCoreDescriptor* core_descriptor; */
+/*   RetroModuleIterator* sub_directory; */
+/*   GHashTable* visited; */
+/* }; */
+
+/* struct _RetroParamSpecModuleIterator { */
+/*   GParamSpec parent_instance; */
+/* }; */
+
+/* static gpointer retro_module_iterator_parent_class = NULL; */
+
+/* gpointer retro_module_iterator_ref (gpointer instance); */
+/* void retro_module_iterator_unref (gpointer instance); */
+/* GParamSpec* retro_param_spec_module_iterator (const gchar* name, const gchar* nick, const gchar* blurb, 
GType object_type, GParamFlags flags); */
+/* void retro_value_set_module_iterator (GValue* value, gpointer v_object); */
+/* void retro_value_take_module_iterator (GValue* value, gpointer v_object); */
+/* gpointer retro_value_get_module_iterator (const GValue* value); */
+/* GType retro_module_iterator_get_type (void) G_GNUC_CONST; */
+/* GType retro_core_descriptor_get_type (void) G_GNUC_CONST; */
+/* #define RETRO_MODULE_ITERATOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), 
RETRO_TYPE_MODULE_ITERATOR, RetroModuleIteratorPrivate)) */
+/* RetroModuleIterator* retro_module_iterator_new (gchar** lookup_paths, int lookup_paths_length1, gboolean 
recursive); */
+/* RetroModuleIterator* retro_module_iterator_construct (GType object_type, gchar** lookup_paths, int 
lookup_paths_length1, gboolean recursive); */
+/* static gchar** _vala_array_dup1 (gchar** self, int length); */
+/* static void _g_free0_ (gpointer var); */
+/* static RetroModuleIterator* retro_module_iterator_new_for_subdirectory (const gchar* lookup_path, 
GHashTable* visited_paths); */
+/* static RetroModuleIterator* retro_module_iterator_construct_for_subdirectory (GType object_type, const 
gchar* lookup_path, GHashTable* visited_paths); */
+/* RetroCoreDescriptor* retro_module_iterator_get (RetroModuleIterator* self); */
+/* gboolean retro_module_iterator_next (RetroModuleIterator* self); */
+/* static void retro_module_iterator_set_current_directory_as_visited (RetroModuleIterator* self); */
+/* static gboolean retro_module_iterator_next_in_current_path (RetroModuleIterator* self, GError** error); */
+/* static gboolean retro_module_iterator_was_current_directory_visited (RetroModuleIterator* self); */
+/* static gboolean retro_module_iterator_next_in_sub_directory (RetroModuleIterator* self, GError** error); 
*/
+/* RetroCoreDescriptor* retro_core_descriptor_new (const gchar* filename, GError** error); */
+/* RetroCoreDescriptor* retro_core_descriptor_construct (GType object_type, const gchar* filename, GError** 
error); */
+/* static void retro_module_iterator_finalize (RetroModuleIterator *obj); */
+/* static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func); */
+/* static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func); */
+
+/* static gchar** _vala_array_dup1 (gchar** self, int length) { */
+/*   gchar** result; */
+/*   int i; */
+/*   result = g_new0 (gchar*, length + 1); */
+/*   for (i = 0; i < length; i++) { */
+/*     gchar* _tmp0_; */
+/*     _tmp0_ = g_strdup (self[i]); */
+/*     result[i] = _tmp0_; */
+/*   } */
+/*   return result; */
+/* } */
+
+/* static void _g_free0_ (gpointer var) { */
+/*   var = (g_free (var), NULL); */
+/* } */
+
+/* RetroModuleIterator* retro_module_iterator_construct (GType object_type, gchar** lookup_paths, int 
lookup_paths_length1, gboolean recursive) { */
+/*   RetroModuleIterator* self = NULL; */
+/*   gchar** _tmp0_; */
+/*   gint _tmp0__length1; */
+/*   gchar** _tmp1_; */
+/*   gint _tmp1__length1; */
+/*   gboolean _tmp2_; */
+/*   GHashFunc _tmp3_; */
+/*   GEqualFunc _tmp4_; */
+/*   GHashTable* _tmp5_; */
+/*   self = (RetroModuleIterator*) g_type_create_instance (object_type); */
+/*   _tmp0_ = lookup_paths; */
+/*   _tmp0__length1 = lookup_paths_length1; */
+/*   _tmp1_ = (_tmp0_ != NULL) ? _vala_array_dup1 (_tmp0_, _tmp0__length1) : ((gpointer) _tmp0_); */
+/*   _tmp1__length1 = _tmp0__length1; */
+/*   self->directories = (_vala_array_free (self->directories, self->directories_length1, (GDestroyNotify) 
g_free), NULL); */
+/*   self->directories = _tmp1_; */
+/*   self->directories_length1 = _tmp1__length1; */
+/*   self->_directories_size_ = self->directories_length1; */
+/*   _tmp2_ = recursive; */
+/*   self->recursive = _tmp2_; */
+/*   _tmp3_ = g_str_hash; */
+/*   _tmp4_ = g_str_equal; */
+/*   _tmp5_ = g_hash_table_new_full (_tmp3_, _tmp4_, NULL, _g_free0_); */
+/*   _g_hash_table_unref0 (self->visited); */
+/*   self->visited = _tmp5_; */
+/*   return self; */
+/* } */
+
+/* RetroModuleIterator* retro_module_iterator_new (gchar** lookup_paths, int lookup_paths_length1, gboolean 
recursive) { */
+/*   return retro_module_iterator_construct (RETRO_TYPE_MODULE_ITERATOR, lookup_paths, lookup_paths_length1, 
recursive); */
+/* } */
+
+/* static gpointer _g_hash_table_ref0 (gpointer self) { */
+/*   return self ? g_hash_table_ref (self) : NULL; */
+/* } */
+
+/* static RetroModuleIterator* retro_module_iterator_construct_for_subdirectory (GType object_type, const 
gchar* lookup_path, GHashTable* visited_paths) { */
+/*   RetroModuleIterator* self = NULL; */
+/*   const gchar* _tmp0_; */
+/*   gchar* _tmp1_; */
+/*   gchar** _tmp2_; */
+/*   GHashTable* _tmp3_; */
+/*   GHashTable* _tmp4_; */
+/*   g_return_val_if_fail (lookup_path != NULL, NULL); */
+/*   g_return_val_if_fail (visited_paths != NULL, NULL); */
+/*   self = (RetroModuleIterator*) g_type_create_instance (object_type); */
+/*   _tmp0_ = lookup_path; */
+/*   _tmp1_ = g_strdup (_tmp0_); */
+/*   _tmp2_ = g_new0 (gchar*, 1 + 1); */
+/*   _tmp2_[0] = _tmp1_; */
+/*   self->directories = (_vala_array_free (self->directories, self->directories_length1, (GDestroyNotify) 
g_free), NULL); */
+/*   self->directories = _tmp2_; */
+/*   self->directories_length1 = 1; */
+/*   self->_directories_size_ = self->directories_length1; */
+/*   self->recursive = TRUE; */
+/*   _tmp3_ = visited_paths; */
+/*   _tmp4_ = _g_hash_table_ref0 (_tmp3_); */
+/*   _g_hash_table_unref0 (self->visited); */
+/*   self->visited = _tmp4_; */
+/*   return self; */
+/* } */
+
+/* static RetroModuleIterator* retro_module_iterator_new_for_subdirectory (const gchar* lookup_path, 
GHashTable* visited_paths) { */
+/*   return retro_module_iterator_construct_for_subdirectory (RETRO_TYPE_MODULE_ITERATOR, lookup_path, 
visited_paths); */
+/* } */
+
+/* static gpointer _g_object_ref0 (gpointer self) { */
+/*   return self ? g_object_ref (self) : NULL; */
+/* } */
+
+/* RetroCoreDescriptor* retro_module_iterator_get (RetroModuleIterator* self) { */
+/*   RetroCoreDescriptor* result = NULL; */
+/*   RetroCoreDescriptor* _tmp0_; */
+/*   RetroCoreDescriptor* _tmp1_; */
+/*   g_return_val_if_fail (RETRO_IS_MODULE_ITERATOR (self) != NULL, NULL); */
+/*   _tmp0_ = self->core_descriptor; */
+/*   _tmp1_ = _g_object_ref0 (_tmp0_); */
+/*   result = _tmp1_; */
+/*   return result; */
+/* } */
+
+static gboolean
+retro_module_iterator_was_current_directory_visited (RetroModuleIterator *self)
+{
+  GFile *current_directory_file;
+  gchar *current_directory_path;
+  gboolean result;
+
+  g_return_val_if_fail (RETRO_IS_MODULE_ITERATOR (self) != NULL, FALSE);
+
+  current_directory_file = g_file_new_for_path (self->directories[self->current_directory]);
+  current_directory_path = g_file_get_path (current_directory_file);
+  g_object_unref (current_directory_file);
+  result = g_hash_table_contains (self->visited, current_directory_path);
+  g_free (current_directory_path);
+
+  return result;
+}
+
+static void
+retro_module_iterator_set_current_directory_as_visited (RetroModuleIterator *self)
+{
+  GFile *current_directory_file;
+  gchar *current_directory_path;
+
+  g_return_val_if_fail (RETRO_IS_MODULE_ITERATOR (self) != NULL, FALSE);
+
+  current_directory_file = g_file_new_for_path (self->directories[self->current_directory]);
+  current_directory_path = g_file_get_path (current_directory_file);
+  g_object_unref (current_directory_file);
+  g_hash_table_add (self->visited, current_directory_path);
+}
+
+gboolean
+retro_module_iterator_next (RetroModuleIterator *self)
+{
+  gboolean next_in_current_path;
+  GError *tmp_error = NULL;
+
+  g_return_val_if_fail (RETRO_IS_MODULE_ITERATOR (self) != NULL, FALSE);
+
+  while (self->current_directory < self->directories_length1) {
+    retro_module_iterator_set_current_directory_as_visited (self);
+
+    next_in_current_path = retro_module_iterator_next_in_current_path (self, &tmp_error);
+    if (G_UNLIKELY (tmp_error != NULL)) {
+      g_debug ("%s", tmp_error->message);
+      g_clear_error (&tmp_error);
+      next_in_current_path = FALSE;
+    }
+
+    if (next_in_current_path)
+      return TRUE;
+
+    while (self->current_directory < self->directories_length1 &&
+           retro_module_iterator_was_current_directory_visited (self))
+      self->current_directory++;
+  }
+
+  g_clear_object (&self->file_enumerator);
+  g_clear_object (&self->core_descriptor);
+  if (self->sub_directory != NULL) {
+    retro_module_iterator_unref (self->sub_directory);
+    self->sub_directory = NULL;
+  }
+
+  return FALSE;
+}
+
+/* static gboolean retro_module_iterator_next_in_current_path (RetroModuleIterator* self, GError** error) { 
*/
+/*   gboolean result = FALSE; */
+/*   gboolean _tmp0_ = FALSE; */
+/*   RetroModuleIterator* _tmp1_; */
+/*   GFile* directory = NULL; */
+/*   gchar** _tmp5_; */
+/*   gint _tmp5__length1; */
+/*   gint _tmp6_; */
+/*   const gchar* _tmp7_; */
+/*   GFile* _tmp8_; */
+/*   GFileEnumerator* _tmp9_; */
+/*   GFileEnumerator* _tmp15_; */
+/*   GError *tmp_error = NULL; */
+
+/*   g_return_val_if_fail (RETRO_IS_MODULE_ITERATOR (self) != NULL, FALSE); */
+
+/*   if (self->sub_directory != NULL && */
+/*       retro_module_iterator_next_in_sub_directory (self)) */
+/*     return TRUE; */
+
+/*   directory = g_file_new_for_path (self->directories[self->current_directory]); */
+
+/*   if (self->file_enumerator == NULL) { */
+/*     self->file_enumerator = g_file_enumerate_children (directory, "", 
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &tmp_error); */
+/*     if (G_UNLIKELY (tmp_error != NULL)) { */
+/*       g_propagate_error (error, tmp_error); */
+/*       g_object_unref (directory); */
+/*       g_clear_object (&self->file_enumerator); */
+
+/*       return FALSE; */
+/*     } */
+/*   } */
+
+/*   if (self->file_enumerator == NULL) { */
+/*     g_object_unref (directory); */
+
+/*     return FALSE; */
+/*   } */
+
+/*   { */
+/*     GFileInfo *info; */
+/*     info = g_file_enumerator_next_file (self->file_enumerator, NULL, &tmp_error); */
+/*     if (G_UNLIKELY (tmp_error != NULL)) { */
+/*       g_propagate_error (error, tmp_error); */
+/*       g_object_unref (directory); */
+
+/*       return FALSE; */
+/*     } */
+/*     { */
+/*       gboolean _tmp19_ = FALSE; */
+/*       _tmp19_ = TRUE; */
+/*       while (TRUE) { */
+/*         GFileInfo* _tmp25_; */
+/*         gboolean _tmp26_ = FALSE; */
+/*         gboolean _tmp27_ = FALSE; */
+/*         gboolean _tmp28_; */
+/*         gchar* core_descriptor_basename = NULL; */
+/*         GFileInfo* _tmp49_; */
+/*         const gchar* _tmp50_; */
+/*         gchar* _tmp51_; */
+/*         const gchar* _tmp52_; */
+/*         gboolean _tmp53_; */
+/*         GFile* core_descriptor_file = NULL; */
+/*         GFile* _tmp54_; */
+/*         const gchar* _tmp55_; */
+/*         GFile* _tmp56_; */
+/*         gchar* core_descriptor_path = NULL; */
+/*         GFile* _tmp57_; */
+/*         gchar* _tmp58_; */
+/*         if (!_tmp19_) { */
+/*           GFileInfo* _tmp20_ = NULL; */
+/*           GFileInfo* _tmp24_; */
+/*           _tmp20_ = g_file_enumerator_next_file (self->file_enumerator, NULL, &tmp_error); */
+/*           if (G_UNLIKELY (tmp_error != NULL)) { */
+/*             g_propagate_error (error, tmp_error); */
+/*             _g_object_unref0 (info); */
+/*             _g_object_unref0 (directory); */
+
+/*             return FALSE; */
+/*           } */
+/*           _tmp24_ = _tmp20_; */
+/*           _tmp20_ = NULL; */
+/*           _g_object_unref0 (info); */
+/*           info = _tmp24_; */
+/*           _g_object_unref0 (_tmp20_); */
+/*         } */
+/*         _tmp19_ = FALSE; */
+
+/*         if (info == NULL) */
+/*           break; */
+
+/*         if (self->recursive && */
+/*             g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { */
+/*           RetroModuleIterator* _tmp31_; */
+/*           _tmp31_ = self->sub_directory; */
+/*           _tmp26_ = _tmp31_ == NULL; */
+/*         } else { */
+/*           _tmp26_ = FALSE; */
+/*         } */
+/*         if (_tmp26_) { */
+/*           gchar *sub_directory_basename; */
+/*           GFile *sub_directory_file; */
+/*           gchar *sub_directory_path; */
+/*           RetroModuleIterator *sub_directory_iterator; */
+
+
+/*           sub_directory_basename = g_strdup (g_file_info_get_name (info); */
+/*           sub_directory_file = g_file_get_child (directory, sub_directory_basename); */
+/*           g_free (sub_directory_basename); */
+/*           sub_directory_path = g_file_get_path (sub_directory_file); */
+/*           g_object_unref (sub_directory_file); */
+/*           if (g_hash_table_contains (self->visited, sub_directory_path) { */
+/*             g_free (sub_directory_path); */
+
+/*             continue; */
+/*           } */
+
+/*           sub_directory_iterator = retro_module_iterator_new_for_subdirectory (sub_directory_path, 
self->visited); */
+/*           g_free (sub_directory_path); */
+/*           g_object_set (&self->sub_directory, sub_directory_iterator); */
+/*           if (retro_module_iterator_next_in_sub_directory (self) { */
+/*             _g_object_unref0 (info); */
+/*             _g_object_unref0 (directory); */
+
+/*             return TRUE; */
+/*           } */
+/*           else */
+/*             continue; */
+/*         } */
+
+/*         core_descriptor_basename = g_file_info_get_name (info); */
+/*         if (!g_str_has_suffix (core_descriptor_basename, ".libretro") */
+/*           continue; */
+
+/*         core_descriptor_file = g_file_get_child (directory, core_descriptor_basename); */
+/*         core_descriptor_path = g_file_get_path (core_descriptor_file); */
+/*         { */
+/*           RetroCoreDescriptor *core_descriptor; */
+/*           core_descriptor = retro_core_descriptor_new (core_descriptor_path, &tmp_error); */
+/*           if (G_UNLIKELY (tmp_error != NULL)) { */
+/*             g_debug ("%s", tmp_error->message); */
+/*             g_error_free (tmp_error); */
+/*             g_propagate_error (error, tmp_error); */
+/*             g_free (core_descriptor_path); */
+/*             g_object_unref (core_descriptor_file); */
+/*             g_object_unref (info); */
+/*             g_object_unref (directory); */
+
+/*             continue; */
+/*           } */
+/*           g_set_object (&self->core_descriptor, core_descriptor); */
+/*           g_free (core_descriptor_path); */
+/*           g_object_unref (core_descriptor_file); */
+/*           g_object_unref (info); */
+/*           g_object_unref (directory); */
+
+/*           return TRUE; */
+/*         } */
+/*         _g_free0 (core_descriptor_path); */
+/*         _g_object_unref0 (core_descriptor_file); */
+/*       } */
+/*     } */
+/*     _g_object_unref0 (info); */
+/*   } */
+
+/*   g_clear_object (&directory); */
+
+/*   return FALSE; */
+/* } */
+
+// FIXME static
+gboolean
+retro_module_iterator_next_in_sub_directory (RetroModuleIterator *self)
+{
+  g_return_val_if_fail (RETRO_IS_MODULE_ITERATOR (self) != NULL, FALSE);
+
+  if (retro_module_iterator_next (self->sub_directory)) {
+    if (self->core_descriptor != NULL)
+      g_object_unref (self->core_descriptor);
+
+    self->core_descriptor = retro_module_iterator_get (self->sub_directory);
+
+    return TRUE;
+  }
+
+  if (self->sub_directory != NULL) {
+    retro_module_iterator_unref (self->sub_directory);
+    self->sub_directory = NULL;
+  }
+
+  return FALSE;
+}
diff --git a/retro-gtk/retro-module-iterator.vala b/retro-gtk/retro-module-iterator.vala
index e106fb1..f8a8802 100644
--- a/retro-gtk/retro-module-iterator.vala
+++ b/retro-gtk/retro-module-iterator.vala
@@ -1,13 +1,13 @@
 // This file is part of retro-gtk. License: GPL-3.0+.
 
 public class Retro.ModuleIterator {
-       private string[] directories;
-       private bool recursive;
-       private int current_directory;
-       private FileEnumerator file_enumerator;
-       private CoreDescriptor? core_descriptor;
-       private ModuleIterator? sub_directory;
-       private GenericSet<string> visited;
+       internal string[] directories;
+       internal bool recursive;
+       internal int current_directory;
+       internal FileEnumerator file_enumerator;
+       internal CoreDescriptor? core_descriptor;
+       internal ModuleIterator? sub_directory;
+       internal GenericSet<string> visited;
 
        internal ModuleIterator (string[] lookup_paths, bool recursive) {
                directories = lookup_paths;
@@ -15,7 +15,7 @@ public class Retro.ModuleIterator {
                visited = new GenericSet<string> (str_hash, str_equal);
        }
 
-       private ModuleIterator.for_subdirectory (string lookup_path, GenericSet<string> visited_paths) {
+       internal ModuleIterator.for_subdirectory (string lookup_path, GenericSet<string> visited_paths) {
                directories = { lookup_path };
                recursive = true;
                visited = visited_paths;
@@ -25,30 +25,9 @@ public class Retro.ModuleIterator {
                return core_descriptor;
        }
 
-       public bool next () {
-               while (current_directory < directories.length) {
-                       set_current_directory_as_visited ();
+       public extern bool next ();
 
-                       try {
-                               if (next_in_current_path ())
-                                       return true;
-                       }
-                       catch (Error e) {
-                               debug (e.message);
-                       }
-
-                       while (current_directory < directories.length && was_current_directory_visited ())
-                               current_directory++;
-               }
-
-               file_enumerator = null;
-               core_descriptor = null;
-               sub_directory = null;
-
-               return false;
-       }
-
-       private bool next_in_current_path () throws Error {
+       internal bool next_in_current_path () throws Error {
                if (sub_directory != null && next_in_sub_directory ())
                        return true;
 
@@ -97,29 +76,6 @@ public class Retro.ModuleIterator {
                return false;
        }
 
-       private bool next_in_sub_directory () throws Error {
-               if (sub_directory.next ()) {
-                       core_descriptor = sub_directory.get ();
-
-                       return true;
-               }
-
-               sub_directory = null;
-
-               return false;
-       }
-
-       private void set_current_directory_as_visited () {
-               var current_directory_file = File.new_for_path (directories[current_directory]);
-               var current_directory_path = current_directory_file.get_path ();
-               visited.add (current_directory_path);
-       }
-
-       private bool was_current_directory_visited () {
-               var current_directory_file = File.new_for_path (directories[current_directory]);
-               var current_directory_path = current_directory_file.get_path ();
-
-               return visited.contains (current_directory_path);
-       }
+       private extern bool next_in_sub_directory ();
 }
 


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