¿Se puede multiplicar Applescript?

7

Estoy escribiendo un Applescript para Spotify que se supone que debe hacer dos cosas:

  1. Registrar cada nueva canción reproducida.
  2. Cada N segundos verifica qué dispositivo de sonido se usa.

Lo hago (1) mediante un bucle simple que verifica qué parte de la pista queda y luego uso ese valor en una declaración de demora en el bucle (innecesario para ejecutar el bucle a toda velocidad). Sin embargo, N suele ser mucho más bajo que el tiempo restante de la pista actual. Por lo tanto, me gustaría que la tarea (2) se ejecute en un bucle separado con N-0.5 como valor de retardo. Básicamente quiero bucles para ejecutar simultáneamente desde el mismo script. ¿Es esto posible?

(Por supuesto, podría usar dos scripts separados, pero necesito distribuir esta solución cuando haya terminado, por lo tanto, es mejor una menor complejidad visual, es decir, dos scripts que se ejecutan simultáneamente ocupando espacio en el Dock, que necesitan ser iniciados, etc.). )

    
pregunta d-b 03.10.2017 - 13:55

4 respuestas

2

No es fácil. El concepto de procesos y subprocesos no está contenido en AppleScript.

Querrás otra herramienta para ese trabajo. Swift puede ser una buena opción, a menos que estés buscando Python o algo más establecido.

    
respondido por el bmike 03.10.2017 - 14:01
2

Límites de idioma

A partir de macOS 10.13, AppleScript no admite trivialmente multihilo en un solo script. Parece posible usar NSThread dentro de un AppleScript pero esto es complejo y lleva a una segunda limitación, la de la aplicación con la que se interactúa.

Límites de aplicación

Además de que el lenguaje AppleScript en sí no representa los subprocesos de forma nativa, es poco probable que la aplicación llamada se ocupe de los eventos de Apple de una manera óptima. MacOS pone en cola los eventos AppleEvents en un orden de primer en entrar, primero en salir (FIFO) para ser procesados por la aplicación.

La aplicación puede diferir las respuestas a AppleEvents de larga ejecución, pero esto requiere ingeniería adicional que pocas aplicaciones implementan. La mayoría de las aplicaciones se bloquearán hasta que AppleEvent se procese antes de ver el próximo AppleEvent.

Esto significa que un AppleScript multiproceso que se comunica con una aplicación única probablemente no verá las ganancias de rendimiento esperadas para el esfuerzo.

¿Bucle de evento único?

Podría abordar el problema con un solo bucle que trata múltiples eventos. El solo bucle podría dormir durante N segundos, despertar y lidiar con las tareas apropiadas pendientes.

La respuesta de Piyomaru muestra una manera de implementar un enfoque basado en eventos. Este enfoque no es multihilo o paralelo; es un bucle dirigido por eventos.

    
respondido por el Graham Miln 03.10.2017 - 14:02
1

AppleScript ahora admite subprocesos múltiples (macOS 10.10 o posterior) ). Y originalmente tiene la función de interrupción del temporizador desde 1993 (el controlador de eventos on idle timer funciona simultáneamente en un solo AppleScript).

Escribí algunos AppleScripts con iTunes como escribiste. AppleScript puede hacer delegados y recibir eventos de otras aplicaciones.

Este ejemplo de AppleScript puede recibir el cambio de estado de reproducción de iTunes. Una vez, la secuencia de comandos se ejecuta en el Editor de secuencias de comandos, recibe el evento de cambio de iTunes y muestra el nombre de la pista mediante el cuadro de diálogo de notificación de macOS.

-- Created 2017-10-13 by Takaaki Naganoya
-- 2017 Piyomaru Software

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSDistributedNotificationCenter : a reference to current application's NSDistributedNotificationCenter

on run
    NSDistributedNotificationCenter's defaultCenter()'s addObserver:me selector:"statusChanged:" |name|:"com.apple.iTunes.playerInfo" object:(missing value)

end run

on statusChanged:sender
    tell application id "com.apple.iTunes"
        try
            tell current track
                set anAlbum to album
                set aName to name
                set anArtist to album artist
                set aRating to rating
            end tell
        on error
            return
        end try
    end tell
    display notification aName
end statusChanged:

Por lo tanto, el punto es que la aplicación Spotify puede proporcionar una función como iTunes o no.

    
respondido por el Piyomaru 13.10.2017 - 08:45
0

Sugeriría escribir esto en JavaScript en lugar de AppleScript. JavaScript es un lenguaje compatible con los scripts de eventos de Apple. JavaScript es de un solo hilo, pero es mucho más fácil escribir código asíncrono sin bloqueo.

setInterval(function() {
    console.log('Do something in the closure function here');
}, 3000);
    
respondido por el David Fekke 03.10.2017 - 18:28

Lea otras preguntas en las etiquetas