changeset 386:268478a184a3 macness

compile the NSAppleScript objs once only, rather than on every invocation
author Dan Stowell <dan.stowell@eecs.qmul.ac.uk>
date Mon, 18 Oct 2010 15:47:46 +0100
parents a555be0ad78f
children
files osx/svitunes.h osx/svitunes.mm
diffstat 2 files changed, 55 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/osx/svitunes.h	Mon Oct 18 15:32:35 2010 +0100
+++ b/osx/svitunes.h	Mon Oct 18 15:47:46 2010 +0100
@@ -18,8 +18,6 @@
 #include <QString>
 #include <QStringList>
 
-//#import <Foundation/Foundation.h>
-
 /**
 * Class to handle communication with a running iTunes program on the system.
 * Only implemented for Mac at present, since using applescript communication.
@@ -70,7 +68,11 @@
         // and "closed" if iTunes isn't running.
         int m_playerState;
         unsigned int m_playerPos; // itunes only tells us seconds
-    
+        
+        // compiled applescript objects, persistent.
+        // void pointers because NSAppleScript is ObjC, which we keep out of this header. Hm.
+        void *m_nowPlayingScript;
+        void *m_updateStateScript;
 };
 
 #endif
--- a/osx/svitunes.mm	Mon Oct 18 15:32:35 2010 +0100
+++ b/osx/svitunes.mm	Mon Oct 18 15:47:46 2010 +0100
@@ -36,17 +36,16 @@
     return result;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// ctor and dtor
+
 ITunesSVRemote::ITunesSVRemote() {
     m_playerState = STATE_UNKNOWN; 
     m_playerPos = 0;
-}
 
-ITunesSVRemote::~ITunesSVRemote() {
-}
+    NSDictionary *errorDict;
 
-QStringList ITunesSVRemote::getNowPlaying(){
-    NSDictionary *errorDict;
-    NSAppleScript *scriptObject = [[NSAppleScript alloc]    initWithSource:@" \
+    m_nowPlayingScript = (void*)[[NSAppleScript alloc]    initWithSource:@" \
 tell application \"System Events\" to set iTunesIsRunning to (name of processes) contains \"iTunes\" \n\
 if iTunesIsRunning is false then return \"\" \n\
 \
@@ -66,28 +65,14 @@
 end tell \n\
 "
     ];
-    
-    NSLog([scriptObject source]);
-    
-    [scriptObject compileAndReturnError: &errorDict];
-    
-    if(![scriptObject isCompiled]){
+    [(NSAppleScript*)m_nowPlayingScript compileAndReturnError: &errorDict];
+    NSLog([(NSAppleScript*)m_nowPlayingScript source]);
+    if(![(NSAppleScript*)m_nowPlayingScript isCompiled]){
         NSLog(@"SV ERROR: applescript object not compiled");
         NSLog([errorDict description]);
     }
-    
-    NSAppleEventDescriptor *eventDesc = [scriptObject executeAndReturnError: &errorDict];
-    NSString *nsResultString = [eventDesc stringValue];
-    
-    QString resultString = qt_mac_NSStringToQString(nsResultString);
-    
-    [scriptObject release];
-    return resultString.split(QChar('\n'));
-}
 
-void ITunesSVRemote::updatePlayerState(){
-    NSDictionary *errorDict;
-    NSAppleScript *scriptObject = [[NSAppleScript alloc]    initWithSource:@" \
+    m_updateStateScript = (void*)[[NSAppleScript alloc]    initWithSource:@" \
 tell application \"System Events\" to set iTunesIsRunning to (name of processes) contains \"iTunes\" \n\
 if iTunesIsRunning is false then return \"\" \n\
 \
@@ -102,17 +87,51 @@
 end tell \n\
 "
     ];
+    [(NSAppleScript*)m_updateStateScript compileAndReturnError: &errorDict];
+    NSLog([(NSAppleScript*)m_updateStateScript source]);
+    if(![(NSAppleScript*)m_updateStateScript isCompiled]){
+        NSLog(@"SV ERROR: applescript object not compiled");
+        NSLog([errorDict description]);
+    }
+
     
-    NSLog([scriptObject source]);
+} // end ctor
+
+ITunesSVRemote::~ITunesSVRemote() {
+    [(NSAppleScript*)m_nowPlayingScript release];
+    [(NSAppleScript*)m_updateStateScript release];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// itunes actual communications
+
+QStringList ITunesSVRemote::getNowPlaying(){
+    NSDictionary *errorDict;
+    NSAppleScript *nowPlayingScript = (NSAppleScript*)m_nowPlayingScript;
     
-    [scriptObject compileAndReturnError: &errorDict];
-    
-    if(![scriptObject isCompiled]){
+    if(![nowPlayingScript isCompiled]){
         NSLog(@"SV ERROR: applescript object not compiled");
         NSLog([errorDict description]);
     }
     
-    NSAppleEventDescriptor *eventDesc = [scriptObject executeAndReturnError: &errorDict];
+    NSAppleEventDescriptor *eventDesc = [nowPlayingScript executeAndReturnError: &errorDict];
+    NSString *nsResultString = [eventDesc stringValue];
+    
+    QString resultString = qt_mac_NSStringToQString(nsResultString);
+    
+    return resultString.split(QChar('\n'));
+}
+
+void ITunesSVRemote::updatePlayerState(){
+    NSDictionary *errorDict;
+    NSAppleScript *updateStateScript = (NSAppleScript*)m_updateStateScript;
+    
+    if(![updateStateScript isCompiled]){
+        NSLog(@"SV ERROR: applescript object not compiled");
+        NSLog([errorDict description]);
+    }
+    
+    NSAppleEventDescriptor *eventDesc = [updateStateScript executeAndReturnError: &errorDict];
     NSString *nsResultString = [eventDesc stringValue];
     
     QString resultString = qt_mac_NSStringToQString(nsResultString);
@@ -126,7 +145,6 @@
         if(results.size() != 2){
             std::cerr << "ITunesSVRemote::updatePlayerState() ERROR: results not in expected format:" 
                        << resultString.toStdString() << std::endl;
-            [scriptObject release];
             return;
         }
         
@@ -148,10 +166,10 @@
                         << m_playerPos << std::endl;
         }
     }
-    
-    [scriptObject release];
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
 bool ITunesSVRemote::isRunning(){
     return (m_playerState != STATE_UNKNOWN) && (m_playerState != STATE_CLOSED);
 }