• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

evalScript taking some time to give back the control to the caller being asynchronous

New Here ,
Jan 21, 2018 Jan 21, 2018

Copy link to clipboard

Copied

Hi,

I'am calling csInterface.evalScript() which in turns calls a synchronous function inside a c++ library and i logged the time before and after  calling the  csInterface.evalScript() and also on getting the result, following is my observation:

Screen Shot 2018-01-22 at 11.49.35 AM.png

There is a delay of 211 milliseconds before and after calling the evalScript, being asynchronous isn't it supposed to give the control back immediately?My understanding of evalScript was that it should give the control back immediately and give the result whenever it is available but in this case it is happening the other way round, it is taking some time to give the control back along with the result(like a synchronous function).

TOPICS
SDK

Views

3.2K

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
community guidelines

correct answers 1 Correct answer

Enthusiast , Jan 22, 2018 Jan 22, 2018

I'll sum up this discussion in order to answer OP's questions:

athila13898684  wrote

There is a delay of 211 milliseconds before and after calling the evalScript, being asynchronous isn't it supposed to give the control back immediately?

CSInterface.evalScript is not, in fact, asynchronous. It is entirely synchronous and will block for the duration of the ExtendScript processing it triggers.

athila13898684  wrote

My understanding of evalScript was that it should give the control back immediately and

...

Votes

Translate

Translate
Adobe Employee ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

For what purposes do you require less than 211ms response time, from a scripting function in a different application?

Votes

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
community guidelines
Enthusiast ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

https://forums.adobe.com/people/Bruce+Bullis  wrote

For what purposes do you require less than 211ms response time, from a scripting function in a different application?

Does it matter? Regardless of what the purpose is, Bruce Bullis​, a 211ms pause is going to create a noticeable hitch for the user.

Let's ask this question in a more direct way: the user perception of the evalScript function is that it is asynchronous. This is implicit in the function takes a callback instead of returning a value. However, athila13898684's experience does not seem to support that assumption.

Is evalScript synchronous or asynchronous?

Also, athila13898684 could you provide some (simplified?) code that reproduces what you're seeing?

Votes

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
community guidelines
Adobe Employee ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

> Does it matter?

Yes, as the caller may have unrealistic expectations around what interactions our apps can support, noticeability aside.

> is evalScript synchronous or asynchronous?


Yes.

ExtendScript is, typically, synchronous, while the environment from which that ExtendScript is being invoked may not be. A panel's JavaScript could be waiting on several asynchronous jobs to complete, all of which may depend on different (synchronous) ExtendScript execution.

Votes

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
community guidelines
Enthusiast ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Bruce Bullis wrote

> is evalScript synchronous or asynchronous?


Yes.

ExtendScript is, typically, synchronous, while the environment from which that ExtendScript is being invoked may not be. A panel's JavaScript could be waiting on several asynchronous jobs to complete, all of which may depend on different (synchronous) ExtendScript execution.

Right.

Let's break this down so that we can speak in specific terms about what's going on. The following is the expected structure of execution. When functions are at the same "

    depth", they are considered to be running in parallel (this is similar to a UML sequence diagram😞

    • Panel.js - calls evalScript to schedule work in the ExtendScript context.
    • ExtendScript.jsx - receives work request, calls Library function and waits for result [blocks].
      • MyLib.dll - does some work, eating ~150-200ms of time. Returns the result to caller.
    • ExtendScript.jsx - waiting done, ExtendScript can return the result, which the CEP context boundary will send (stringified) to the panel via a scheduled message.
    • Panel.js - handles the message at some point (based on status of event loop and message queue).

What it sounds like  athila13898684​ is experiencing, however, is something like the following:

    • Panel.js - calls evalScript to "schedule" work in the ExtendScript context.
      • ExtendScript.jsx - the csInterface.evalScript function is blocking - it didn't schedule the message and return but scheduled and waited for the ExtendScript message to be processed. Now that it's processing, it calls the Library function and waits for results [blocks].
        • MyLib.dll - does some work, eating ~150-200ms of time. Returns the result to caller.
      • ExtendScript.jsx - waiting done, ExtendScript schedules the CEP callback and can return control to the caller, which now unblocks the CEP thread.
    • Panel.js - Gains control again. Can process the line of JavaScript that outputs the console log "After..." line output. Finally ends running.
    • Panel.js - Processes the scheduled callback after some little amount of time.

