Skip to main content
Known Participant
November 23, 2009
Answered

Removing $Sleep in code

  • November 23, 2009
  • 1 reply
  • 2878 views

Hi,

I had a previous post that was answered.  The code that was given had a few sleep commands in there. I was happy for it to run on my machine but I had to put in a big value sleep(10000) for my indesign document and illustrator script to both update and refresh correctly.

When I was demonstrating this via remote desktop things got a bit slow and the gragh did not refresh on the Indesign.  Therefore I had to run the code twice.  Sometimes it is the graph that does not update the dataset and therefore contains the values from the previous variables file.  Other times it's just that the graph has not completed saving properly and therefore when Indesign refreshes it still picks up the old graph.  This will be a real problem for us when the code goes live.  Basically, I want to know if anyone can re-write the below so that no sleep commands are run.

Basically the script is called from within Indesign. It opens up the Graph in illustrator.  Loads the variable file and updates the dataset.  It then saves the file and closes it.  Back in Indesign, all links are then refreshed.  Any help would be appreciated.  Thanks.

This topic has been closed for replies.
Correct answer Kasyan Servetsky

The only way you can make a script wait is to use 'sleep'. What you need to do is have bridge talk sat in a while loop waiting for a response from your illustrator script. Have illustrator return a value after it has done. Also I think in this case you would be better served by using toSource() & having illustrator do eval() at the other end of the bt message body (both these methods are over my head at the minute but heres a sample by someone else that may help you with some of the syntax with waiting and timing out)

function GetFilesFromBridge() {

  var fileList;

  if ( BridgeTalk.isRunning( "bridge" ) ) {

     var bt = new BridgeTalk();

     bt.target = "bridge";

     bt.body = "var theFiles = photoshop.getBridgeFileListForAutomateCommand();theFiles.toSource();";

     bt.onResult = function( inBT ) { fileList = eval( inBT.body ); }

     bt.onError = function( inBT ) { fileList = new Array(); }

     bt.send();

     bt.pump();

     $.sleep( 100 );

     var timeOutAt = ( new Date() ).getTime() + 5000;

     var currentTime = ( new Date() ).getTime();

     while ( ( currentTime < timeOutAt ) && ( undefined == fileList ) ) {

        bt.pump();

        $.sleep( 100 );

        currentTime = ( new Date() ).getTime();

     }

  }

  if ( undefined == fileList ) {

     fileList = new Array();

  }

  return fileList;

}

the target that you want to test 'is running' here is 'illustrator' no point in sending a message if its not

  if ( BridgeTalk.isRunning( "illustrator" ) ) {

}


Hi pvisell,

I think you overcomplicated things in the script you posted.

Here is my implementation of what I suggested in post #2.

The key points are:

1. Define an empty onResult function

bt.onResult = function(resObj) {}

2. provide a timeout value for send method as Bob advised (and I forgot to mention in my previous post)

bt.send(30);

I don't know why we should do both of these things — I found this out by experimenting.

Interapplication communication with scripts is explained very obscurely in documentation, so it's hard to understand. But once you sorted it out — it's easy. I would never understood this on my own, if Bob hadn't helped me. Thanks Bob a lot for this!!!

Kasyan

//-----------------------------------------

#target indesign

var myXmlPath = "/c/Test/Capella Gross Sector Exposure.xml";
var mySetName = "Capella";

var myDoc = app.activeDocument;
ProcessLinks();
UpdateLinks()
alert("Done");

// ------------------------- FUNCTIONS -------------------------
function ProcessLinks() {
    for (var j = 0; j < myDoc.links.length; j++) {
        var myLink = myDoc.links;
        CreateBridgeTalkMessage(myLink.filePath, myXmlPath, mySetName);
    }
}

function CreateBridgeTalkMessage(myAiPath, myXmlPath, mySetName) {
    var bt = new BridgeTalk();
    bt.target = "illustrator";
    var myScript = UpdateDataset.toString() + '\r';
    myScript += 'UpdateDataset(\"' + myAiPath + '\", \"' + myXmlPath + '\", \"' + mySetName + '\");';
    bt.body = myScript;
    bt.onResult = function(resObj) {}
    bt.send(30);
}

function UpdateDataset(myAiPath, myXmlPath, mySetName) {
    var myAiFile = new File(myAiPath);
    var myDoc = app.open(myAiFile);
    var myXmlFile = new File(myXmlPath);
    if (myXmlFile.exists) {
        myDoc.importVariables(myXmlFile);
        myDoc.activeDataset = myDoc.dataSets.getByName(mySetName);
        myDoc.activeDataset.display();
        myDoc.close(SaveOptions.SAVECHANGES);
    }
}

