Highlighted

Break out of loop on demand - by button click, keyboard... ?

New Here ,
Jun 03, 2020

Copy link to clipboard

Copied

Hello;

I have a script that pols a folder for files despited by some other process (getDataFiles()); when it finds a file, it processes it (processData()), then moves it to a different folder and pols for a newly depostied file. This is the loop you see below.

 

I’m looking for a way to break the loop. I can’t, from what I’ve read, set the “isStopped” variable via a button click because of the single-thread nature of Javascript processing.

 

Ideally, I’d like to have a UI with a start and stop button.

I’ve spent a lot of time Googling, to no avail. What would you suggest?

Thanks.

 

var isStopped = false;
...
...
...


function doIt() {

    while (!isStopped) {
        
        
        getDataFiles();  // read the file names into var dataFiles
        
        for(i=0; i < dataFiles.length ;i++) { // if there are files,process them.
            processData(dataFiles[i].name)            
            }
        
       // wait for a bit (for new data files to be deposited)        
       $.sleep(2000)           // wait 2 seconds        
       
       }   // while !isStopped

    }

 

 

Adobe Community Professional
Correct answer by Mathias Moehl | Adobe Community Professional

Unfortunately, Ae scripting has no concept of code running asynchronous. That means while your code is running, Ae essentially freezes and hence the user has no chance to click a button.

For anything that goes beyond a simple progress bar, I recommend to implement that as a CEP panel instead.

 

In CEP you can write asynchronous javascript such that the UI stays fully responsive while your file processing operations run in the background.

Topics

Scripting

Views

425

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Break out of loop on demand - by button click, keyboard... ?

New Here ,
Jun 03, 2020

Copy link to clipboard

Copied

Hello;

I have a script that pols a folder for files despited by some other process (getDataFiles()); when it finds a file, it processes it (processData()), then moves it to a different folder and pols for a newly depostied file. This is the loop you see below.

 

I’m looking for a way to break the loop. I can’t, from what I’ve read, set the “isStopped” variable via a button click because of the single-thread nature of Javascript processing.

 

Ideally, I’d like to have a UI with a start and stop button.

I’ve spent a lot of time Googling, to no avail. What would you suggest?

Thanks.

 

var isStopped = false;
...
...
...


function doIt() {

    while (!isStopped) {
        
        
        getDataFiles();  // read the file names into var dataFiles
        
        for(i=0; i < dataFiles.length ;i++) { // if there are files,process them.
            processData(dataFiles[i].name)            
            }
        
       // wait for a bit (for new data files to be deposited)        
       $.sleep(2000)           // wait 2 seconds        
       
       }   // while !isStopped

    }

 

 

Adobe Community Professional
Correct answer by Mathias Moehl | Adobe Community Professional

Unfortunately, Ae scripting has no concept of code running asynchronous. That means while your code is running, Ae essentially freezes and hence the user has no chance to click a button.

For anything that goes beyond a simple progress bar, I recommend to implement that as a CEP panel instead.

 

In CEP you can write asynchronous javascript such that the UI stays fully responsive while your file processing operations run in the background.

Topics

Scripting

Views

426

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Adobe Community Professional ,
Jun 03, 2020

Copy link to clipboard

Copied

Unfortunately, Ae scripting has no concept of code running asynchronous. That means while your code is running, Ae essentially freezes and hence the user has no chance to click a button.

For anything that goes beyond a simple progress bar, I recommend to implement that as a CEP panel instead.

 

In CEP you can write asynchronous javascript such that the UI stays fully responsive while your file processing operations run in the background.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
New Here ,
Jun 04, 2020

Copy link to clipboard

Copied

Thank you for your quick response Mathias;  it does seem like AE scripting is  fire-and-forget 😉

 

I've downloaded a few tutorials on CEP and will start learning about it this evening. 

 

Kind regards,

Roland

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Adobe Community Professional ,
Jun 04, 2020

Copy link to clipboard

Copied

Yes. Little side note: Adobe plans to discontinue CEP in the longterm and replace it with UXP. UXP is not yet available for After Effects, so for now CEP is your only option. But when learning CEP keep in mind that you will have to port your tools to UXP in the long term.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
New Here ,
Jun 09, 2020

Copy link to clipboard

Copied

 

 

Hi Mathias; OK, I’ve created my first panel with start and stop buttons.

I’ve moved the loop to the  JS from the JSX; still no luck stopping the loop, I tried a couple of things;  likely for the same reason as my previous attempt.

What is  your recommendation please, thanks so much  for your help.

var csInterface = new CSInterface();

var isStopped = false;

var startButton = document.querySelector("#start-button");
startButton.addEventListener("click", startProc);    /* Write a helper function to pass instructions to the ExtendScript side. */

var stopButton = document.querySelector("#stop-button");
stopButton.addEventListener("click", stopProc);    /* Write a helper function to pass instructions to the ExtendScript side. */

function startProc() {
    while (!isStopped) {
         csInterface.evalScript("startProcessing()");  
     } 
}

function stopProc() {
    isStopped == true;
  }

 

 

 

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Adobe Community Professional ,
Jun 09, 2020

Copy link to clipboard

Copied

Instead of having one function "startProcessing()" that does all the work, you need to have a function that only does a little bit of processing and then returns to give the user the chance to cancel. The evalScript has a second parameter: a function that is called when the evalScript finished. Use it to start the next bit of work.

 

Example:

Say you have to process each layer from 1 to 100 of a composition in whatever way. Then you could do it like this:

var firstLayer = 1;
var lastLayer = 100;

function startProc(){
	doWorkForLayer(firstLayer);
}

function doWorkForLayer(nextLayerToBeProcessed){
	csInterface.evalScript("processLayer(${nextLayerToBeProcessed})", function(){
		// this code is executed once processLayer is finished
		if(!isStopped && nextLayerToBeProcessed<= lastLayer ){
			doWorkForLayer(nextLayerToBeProcessed+1)
		}
	});  
}

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Rol3d LATEST
New Here ,
Jun 10, 2020

Copy link to clipboard

Copied

Ahhhhhh, thank you again Mathias! That did it. One little thing trippped me up, especcialy because it results in a weird error message, "unable to execute script at line 1: Expected: )":

 

"processLayer(${nextLayerToBeProcessed})"

 

 must be in 'accent grave' characters: 

 

 

`startProcessing(${nextLayerToBeProcessed})`

 

I have it running now. Amazing, all that just to interrupt the loop. Crazy.
Thanks again.
 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...