Given the output that athila13898684​ posted in their original question, the only version that makes any sense to me is the latter. This is probably the intuition that is also driving the initial question.

So the question, then, becomes: does the CSInterface evalScript function properly schedule a message and immediately return or does it block and wait for the ExtendScript context to process the message?

Votes

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
community guidelines
Adobe Employee ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

> "The following is the expected structure of execution. When functions are at the same "

    depth",

> they are considered to be running in parallel..."


I'm not sure what suggests to you, that these expectations properly apply to CEP panels...? [I'm not saying you're wrong, just wondering why you have these expectations.]

> "...does the CSInterface evalScript function properly schedule a message and immediately return..."

I don't understand your usage of "Properly", above. evalScript() does just that; evaluate a given snippet or file of ExtendScript.

That ExtendScript could block until execution is complete; this is the common case. OR, that ExtendScript could execute and return immediately, AND set up other ExtendScript functions to be called back, when some child processes are complete. PProPanel's usage of Encoder.encode() would do this.

Votes

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
community guidelines
Enthusiast ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Bruce Bullis wrote

> "The following is the expected structure of execution. When functions are at the same "

    depth",

> they are considered to be running in parallel..."


I'm not sure what suggests to you, that these expectations properly apply to CEP panels...? [I'm not saying you're wrong, just wondering why you have these expectations.]

What suggests this structure to me is the format of the API itself. In JavaScript, when you use an API that takes a callback, it is typically fair to assume that the API is asynchronous in nature (or, at least, that it can be). The format of CSInterface.evalScript follows that format:

CSInterface.prototype.evalScript = function(script, callback)

As a user, I look at that API definition and say "Okay, I'm sending a message from one 'JavaScript' context to another. I have no idea what the other context is doing or if it's even running right now. I will provide this callback to receive the result at some future time once the other 'JavaScript' context has completed its work."

Bruce Bullis wrote

> "...does the CSInterface evalScript function properly schedule a message and immediately return..."

I don't understand your usage of "Properly", above. evalScript() does just that; evaluate a given snippet or file of ExtendScript.

Let me be explicit about what I'm stating:

Expectation: "As a user, I expect the CSInterface.evalScript function to schedule work to be done in ExtendScript. It should add a message containing the 'script-to-evaluate' to ExtendScript's internal message queue​​ and immediately return. When the ExtendScript context has had a chance to process that message, it will return a result. That result will be coerced to a string by the 'glue code' that understands the CEP and ExtendScript contexts. That glue code will then add the callback (the one supplied to the evalScript function) as a message to be called in the CEP context's message queue."

What you've just stated is very different: "evalScript() does just that; evaluate a given snippet or file of ExtendScript." What this says to me is:

Reality[?]: "The CSInterface.evalScript function will block the CEP caller and start up the ExtendScript context. It will then evaluate the 'script' provided in the parameter. If this work takes three seconds, then CEP will also be blocked for three seconds. A callback with the result will indeed be scheduled but it won't gain you anything over simply returning the value directly from the evalScript call as the calling CEP context was blocked for the entire time anyway."

The expectation is that CSInterface.evalScript is asynchronous in nature - it is akin to sending a message to a separate context that will process it "in due time, thank you very much", rather than immediately. In other words, it's almost the CEP version of the ExtendScript context's CSXSEvent system.

I mean, why even bother with the callback if you're simply going to block anyway? Just return the result directly!

I checked what the CEP 8 HTML Extension Cookbook has to say about the evalScript function. Unfortunately, the writing isn't terribly clear, but it may be trying to say what I believe you confirmed above. Specifically, this section:

Please be aware that the script in evalScript and the jsx file which is configured in <ScriptPath> in the extension's manifest are executed in host application's ExtendScript engine, which runs in host application's main thread. On the other hand, CEP event is also dispatched from host application's main thread. If the interaction between the script and CEP event is needed, please split the script into small parts and call them separately so that CEP event has a chance to be scheduled.

Here's what I gather from this:

  • Code passed as a string into evalScript and JSX files are processed on the application's MAIN THREAD. This is expected. There is one ExtendScript engine [context] in Premiere Pro and its work is done on a unified Event Loop.
  • CEP events are dispatched from the application's MAIN THREAD. I'm unclear as to whether this means events from CEP, to CEP, or both...
  • That last sentence is frustratingly ambiguous. "... please split the script into small parts..."... Which script? CEP-side or ExtendScript side?

