branch: externals/listen
commit dd35d78afe41adf10122931668f342e04e2dfc79
Author: Adam Porter <[email protected]>
Commit: Adam Porter <[email protected]>

    Fix: (listen-send*) Cleanup callback; update docstring
---
 listen-mpv.el | 59 +++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/listen-mpv.el b/listen-mpv.el
index 63bc3ab0d0..049b8dc0b8 100755
--- a/listen-mpv.el
+++ b/listen-mpv.el
@@ -242,29 +242,44 @@ Stops playing, clears playlist, adds FILE, and plays it."
     request-id))
 
 (cl-defmethod listen--send* ((player listen-player-mpv) command-args &key then)
-  "Send COMMAND to PLAYER"
+  "Send COMMAND-ARGS to PLAYER.
+The first string in COMMAND-ARGS is the MPV command, and the remaining
+ones are arguments to it.  If THEN is provided, it should be a function
+which will be called asynchronously with the message alist returned by
+MPV, and the request ID number is returned from this function;
+otherwise, the MPV command is called synchronously and the message alist
+is returned from this function."
   (listen--ensure player)
-  (pcase-let* (((cl-struct listen-player (etc (map :network-process))) player)
-               (request-id (cl-incf (map-elt (listen-player-etc player) 
:request-id)))
-               (`(,command . ,args) command-args)
-               (json (json-encode `(("command" ,command ,@args)
-                                    ("request_id" . ,request-id)))))
-    (listen-debug :buffer "*listen-mpv*" (listen-player-process player) json)
-    (process-send-string network-process json)
-    (process-send-string network-process "\n")
-    ;; TODO: Maybe check for success/error.
-    (if then
-        (progn
-          (setf (map-elt (map-elt (listen-player-etc player) :requests) 
request-id) then)
-          request-id)
-      (let ((value :unknown))
-        (setf (map-elt (map-elt (listen-player-etc player) :requests) 
request-id)
-              (lambda (msg)
-                ;; Save the callback's value to the map so we can retrieve it.
-                (setf value (map-elt msg 'data))))
-        (accept-process-output (listen-player-process player) 0.05)
-        ;; Return the then's value.
-        value))))
+  (cl-macrolet
+      ((wrap-callback (callback)
+         `(lambda (msg)
+            (unwind-protect
+                (funcall ,callback msg)
+              (setf (map-elt (listen-player-etc player) :requests)
+                    (map-delete (map-elt (listen-player-etc player) :requests) 
request-id))))))
+    (pcase-let* (((cl-struct listen-player (etc (map :network-process))) 
player)
+                 (request-id (cl-incf (map-elt (listen-player-etc player) 
:request-id)))
+                 (`(,command . ,args) command-args)
+                 (json (json-encode `(("command" ,command ,@args)
+                                      ("request_id" . ,request-id)))))
+      (listen-debug :buffer "*listen-mpv*" (listen-player-process player) json)
+      (process-send-string network-process json)
+      (process-send-string network-process "\n")
+      ;; TODO: Maybe check for success/error.
+      (if then
+          (progn
+            (setf (map-elt (map-elt (listen-player-etc player) :requests) 
request-id)
+                  (wrap-callback then))
+            request-id)
+        (let ((value :unknown))
+          (setf (map-elt (map-elt (listen-player-etc player) :requests) 
request-id)
+                (wrap-callback
+                 (lambda (msg)
+                   ;; Save the callback's value to the map so we can retrieve 
it.
+                   (setf value (map-elt msg 'data)))))
+          (accept-process-output (listen-player-process player) 0.05)
+          ;; Return the then's value.
+          value)))))
 
 (cl-defmethod listen--seek ((player listen-player-mpv) seconds)
   "Seek PLAYER to SECONDS."

Reply via email to