From bb65333ef00df02dbf6bd83294b4df49e64ea325 Mon Sep 17 00:00:00 2001 From: forcer Date: Sun, 11 Sep 2005 20:05:00 +0000 Subject: Initial commit (CVS 2005-09-11) darcs-hash:20050911200506-2189f-48a136015e33465c3cf09940ce935ec2203df463.gz --- emms-info-later-do.el | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 emms-info-later-do.el (limited to 'emms-info-later-do.el') diff --git a/emms-info-later-do.el b/emms-info-later-do.el new file mode 100644 index 0000000..da8acde --- /dev/null +++ b/emms-info-later-do.el @@ -0,0 +1,161 @@ +;;; emms-info-later-do.el --- Using later-do.el to load info + +;; Copyright (C) 2004 Free Software Foundation, Inc. + +;; Author: Ulrik Jensen +;; Keywords: + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +;; Boston, MA 02110-1301 USA + +;;; Commentary: + +;; This probably *won't* work if you have the info-cache disabled! + +;; Also, you need to have Jorgen Schäfers later-do.el in your +;; loadpath. That file can be found here: + +;; + +;; Possible problems: if the init-playlist hook gets called *after* +;; the playlists hook for the same thing gets called, we're doomed. + +;; To use this, add the following to your EMMS-configuration + +;; (require 'emms-info-later-do) +;; (emms-info-later-do-mode 1) + +;; If you want to use the playlist-buffer interface with this, you +;; need to add the following as well: + +;; (add-hook 'emms-info-later-do-read-info-functions +;; 'emms-pbi-entry-update-track) + +;; Which will make the PBI update it's entries as their info is being +;; loaded. + +;; To change the speed this loading happens with, see +;; `later-do-interval'. + +;;; Code: +(eval-when-compile (require 'cl)) +(require 'emms-info) +(condition-case nil + (require 'later-do) + (error nil)) + +(defvar emms-info-later-do-track-queue nil + "A list of tracks whose info needs to be updated.") + +(defun emms-info-later-do-mode (arg) + "Activate later-do-mode for loading info." + (interactive "p") + (if (and (numberp arg) (> arg 0)) + ;; this hook needs to be run before any hooks that uses the + ;; info-cache to do something productive. + (add-hook 'emms-playlist-changed-hook + 'emms-info-later-do-new-playlist) + (remove-hook 'emms-playlist-changed-hook + 'emms-info-later-do-new-playlist))) + +(defvar emms-info-later-do-read-info-functions nil + "Functions to run when the info for a track has been read. + +The functions will be called with one argument, TRACK, the track just +updated.") + +(defun emms-info-later-do-clean-queue () + "Remove all emms-info jobs from the later-do queue." + (let ((funcs later-do-list) + (everything-up-to nil)) + (while funcs + (let ((queued-job (car funcs))) + ;; if this job is an emms-info-later-do-process + (if (equal (car queued-job) 'emms-info-later-do-process) + (progn + ;; Remove this item from the list, and continue in a clean + ;; way! + (let ((everything-after (cdr funcs))) + (setq later-do-list (append everything-up-to + everything-after)) + (setq funcs everything-after))) + ;; Add this item to everything-up-to + (setq everything-up-to (append everything-up-to + (list queued-job))) + (setq funcs (cdr funcs))))))) + +(defun emms-info-later-do-process () + "Load the info for one single item. + +Also set up loading the next item, if there are anymore." + (when emms-info-later-do-track-queue + (let ((track (car emms-info-later-do-track-queue))) + ;; remove track from queue + (setq emms-info-later-do-track-queue + (cdr emms-info-later-do-track-queue)) + ;; load info for track -- this is kinda redundant, considering + ;; that info-get will update the cache when forced to go around + ;; it, but just in case. + (emms-info-set-cached track (emms-info-get track t)) + ;; notify the world of our heroic conquest! + (run-hook-with-args 'emms-info-later-do-read-info-functions + track) + (if emms-info-later-do-track-queue + ;; we still have a queue, run us again! + (later-do 'emms-info-later-do-process) + (message "Lazy loading of info complete!"))))) + +(defun emms-info-later-do-new-playlist () + "Function that gets ready to lazy-load a new playlist. + +Should be called from `emms-playlist-changed-hook'." + ;; Cleaning up the potential old playlist/process: + ;; Clean up any currently running emms-info-later-do-process lists + (emms-info-later-do-clean-queue) + ;; Remove the cache for any tracks currently containing placeholder + ;; info-objects. + (while emms-info-later-do-track-queue + ;; This track still holds a placeholder info-object, remove that. + (emms-info-set-cached (car emms-info-later-do-track-queue) nil) + (setq emms-info-later-do-track-queue (cdr emms-info-later-do-track-queue))) + (setq emms-info-later-do-track-queue nil) + ;; Processing the new playlist: + ;; For all tracks where info isn't already cached, create a + ;; placeholder info object, so modules requesting info get + ;; *something*. Accumulate indices for each track needing to be + ;; reread, and add them to the queue. + (let ((tracks (emms-playlist-get-playlist)) + (idx 0)) + (while (< idx (length tracks)) + (let* ((curtrack (aref tracks idx)) + (curinfo (emms-info-get-cached curtrack))) + (unless curinfo + ;; Mark this one as needing to be loaded + (add-to-list 'emms-info-later-do-track-queue curtrack t) + ;; Setup a placeholder-info object in the cache + (emms-info-set-cached + curtrack + (make-emms-info :title "" :album "" + :artist "" :note "" + :file (emms-track-name curtrack))))) + (setq idx (1+ idx)))) + ;; Queue loading the info for each track, if any tracks need to be loaded. + (when emms-info-later-do-track-queue + ;; Process the first item synchronously to avoid having it displayed in + ;; the mode line before its meta-data has been fetched. + (emms-info-later-do-process))) + +(provide 'emms-info-later-do) +;;; emms-info-later-do.el ends here -- cgit v1.2.3