However, combine that with your comments:

Bruce Bullis wrote

That ExtendScript could block until execution is complete; this is the common case. OR, that ExtendScript could execute and return immediately, AND set up other ExtendScript functions to be called back, when some child processes are complete. PProPanel's usage of Encoder.encode() would do this.

And it seems that, indeed, evalScript does block the CEP thread until it's done processing. To that end, to achieve a result that's inline with expectations, you should use the CSInterface.evalScript function to schedule work to be done in the ExtendScript context and have that code dispatch a CSXSEvent.

All That Being Said...

Will the ExtendScript context cause a noticeable glitch regardless of whether it's been scheduled to work asynchronously? The fear is that ExtendScript processing always occurs on the main thread (and blocks the application, CEP, etc.) rather than in its own thread. This would result in that long API call blocking the main thread and causing the noticeable hitch regardless of the work you do to make things asynchronous.

Votes

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
community guidelines
Adobe Employee ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Thanks for the explanation behind your expectations; yeah, that makes sense.

I think your "Reality[?]" assessment is correct, and that evalScript() does block. I've asked CEP and ExtendScript nerds for confirmation.

> why even bother with the callback if you're simply going to block anyway?

To allow delegation of processing of returned stuff; PProPanel's encode() usage registers different callback functions, for different render results.

> The fear is that ExtendScript processing
always occurs on the main thread (and blocks the application, CEP, etc.) rather than in its own thread.

That fear is founded; that's how PPro executes ExtendScript, today.

Votes

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
community guidelines
Enthusiast ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Bruce Bullis wrote

Thanks for the explanation behind your expectations; yeah, that makes sense. 

Glad it was helpful!

Bruce Bullis wrote

I think your "Reality[?]" assessment is correct, and that evalScript() does block. I've asked CEP and ExtendScript nerds for confirmation.

Got it. Very interested in hearing the results. It may affect how we prepare interactions between the two JavaScript contexts.

Bruce Bullis wrote

> why even bother with the callback if you're simply going to block anyway?

To allow delegation of processing of returned stuff; PProPanel's encode() usage registers different callback functions, for different render results.

But... that's not what I'm talking about. The CEP code that you use to trigger the PProPanel's encode() usage doesn't register a callback:

csInterface.evalScript(whole_megillah);

You don't hand evalScript a callback. Instead, you rely upon the CSXSEvent system in ExtendScript to pass results back.

app.encoder.bind('onEncoderJobComplete', $._PPP_.onEncoderJobComplete);

app.encoder.bind('onEncoderJobError', $._PPP_.onEncoderJobError);

app.encoder.bind('onEncoderJobProgress', $._PPP_.onEncoderJobProgress);

app.encoder.bind('onEncoderJobQueued', $._PPP_.onEncoderJobQueued);

app.encoder.bind('onEncoderJobCanceled', $._PPP_.onEncoderJobCanceled);

This is fine, but it doesn't answer the question as to why CSInterface.evalScript requests a callback if it returns the result directly anyway. The point is that this:

csInterface.evalScript("doWork();", function(res){

    console.log(res);

});

is no different from the following setup (in the imaginary world where evalScript returns the result directly):

var res = csInterface.evalScript("doWork();");

setTimeout(function(){

    console.log(res);

}, 0);

Rather, it's somewhat odd that we're forced into a callback structure if the function blocks anyway. It breaks up logic in an asynchronous manner without actually providing any of the benefit derived from being asynchronous.

Does this make sense?

Bruce Bulliswrote

> The fear is that ExtendScript processing

always occurs on the main thread (and blocks the application, CEP, etc.) rather than in its own thread.

That fear is founded; that's how PPro executes ExtendScript, today.

Yikes. That likely explains your initial response, then. Based on this information, it seems that there's no way for  athila13898684​ to avoid the hitch if their native (C++) function call indeed takes ~200ms to process. Would that be the case?

Votes

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
community guidelines
Adobe Employee ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

> This is fine, but it doesn't answer the question as to why CSInterface.evalScript requests a callback if it returns the result directly anyway.

Why = It's a convenience, for handling the result of a call, once that result becomes available.

