Javascript vraagje
17 maart 2009 - 13:13   
geplaatst door: macpeterr
Hoi,

Ik ben wat in dashcode aan het experimenteren en loop tegen het volgende aan.
Voor detectie van een file heb ik een functoe welke gebruik maakt van het widget.system function.
De functie geeft eenr return value 0 als de app geinstalleerd is, 1 als dit niet zo is. Aangezien een system call onverwacht lang kan duren of hangen wil ik de functie op basis van een timeout een returnvalue geven van 1. Het lukt mij echter niet om dit werkend te krijgen en mogelijk dat een andere benadering beter werkt... alle tips zijn dus welkom.

Ik zou graag gebruik willen blijven maken van een timeout en niet meerdere malen een recursive call willen maken ivm met gebruik van resources.

Hieronder de (nog niet zo net geformatteerde code) ;

function growlDetect(status)
{

var growlDetectInterval = 500 ;
this.status = status ;

if (status == undefined) {
growlDetector = widget.system( "/bin/bash -c ls -d /Library/PreferencePanes/Growl.prefPane/Contents/Resources/GrowlHelperApp.app" , function() {} ) ;
growlDetector.status = -1 ;
return (growlDetect(0)) ;

}
else
{
alert("GrowlDetect (" + status + ")") ;

if (growlDetector.status != -1)
{
return growlDetector.status ;
}

if (status >= 5000) {
growlDetector.cancel() ;
return 1 ;
}

alert("status " + growlDetector.status) ;

status += growlDetectInterval ;
setTimeout('growlDetect(' + status + ');', growlDetectInterval) ;


}

alert("returning status :" + status) ;
return status ;
}


Peter
Javascript vraagje
17 maart 2009 - 14:00    reactie #1
geplaatst door: mvdg
Volgens mij staat het toch vrij duidelijk uitgelegd op deze pagina:
http://developer.apple.com/documentation/appleapplications/Conceptual/Dashboard_ProgTopics/Articles/CommandLine.html

Je maakt het jezelf wat moeilijk door zelf steeds te willen checken of het antwoord er al is. Dat kan toch veel makkelijker met de callback functie die het commando zelf al heeft. Je hoeft daarnaast dan enkel een aanroep te doen die na een bepaalde tijd (bv. 5 seconden) teruggeeft: 'mislukt' (dus '1').


// hierin kan de rest van je programma aflezen hoe het zit
var growlDetected = false;    // als deze true is, is het antwoord bekend
var growlPresent = false;      // deze is true of false als growl er wel of niet is

// deze functie roep je 1 x aan
function growlDetect()
{
   // detectie beginnen
   detector = widget.system( '/bin/bash ....... ', detectComplete);
   detectFailTimer = setTimeout ('detectFail', 5000);
}

// deze functie wordt gebruikt als het antwoord binnenkomt
function detectComplete()
{
   // hij is klaar. geef het antwoord door
   // eerst de timer voor het mislukken beeindigen
   clearTimeout(detectFailTimer);
   growlPresent = (detector.outputString == '0') ? true : false;
   growlDetected = true;
}

// deze functie wordt gebruikt als het te lang duurt
function detectFail()
{
    // het duurde te lang. geef negatief antwoord door.
   growlPresent = false;
   growlDetected = true;
   // stop het zoekcommando
   detector.cancel();
}

Mitch Design : websites en interactieve toepassingen : http://www.mitchdesign.nl
Javascript vraagje
17 maart 2009 - 14:53    reactie #2
geplaatst door: macpeterr

Ik neem aan dat je met callback functies de eventhandlers (onreadoutput en onreaderror) en de endhandler bedoelt?

Ik heb dit volgens mij ook uitgeprobeert, echter bij een cancel() method wordt niet de endhandler() aangeroepen. Dus een settimeout( detector.cancel(), 5000)  zorgt voor het cancelen van het system commando, maar resulteerd niet in een call naar de endhandler.

Wat ik ook wil is dat de aanroep van growlDetect() pas een waarde teruggeeft als de widget.system() call beeindigd is of een timeout is opgetreden.

Peter
Javascript vraagje
17 maart 2009 - 16:18    reactie #3
geplaatst door: mvdg
Volgens mij is het niet handig om een functie te gebruiken die meteen een waarde moet teruggeven. Als dat niet lukt, moet je daarna zelf er achteraan gaan om te blijven checken.

Vandaar dat ik dus voorstel om de widget.system call te doen en dan gewoon even te wachten. Je weet immers dat er binnen 5 seconden 1 van de 2 dingen gebeurt: hij lukt en je krijgt een antwoord, of hij mislukt. En als je eigen timeout eenmaal in werking treedt, ben je toch niet meer geinteresseerd in de retourwaarde van widge.system: die waarde is er immers niet, anders had je die al binnengehad. Dus als je eenmaal .cancel() aanroept dan hoef je niet meer je normale endhandler te doen; die levert dan toch niets op!

Naar mijn idee levert de aanroep van growlDetect() dus geen direct resultaat op, maar zet het proces in gang. Na 5 seconden wordt je programma dan vanzelf voortgezet (afhankelijk van wat je zelf in je software verder programmeert natuurlijk).

Mitch Design : websites en interactieve toepassingen : http://www.mitchdesign.nl