Peter Siebel - Practical Common Lisp
Здесь есть возможность читать онлайн «Peter Siebel - Practical Common Lisp» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2005, ISBN: 2005, Издательство: Apress, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.
- Название:Practical Common Lisp
- Автор:
- Издательство:Apress
- Жанр:
- Год:2005
- ISBN:1-59059-239-5
- Рейтинг книги:4 / 5. Голосов: 1
-
Избранное:Добавить в избранное
- Отзывы:
-
Ваша оценка:
- 80
- 1
- 2
- 3
- 4
- 5
Practical Common Lisp: краткое содержание, описание и аннотация
Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Practical Common Lisp»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.
Practical Common Lisp — читать онлайн бесплатно полную книгу (весь текст) целиком
Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Practical Common Lisp», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
(ipaddr-to-dotted (remote-host (request-socket request))))
The function request-socketis part of AllegroServe, while remote-hostand ipaddr-to-dottedare part of Allegro's socket library.
To make a playlist usable as a song source by the Shoutcast server, you need to define methods on current-song, still-current-p, and maybe-move-to-next-songthat specialize their sourceparameter on playlist. The current-songmethod is already taken care of: by defining the accessor current-songon the eponymous slot, you automatically got a current-songmethod specialized on playlistthat returns the value of that slot. However, to make accesses to the playlistthread safe, you need to lock the playlistbefore accessing the current-songslot. In this case, the easiest way is to define an :aroundmethod like the following:
(defmethod current-song :around ((playlist playlist))
(with-playlist-locked (playlist) (call-next-method)))
Implementing still-current-pis also quite simple, assuming you can be sure that current-songgets updated with a new songobject only when the current song actually changes. Again, you need to acquire the process lock to ensure you get a consistent view of the playlist's state.
(defmethod still-current-p (song (playlist playlist))
(with-playlist-locked (playlist)
(eql song (current-song playlist))))
The trick, then, is to make sure the current-songslot gets updated at the right times. However, the current song can change in a number of ways. The obvious one is when the Shoutcast server calls maybe-move-to-next-song. But it can also change when songs are added to the playlist, when the Shoutcast server has run out of songs, or even if the playlist's repeat mode is changed.
Rather than trying to write code specific to every situation to determine whether to update current-song, you can define a function, update-current-if-necessary, that updates current-songif the songobject in current-songno longer matches the file that the current-idxslot says should be playing. Then, if you call this function after any manipulation of the playlist that could possibly put those two slots out of sync, you're sure to keep current-songset properly. Here are update-current-if-necessaryand its helper functions:
(defun update-current-if-necessary (playlist)
(unless (equal (file (current-song playlist))
(file-for-current-idx playlist))
(reset-current-song playlist)))
(defun file-for-current-idx (playlist)
(if (at-end-p playlist)
nil
(column-value (nth-row (current-idx playlist) (songs-table playlist)) :file)))
(defun at-end-p (playlist)
(>= (current-idx playlist) (table-size (songs-table playlist))))
You don't need to add locking to these functions since they'll be called only from functions that will take care of locking the playlist first.
The function reset-current-songintroduces one more wrinkle: because you want the playlist to provide an endless stream of MP3s to the client, you don't want to ever set current-songto NIL . Instead, when a playlist runs out of songs to play—when songs-tableis empty or after the last song has been played and repeatis set to :none—then you need to set current-songto a special song whose file is an MP3 of silence [308] Unfortunately, because of licensing issues around the MP3 format, it's not clear that it's legal for me to provide you with such an MP3 without paying licensing fees to Fraunhofer IIS. I got mine as part of the software that came with my Slimp3 from Slim Devices. You can grab it from their Subversion repository via the Web at http://svn.slimdevices.com/*checkout*/trunk/server/HTML/EN/html/silentpacket.mp3?rev=2 . Or buy a Squeezebox, the new, wireless version of Slimp3, and you'll get silentpacket.mp3 as part of the software that comes with it. Or find an MP3 of John Cage's piece 4'33" .
and whose title explains why no music is playing. Here's some code to define two parameters, *empty-playlist-song*and *end-of-playlist-song*, each set to a song with the file named by *silence-mp3*as their file and an appropriate title:
(defparameter *silence-mp3* ...)
(defun make-silent-song (title &optional (file *silence-mp3*))
(make-instance
'song
:file file
:title title
:id3-size (if (id3-p file) (size (read-id3 file)) 0)))
(defparameter *empty-playlist-song* (make-silent-song "Playlist empty."))
(defparameter *end-of-playlist-song* (make-silent-song "At end of playlist."))
reset-current-songuses these parameters when the current-idxdoesn't point to a row in songs-table. Otherwise, it sets current-songto a songobject representing the current row.
(defun reset-current-song (playlist)
(setf
(current-song playlist)
(cond
((empty-p playlist) *empty-playlist-song*)
((at-end-p playlist) *end-of-playlist-song*)
(t (row->song (nth-row (current-idx playlist) (songs-table playlist)))))))
(defun row->song (song-db-entry)
(with-column-values (file song artist album id3-size) song-db-entry
(make-instance
'song
:file file
:title (format nil "~a by ~a from ~a" song artist album)
:id3-size id3-size)))
(defun empty-p (playlist)
(zerop (table-size (songs-table playlist))))
Now, at last, you can implement the method on maybe-move-to-next-songthat moves current-idxto its next value, based on the playlist's repeat mode, and then calls update-current-if-necessary. You don't change current-idxwhen it's already at the end of the playlist because you want it to keep its current value, so it'll point at the next song you add to the playlist. This function must lock the playlist before manipulating it since it's called by the Shoutcast server code, which doesn't do any locking.
(defmethod maybe-move-to-next-song (song (playlist playlist))
(with-playlist-locked (playlist)
(when (still-current-p song playlist)
(unless (at-end-p playlist)
(ecase (repeat playlist)
(:song) ; nothing changes
(:none (incf (current-idx playlist)))
(:all (setf (current-idx playlist)
(mod (1+ (current-idx playlist))
(table-size (songs-table playlist)))))))
(update-current-if-necessary playlist))))
Manipulating the Playlist
The rest of the playlist code is functions used by the Web interface to manipulate playlistobjects, including adding and deleting songs, sorting and shuffling, and setting the repeat mode. As in the helper functions in the previous section, you don't need to worry about locking in these functions because, as you'll see, the lock will be acquired in the Web interface function that calls these.
Интервал:
Закладка:
Похожие книги на «Practical Common Lisp»
Представляем Вашему вниманию похожие книги на «Practical Common Lisp» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Practical Common Lisp» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.