function UpdateLinks() {
    for (var i = myDoc.links.length-1; i >= 0; i--) {
        if (myDoc.links.status == LinkStatus.linkOutOfDate) {
            myDoc.links.update();
        }
    }
}

1 reply

pvisellAuthor
Known Participant
November 23, 2009

Code below....thanks

#target indesign


function main() {

if (app.documents.length == 0) {

alert("Please have an 'Indesign' document before running this script.");

return;

}

var docRef = app.documents[0];

$.sleep( 3000 ); // Just my novice delay method

updateGraph();

$.sleep( 3000 ); // Ditto here

//updateGraph();// done this twice because there seems to be a bug where the dataset is not getting updated first time around

$.sleep( 3000 );
//} //end for
updateLinks(docRef);

};

// Reverse loop to do this

function updateLinks(docRef) {

for (var i = docRef.links.length-1; i >= 0; i--) {

//if (docRef.links.status == LinkStatus.linkOutOfDate) {

docRef.links.update();
// } if clause end
}// for

}

// A basic Bridge Talk example

function updateGraph() {

if ( BridgeTalk.isRunning( "bridge" ) ) {

var bt = new BridgeTalk();

bt.target = "illustrator";

bt.body = "#target illustrator" + "\r"
+ "var DBHelper = {" + "\r"

+ "mainFs: null," + "\r"

+ "myDoc: null," + "\r"
+ "loadFile: function(fileOrFilename, isAI) {" + "\r"
+ "var _fl = (fileOrFilename instanceof 'File') ? fileOrFilename : new File(fileOrFilename);" + "\r"
+ " if(isAI) { this.myDoc = app.open(_fl);}" + "\r"
+ "else {" + "\r"
+ "this.myDoc.importVariables(_fl);" + "\r"
+ "this.mainFs = app.activeDocument.path.fullName + '/' + app.activeDocument.name;" + "\r"
+ "this.myDoc.save();" + "\r"
+ "this.myDoc.close(SaveOptions.SAVECHANGES);" + "\r"
+ "$.sleep( 3000 );" + "\r"
+ "this.loadFile(this.mainFs,true);" + "\r"
+ "}" + "\r"
+ "}," + "\r"
+ "displaySet: function(setName) {" + "\r"
+ "this.myDoc.activeDataset = this.myDoc.dataSets.getByName(setName);" + "\r"
+ "this.myDoc.activeDataset.display();" + "\r"
+ "this.myDoc.close(SaveOptions.SAVECHANGES);" + "\r"
+ "$.sleep( 3000 );" + "\r"
+ "}" + "\r"
+ "}" + "\r"

+ "DBHelper.loadFile('/u/adobe indesign/Capella Gross Sector Exposure.ai', true);" + "\r"
+ "DBHelper.loadFile('/u/adobe indesign/Capella Gross Sector Exposure2.xml',false);" + "\r"
+ "DBHelper.displaySet('Capella');" + "\r"
// Save to modify the link status
//+ "DBHelper.myDoc.close(SaveOptions.SAVECHANGES);";
bt.send();

}
else
{
alert ("Please start Adobe Bridge");
}
}
main();

Kasyan Servetsky
Legend
November 27, 2009

First of all, you don't need to run Bridge application to use Bridge talk. So these lines are unnecessary:

if ( BridgeTalk.isRunning( "bridge" ) ) {

...

}

else

{

alert ("Please start Adobe Bridge");

}

When I was writing my Resize images script — http://kasyan.ho.com.ua/resize.html — I stumbled upon a problem: InDesign attempted to update a linked image before Photoshop finished resizing it. At first, I tried to use $.sleep() but it didn't help. Then I added an empty onResult function:

bt. = function(resObj) {}

and this solved the problem — script in InDesign continues only after the script in Photoshop finishes its execution.

It would be a good thing if you posted not only your script, but sample documents as well — indd, ai, xml files — so that we could run the script against them.

Kasyan

pvisellAuthor
Known Participant
November 27, 2009

Hi Kasyan,

I removed all the sleep commands and I put your code in, but it still did not allow illustrator to finish processing before it carried on.

I tried both of the below:

bt.send();
bt.onResult = function(resObj) {} // empty function - to wait untill PS finishes processing the file

and

bt.onResult = function(resObj) {} // empty function - to wait untill PS finishes processing the file

bt.send();

In debug mode the script just carries on and updates the links even before Illustrator has started up.

The above line is the only thing that I changed.  I assume that is what I should have done.

Thanks.