commit f67db4d199ee46afd74f30165a8179c03bb35016
Author: phantomjinx <p.g.richard...@phantomjinx.co.uk>
Date:   Tue Mar 15 20:49:22 2011 +0000

    Fix save if needed to always save on threshold
    
    * file.c
     * Init a signal that is fired upon the addition of a track
     * The callback added one to a count for the track's itdb.
     * When the count reaches the threshold, the itdb is saved.
     * This is a single point of saving and will always be fired upon track
       addition regardless of how the track was added, eg. by directory, 
playlist
    
    * Removal of all locations where save is called upon reaching threshold as
      no longer necessary

 libgtkpod/file.c                                   |  131 ++++++++++++++------
 libgtkpod/gtkpod_app_iface.c                       |    2 +-
 .../playlist_display/playlist_display_actions.c    |    7 -
 3 files changed, 91 insertions(+), 49 deletions(-)
---
diff --git a/libgtkpod/file.c b/libgtkpod/file.c
index 5f288bb..6acd4de 100644
--- a/libgtkpod/file.c
+++ b/libgtkpod/file.c
@@ -59,6 +59,72 @@
 static const gchar *imageext[] =
     { ".jpg", ".jpeg", ".png", ".pbm", ".pgm", ".ppm", ".tif", ".tiff", 
".gif", NULL };
 
+/*
+ * Struct to hold the track added signal and
+ * hashtable of itdb to count of tracks added
+ * so far
+ */
+typedef struct {
+    gulong file_added_signal_id;
+    GHashTable *itdb_tracks_count;
+} TrackMonitor;
+
+/*
+ * Pair struct for insertion into the TrackMonitor
+ * hashtable
+ */
+typedef struct {
+    guint64 *id;
+    gint count;
+} TrackMonitorPair;
+
+/* Single TrackMonitor instance */
+static TrackMonitor *trkmonitor = NULL;
+
+/**
+ * Callback fired when a new track is added to an itdb.
+ * Will be fired from playlist, directory and file functions
+ */
+static void file_track_added_cb(GtkPodApp *app, gpointer tk, gpointer data) {
+    Track *track = tk;
+    if (!track)
+        return;
+
+    g_return_if_fail(track->itdb);
+    g_return_if_fail(trkmonitor);
+
+    guint64 *key = &track->itdb->id;
+    TrackMonitorPair *value = 
g_hash_table_lookup(trkmonitor->itdb_tracks_count, key);
+    if (!value) {
+        value = g_new0(TrackMonitorPair, 1);
+        value->id = key;
+        value->count = 1;
+    } else {
+        value->count++;
+    }
+
+    /* save every ${file_threshold} files but do at least ${file_theshold} 
first*/
+    int threshold = prefs_get_int("file_saving_threshold");
+    if (value->count >= threshold) {
+        gp_save_itdb(track->itdb);
+        gtkpod_tracks_statusbar_update();
+        // Reset the count
+        value->count = 0;
+    }
+
+    g_hash_table_replace(trkmonitor->itdb_tracks_count, key, value);
+}
+
+/**
+ * Initialise the file added signal with the callback
+ */
+static void init_file_added_signal() {
+    if (! trkmonitor) {
+        trkmonitor = g_new0(TrackMonitor, 1);
+        trkmonitor->itdb_tracks_count = g_hash_table_new (g_int64_hash, 
g_int64_equal);
+        trkmonitor->file_added_signal_id = g_signal_connect (gtkpod_app, 
SIGNAL_TRACK_ADDED, G_CALLBACK (file_track_added_cb), NULL);
+    }
+}
 
 /* Determine the type of a file.
  *
@@ -89,15 +155,6 @@ FileType *determine_filetype(const gchar *path) {
     return type;
 }
 
-static void save_if_needed(gint count, iTunesDB *itdb) {
-    /* save every ${file_threshold} files but do at least ${file_theshold} 
first*/
-    int threshold = prefs_get_int("file_saving_threshold");
-    if (count >= threshold && count % threshold == 0) {
-        gp_save_itdb(itdb);
-        gtkpod_tracks_statusbar_update();
-    }
-}
-
 /** check a filename against the "excludes file mask" from the preferences
  *  and return TRUE if it should be excluded based on the mask
  */