Niggling distinction, which may not make a difference: In the encode() handling I referenced, you're right that PProPanel is NOT relying on evalScript() to register a callback handler, but it's also not relying on CSXS messaging. The backing code inside encode() registers the provided callbacks, as handler functions for a variety of return states.

> Yikes...Would that be the case?

Yes, I still think my initial response was correct, that there's no obvious way to avoid that ~200ms delay, and that PPro ExtendScript is processed on the Main UI thread.

Votes

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
community guidelines
Enthusiast ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Bruce Bullis wrote

> This is fine, but it doesn't answer the question as to why CSInterface.evalScript requests a callback if it returns the result directly anyway.

Why = It's a convenience, for handling the result of a call, once that result becomes available.

I... think we may be talking in circles here, Bruce Bullis​. With CSInterface.evalScript, there is no "once that result becomes available."

The entire point is that the evalScript call blocks the CEP thread until the ExtendScript it triggers is done. When the ExtendScript context returns, it will coerce any returned value into a string type value. Rather than returning that string directly to the evalScript caller, however, the system will schedule a callback in the CEP message queue.

The whole point I'm trying to make is that the result string value that the callback receives is already available by the time the call to evalScript() returns and the CEP thread is unblocked. You're just needlessly putting it into a callback and kicking it down the road.

Bruce Bullis wrote

Niggling distinction, which may not make a difference: In the encode() handling I referenced, you're right that PProPanel is NOT relying on evalScript() to register a callback handler, but it's also not relying on CSXS messaging. The backing code inside encode() registers the provided callbacks, as handler functions for a variety of return states.

It does rely on CSXS messaging. Just not directly. Here's the flow:

In the onClick handler function for the renderusingdefaultpreset button (index.html:181😞

// Prepare a call to the JSX "$._PPP_.render" function. No callback specified.

var pre       = '$._PPP_.render(\'';

var post      = '\'';

var postpost  = ')';

var whole_megillah =  pre + path + post + postpost;

csInterface.evalScript(whole_megillah);

In $._PPP_.render (Premiere.jsx:532😞

// Schedule some callbacks with the encoder. These callbacks are JSX functions.

app.encoder.bind('onEncoderJobComplete', $._PPP_.onEncoderJobComplete);

app.encoder.bind('onEncoderJobError', $._PPP_.onEncoderJobError);

app.encoder.bind('onEncoderJobProgress', $._PPP_.onEncoderJobProgress);

app.encoder.bind('onEncoderJobQueued', $._PPP_.onEncoderJobQueued);

app.encoder.bind('onEncoderJobCanceled', $._PPP_.onEncoderJobCanceled);

In $._PPP_.onEncoderJobComplete (Premiere.jsx:1190😞

// Schedule a CSXS Event. This will broadcast the message to the CEP panel.

var eventObj = new CSXSEvent();

eventObj.type = "com.adobe.csxs.events.PProPanelRenderEvent";

eventObj.data = "Rendered Job " + jobID + ", to " + outputFilePath + ".";

eventObj.dispatch();

In onLoaded (ext.js:17😞

// Listen for event sent in response to rendering a sequence.

csInterface.addEventListener("com.adobe.csxs.events.PProPanelRenderEvent", function(event){

    alert(event.data);

});

So you have this:

  1. CEP calls ExtendScript.
  2. ExtendScript registers handlers with ExtendScript APIs.
  3. ExtendScript triggers some asynchronous work via Adobe APIs.
  4. ExtendScript returns nothing (void) to CEP.
  5. CEP continues processing.
  6. [Encoding occurs...]
  7. ExtendScript encoding event is triggered, handler is called.
  8. ExtendScript packages up a message for CEP via the CSXS system.
  9. CEP receives an event from JSX that the render job completed.

You had to go this route as the call to app.encoder.encodeSequence() that does the bulk of the work is itself asynchronous by nature. You couldn't get the result back immediately, even if you wanted to block that whole time. You do send the completion message back to CEP and you do so via CSXS, not by the evalScript callback. There is, in fact, no way for you to be able to do that. The evalScript callback only receives the value returned by whatever code you asked it to process in the ExtendScript context. If you did the following:

csInterface.evalScript("return 5;", function(res) { console.log(res); });

you would see the number 5 printed in your JavaScript console. Your $._PPP_.render() function doesn't return anything so the callback wouldn't receive anything.

The point of all of this is that the evalScript function call doesn't return until its first "script-as-a-string" parameter is fully processed. If that code blocks for 200ms, then so will evalScript and thus CEP.

Bruce Bullis wrote

Yes, I still think my initial response was correct, that there's no obvious way to avoid that ~200ms delay, and that PPro ExtendScript is processed on the Main UI thread.

Okay, got it. Thanks for the clarifications!

Votes

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
community guidelines
Adobe Employee ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

> It does rely on CSXS messaging. Just not directly.

Fair enough. Restated: "The callback mechanism doesn't rely on CSXS messaging. This particular implementation happens to use CSXS messaging."


Votes

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
community guidelines
Enthusiast ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Bruce Bullis wrote

> It does rely on CSXS messaging. Just not directly.

Fair enough. Restated: "The callback mechanism doesn't rely on CSXS messaging. This particular implementation happens to use CSXS messaging."

Ahh, but Bruce Bullis​​! This then takes us right back to where we were before!

Right, the callback mechanism doesn't rely on CSXS messaging. It is different. The evalScript function has its own callback mechanism. Specifically, window.__adobe_cep__.evalScript has its own distinct callback mechanism.

To get back to my initial question, then:

sberic wrote

I mean, why even bother with the callback if you're simply going to block anyway? Just return the result directly!

What we've learned through this forum post is that window.__adobe_cep__.evalScript will block while it executes some code in the ExtendScript context to its completion. We are told that the callback function "receives the result of execution". If the evalScript function is not actually making use of the ExtendScript context's message queue; if it's not scheduling that script evaluation to occur at some point down the road, then why not just return the data directly like just about all other synchronous functions out there?

The point is that right now, calling evalScript feels a bit like doing the following:

function countToNumber(num, callback)

{

    var result = 0;

    for (var i = 0; i < num; ++i)

    {

        result++;

    }

    function returnResult()

    {

        callback(result);

    }

    // Send the result to the callback, rather than

    //  return directly!

    setTimeout(returnResult, 0);

}

countToNumber(999999999, function(val) { console.log(val); });

Do you see the point? The countToNumber function in my example does its work synchronously. Rather than returning the result directly, however, it kicks it down the road to be handled at some other point. This seems... silly.

Votes

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
community guidelines
Adobe Employee ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

> This seems... silly.

I wouldn't go all the way to 'silly', though I'd admit that having two callback mechanisms in place might seem extraneous.

Except...

ExtendScript is ~15 years older than CEP, and CEP was designed to allow for interaction with N ExtendScript engines (where N = "all Adobe apps that support ExtendScript and CEP").  I can imagine having an available-but-not-mandatory CEP callback mechanism, above/beyond/outside ExtendScript's own such mechanism, might be useful.

Votes

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
community guidelines
Enthusiast ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Bruce Bullis wrote

> This seems... silly.

I wouldn't go all the way to 'silly', though I'd admit that having two callback mechanisms in place might seem extraneous.

This isn't the point. The CSXS event system makes sense. That a blocking call triggers a callback rather than returning a value directly is what is silly.

Let's try this another way. This is the definition of CSInterface.evalScript today:

/**

* Evaluates a JavaScript script, which can use the JavaScript DOM

* of the host application.

*

* @param script    The JavaScript script.

* @param callback  Optional. A callback function that receives the result of execution.

*          If execution fails, the callback function receives the error message \c EvalScript_ErrMessage.

*/

CSInterface.prototype.evalScript = function(script, callback)

{

    if(callback === null || callback === undefined)

    {

        callback = function(result){};

    }

    window.__adobe_cep__.evalScript(script, callback);

};

For all intents and purposes, evalScript looks like a call that starts some asynchronous work. This confused me and it confused the original author of this thread.

As window.__adobe_cep__.evalScript is not asynchronous, it would make more sense to just have it be the following:

/**

* Evaluates a JavaScript script, which can use the JavaScript DOM

* of the host application.

*

* @param script    The JavaScript script.

* @returns         The result of execution.

*          If execution fails, returns the error message \c EvalScript_ErrMessage.

*/

CSInterface.prototype.evalScript = function(script)

{

    return window.__adobe_cep__.evalScript(script);

};

That is unquestionably synchronous. It both looks synchronous and does not make you jump through hoops to make use of the results.

The only reason I can think of to have window.__adobe_cep__.evalScript take a callback function is if some Adobe applications actually do (or did?) schedule the ExtendScript work by adding it to the ExtendScript context's message queue. Otherwise... adding a callback step seems, well, silly...

Votes

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
community guidelines
Adobe Employee ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

I think you've identified a primary motivator: Even if no ExtendScript host app deals with asynchrony today, providing for a callback 'by convention' allows for that possibility in the future.

Votes

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
community guidelines
Enthusiast ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Bruce Bullis wrote

I think you've identified a primary motivator: Even if no ExtendScript host app deals with asynchrony today, providing for a callback 'by convention' allows for that possibility in the future.

If that is indeed the reason for it being that way, it would have been very nice to add a synchronous version as well and then document the applications that actually support the asynchronous version... Less jumping through hoops; less ambiguity; less confusion.

New Feature Request

Please add an override for CSInterface.evalScript() that returns the result value directly to the caller. This function should throw an exception or return an error in the case that it is unsupported for the given host application (e.g. a new sibling for the EvalScript_ErrMessage). The documentation for this function should clearly state that this is a synchronous call and will block for the duration of the ExtendScript processing.

Votes

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
community guidelines
Adobe Employee ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Does not passing a callback function to evalScript() elicit the behavior you want, today?

Votes

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
community guidelines
Enthusiast ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Bruce Bullis wrote

Does not passing a callback function to evalScript() elicit the behavior you want, today?

No. It does not.

Also, I feel that I should amend a previous statement. You get an error if you attempt to call:

csInterface.evalScript("return 5;");

The return keyword is only valid in a function and you are not in a function by default. Instead, the following properly returns 5:

csInterface.evalScript("5;");

Logging the results of that call result in "undefined". However, logging the results in a callback passed to evalScript results in "5".

Unfortunately, not passing a callback function to evalScript does not elicit the behavior I want today. Even amending the CSInterface.js function definition to return the results of the internal call to window.__adobe_cep__.evalScript didn't change anything. It seems that something deeper would need to be adjusted or added for this to work.

Votes

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
community guidelines
Adobe Employee ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

Fair enough.

Votes

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
community guidelines
Enthusiast ,
Jan 22, 2018 Jan 22, 2018

Copy link to clipboard

Copied

I'll sum up this discussion in order to answer OP's questions:

athila13898684  wrote

There is a delay of 211 milliseconds before and after calling the evalScript, being asynchronous isn't it supposed to give the control back immediately?

CSInterface.evalScript is not, in fact, asynchronous. It is entirely synchronous and will block for the duration of the ExtendScript processing it triggers.

athila13898684  wrote

My understanding of evalScript was that it should give the control back immediately and give the result whenever it is available but in this case it is happening the other way round, it is taking some time to give the control back along with the result(like a synchronous function).

You are not alone in believing that this is how the function works. What is extra-confusing is that the function blocks but it does not immediately return the response. You still have to handle any returned values in a callback that you provide, which will be added to the normal event loop (message queue) and processed sometime later.

Yes, it is confusing.

athila13898684  wrote

I'am calling csInterface.evalScript() which in turns calls a synchronous function inside a c++ library

There is a delay of 211 milliseconds before and after calling the evalScript

Both the CEP and the ExtendScript contexts process on the Main UI thread. Even if you were to delay the call into your C++ library, if it takes ~200ms to process something you would still cause a hitch in the UI - just later.

It may be possible, however, for you to make your C++ library perform its work asynchronously. There's a promising looking SoServerEval_f function defined in SoCClient.h (amongst others)... Once the work is done in your library (on a separate thread? time sliced somehow?) you might be able to trigger a callback into the ExtendScript context with some of the SoServer (?) APIs and then use the CSXS event system from there to dispatch an event back to CEP...?

Votes

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
community guidelines
Guru ,
Jan 28, 2018 Jan 28, 2018

Copy link to clipboard

Copied

LATEST

Bruce Bullis

Just want to confirm this a a bug which is Mac specific. On Windows evalScript is asynchronously.

See Re: Does CSInterface.evalScript() Work Asynchronously in Any Host Application? for the proofs.

It would be nice if it could be fixed.

Jonathan FermanVishakha​ Please take note.

Thanks

Trevor

Votes

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
community guidelines