@@ -265,8 +322,8 @@ add_playlist_by_filename(iTunesDB *itdb, gchar *plfile, 
Playlist *plitem, gint p
             else if (strcmp(plfile, filename) == 0) {
                 gtkpod_warning(_("Skipping '%s' to avoid adding playlist file 
recursively\n"), filename);
             }
-            else if (add_track_by_filename(itdb, filename, plitem, 
prefs_get_int("add_recursively"), addtrackfunc, data)) {
-                save_if_needed(tracks, itdb);
+            else {
+                add_track_by_filename(itdb, filename, plitem, 
prefs_get_int("add_recursively"), addtrackfunc, data);
             }
             g_free(filename);
         }
@@ -289,8 +346,23 @@ add_playlist_by_filename(iTunesDB *itdb, gchar *plfile, 
Playlist *plitem, gint p
  *                                                                  *
  \*------------------------------------------------------------------*/
 
-
-static gint add_directory_by_name_internal(iTunesDB *itdb, gchar *name, 
Playlist *plitem, gboolean descend, gint *filecount, AddTrackFunc addtrackfunc, 
gpointer data) {
+/*
+ * Add all files in directory and subdirectories.
+ *
+ * If @name is a regular file, just add that.
+ * If @plitem != NULL, add tracks also to Playlist @plitem
+ * @descend:    TRUE: add recursively
+ *                      FALSE: don't enter subdirectories
+ * @addtrackfunc:
+ *                      if != NULL this will be called instead of
+ *                      "add_track_to_playlist () -- used for dropping
+ *                      tracks at a specific position in the track view
+ *
+ * return:
+ *              value indicating number of added tracks.
+ */
+/* */
+gint add_directory_by_name(iTunesDB *itdb, gchar *name, Playlist *plitem, 
gboolean descend, AddTrackFunc addtrackfunc, gpointer data) {
     gint result = 0;
 
     g_return_val_if_fail (itdb, 0);
@@ -306,7 +378,7 @@ static gint add_directory_by_name_internal(iTunesDB *itdb, 
gchar *name, Playlist
                 if (next != NULL) {
                     gchar *nextfull = g_build_filename(name, next, NULL);
                     if (descend || !g_file_test(nextfull, G_FILE_TEST_IS_DIR)) 
{
-                        result += add_directory_by_name_internal(itdb, 
nextfull, plitem, descend, filecount, addtrackfunc, data);
+                        result += add_directory_by_name(itdb, nextfull, 
plitem, descend, addtrackfunc, data);
                     }
                     g_free(nextfull);
                 }
@@ -318,37 +390,12 @@ static gint add_directory_by_name_internal(iTunesDB 
*itdb, gchar *name, Playlist
         release_widgets();
     }
     else {
-        if (add_track_by_filename(itdb, name, plitem, descend, addtrackfunc, 
data)) {
-            *filecount = *filecount + 1;
-            save_if_needed(*filecount, itdb);
-        }
-        result += *filecount;
+        if (add_track_by_filename(itdb, name, plitem, descend, addtrackfunc, 
data))
+            result++;
     }
     return result;
 }
 
-/*
- * Add all files in directory and subdirectories.
- *
- * If @name is a regular file, just add that.
- * If @plitem != NULL, add tracks also to Playlist @plitem
- * @descend:    TRUE: add recursively
- *                      FALSE: don't enter subdirectories
- * @addtrackfunc:
- *                      if != NULL this will be called instead of
- *                      "add_track_to_playlist () -- used for dropping
- *                      tracks at a specific position in the track view
- *
- * return:
- *              value indicating number of added tracks.
- */
-/* */
-gint add_directory_by_name(iTunesDB *itdb, gchar *name, Playlist *plitem, 
gboolean descend, AddTrackFunc addtrackfunc, gpointer data) {
-    /* Uses internal method so that a count parameter can be added for saving 
purposes. */
-    gint filecount = 0;
-    return add_directory_by_name_internal(itdb, name, plitem, descend, 
&filecount, addtrackfunc, data);
-}
-
 /*------------------------------------------------------------------*\
  *                                                                  *
  *      Fill in track struct with data from file                     *
@@ -1462,6 +1509,8 @@ gboolean add_track_by_filename(iTunesDB *itdb, gchar 
*fname, Playlist *plitem, g
     mpl = itdb_playlist_mpl(itdb);
     g_return_val_if_fail (mpl, FALSE);
 
+    init_file_added_signal();
+
     if (!plitem)
         plitem = mpl;
 
diff --git a/libgtkpod/gtkpod_app_iface.c b/libgtkpod/gtkpod_app_iface.c
index 2d1b2b6..612d367 100644
--- a/libgtkpod/gtkpod_app_iface.c
+++ b/libgtkpod/gtkpod_app_iface.c
@@ -300,7 +300,7 @@ void gtkpod_track_added(Track *track) {
     g_return_if_fail (GTKPOD_IS_APP(gtkpod_app));
     g_return_if_fail (track);
 
-    g_signal_emit(gtkpod_app, gtkpod_app_signals[TRACK_UPDATED], 0, track);
+    g_signal_emit(gtkpod_app, gtkpod_app_signals[TRACK_ADDED], 0, track);
 }
 
 void gtkpod_track_removed(Track *track) {
diff --git a/plugins/playlist_display/playlist_display_actions.c 
b/plugins/playlist_display/playlist_display_actions.c
index 4c50881..37c7075 100644
--- a/plugins/playlist_display/playlist_display_actions.c
+++ b/plugins/playlist_display/playlist_display_actions.c
@@ -234,10 +234,8 @@ static void create_add_playlists_dialog(iTunesDB *itdb) {
 }
 
 static void fileselection_add_files(GSList* names, Playlist *playlist) {
-    gint count = 0;
     GSList* gsl; /* Current node in list */
     gboolean result = TRUE; /* Result of file adding */
-    int threshold = prefs_get_int("file_saving_threshold");
 
     /* If we don't have a playlist to add to, don't add anything */
     g_return_if_fail (playlist);
@@ -249,11 +247,6 @@ static void fileselection_add_files(GSList* names, 
Playlist *playlist) {
     for (gsl = names; gsl; gsl = gsl->next) {
         result
                 &= add_track_by_filename(playlist->itdb, gsl->data, playlist, 
prefs_get_int("add_recursively"), NULL, NULL);
-        count++;
-        if (count % threshold == 0) { /* update and save every ten tracks 
added */
-            gp_save_itdb(playlist->itdb);
-            gtkpod_tracks_statusbar_update();
-        }
     }
 
     /* Final save of remaining added tracks */

------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
gtkpod-cvs2 mailing list
gtkpod-cvs2@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2

Reply via email to