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

Debounce w/o setTimeout()?

Advocate ,
Sep 07, 2016 Sep 07, 2016

Copy link to clipboard

Copied

Hi,

I'm looking for a way to implement a Debounce function (see here), like this one:

// Returns a function, that, as long as it continues to be invoked, will not

// be triggered. The function will be called after it stops being called for

// N milliseconds. If `immediate` is passed, trigger the function on the

// leading edge, instead of the trailing.

function debounce(func, wait, immediate) {

  var timeout;

  return function() {

  var context = this, args = arguments;

  var later = function() {

  timeout = null;

  if (!immediate) func.apply(context, args);

  };

  var callNow = immediate && !timeout;

  clearTimeout(timeout);

  timeout = setTimeout(later, wait);

  if (callNow) func.apply(context, args);

  };

};

To be used in ScriptUI.

Problem is that we don't have setTimeout in ExtendScript land, and $.sleep is blocking / not cancelable.

There is a working implementation for InDesign, using app.idleTasks, which, again, we don't have in Photoshop so back to square one.

Suggestions?

Thank you!

Davide Barranca

TOPICS
Actions and scripting

Views

2.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
Adobe
Enthusiast ,
Sep 07, 2016 Sep 07, 2016

Copy link to clipboard

Copied

Depends on the reason it no longer gets called.. If you have a main-loop of sorts that keeps on running, you can have

  • registerDebounce(func, wait, immediate) that just stores func, wait and start time to a global table
  • add tick() function to the main loop that does the logic "has it been called since wait" and either invoke the callback or reset start

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
Advocate ,
Sep 07, 2016 Sep 07, 2016

Copy link to clipboard

Copied

Matias, I'm not sure it could work, since $.sleep is blocking, and there's no way to cancel it – while setTimeout leaves the rest running.

Apparently a proper setTimeout implementation has been added in After Effects 2015, so I've requested that feature for Photoshop myself.

Davide

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
Engaged ,
Dec 03, 2017 Dec 03, 2017

Copy link to clipboard

Copied

I am also trying to find a clean way to to this... I thought to myself:

  • Start a timer
  • Display a dialog [Stop, Continue]
  • Cancel the dialog when the timer expires, or the user hits Cancel.

I don't need to do any processing in the background. I'm trying to insert periodic pause points in my action/script that give Photoshop a chance to catch up on the display and let the user stop the operation if they are happy with the results.

I would like to do this in ScriptUI.

Something along these lines:

    var w = new Window("palette");     
    // Add some buttons/status/etc.    
    // setTimeout( w.close(), 3000)    
    w.show ();
    $.sleep(3000)

But sleep is not interruptible.

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
People's Champ ,
Dec 03, 2017 Dec 03, 2017

Copy link to clipboard

Copied

Maybe so. The function is interruptible)

wait(3)

alert()

function wait(sec)

    {

    $.hiresTimer;

    var timer = 0;

    try {

        while(1)

            {

            step_by_step();

            timer += ($.hiresTimer/1000000);

            if (timer > sec) break;

            }

        }

    catch(e) {}

    accelerated(); 

    }

function accelerated()  {  set_performance("accelerated"); }

function step_by_step() {  set_performance("stepByStep");  }

function set_performance(mode)

    {

    try {

        var d1 = new ActionDescriptor();

        var d2 = new ActionDescriptor();

        var r1 = new ActionReference();

        r1.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( "PbkO" ) );

        r1.putEnumerated( charIDToTypeID( "capp" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

        d1.putReference( charIDToTypeID( "null" ), r1 );

        d2.putEnumerated( stringIDToTypeID( "performance" ), stringIDToTypeID( "performance" ), stringIDToTypeID( mode ) );

        d1.putObject( charIDToTypeID( "T   " ), charIDToTypeID( "PbkO" ), d2 );

        executeAction( charIDToTypeID( "setd" ), d1, DialogModes.NO );

        }

    catch (e) { throw(e); }

    }

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
Engaged ,
Dec 04, 2017 Dec 04, 2017

Copy link to clipboard

Copied

Awesome, r-bin. Thank you very much! The gist seems to be to use a hard loop which continuously invokes a Photoshop call. In particular, it seems you're messing with the action PlayBack options. I hadn't even thought about changing the Playback behavior. My tool has a lot of steps and it would be really, really slow if I let it do step-by-step or pause between steps, so you've given me TWO great tools.

Thanks!

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
Engaged ,
Dec 05, 2017 Dec 05, 2017

Copy link to clipboard

Copied

Thank you r-bin , I'll surely give it a try!

I don't recall now what I needed it for, but it's surely great to have.

Best,

Davide

Davide Barranca - PS developer and author
www.ps-scripting.com

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
LEGEND ,
Dec 24, 2017 Dec 24, 2017

Copy link to clipboard

Copied

Is that your twin brother who created this topic? I answered for one of your post in other theard but then found you use 2 accounts and I'm not sure you are still active on that one? Display thumbnail of PSD on ScriptUI dialog

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
Engaged ,
Dec 05, 2017 Dec 05, 2017

Copy link to clipboard

Copied

Thanks to r-bin, here is a self-contained "pause" script which pops open a dialog, but allows the user to stop the countdown. Would be slightly better if there was a completely innocuous action to execute. Here it is using "Reset Palette". Also note that closing the window with the cancel does NOT stop the countdown... it just becomes invisible.

/*  Waits up to 'sec' seconds. Can continue/interrupt the wait with a Continue button

    Counts down the time, too.  With much thanks to r-bin

*/

function wait(sec, title, description)

{

    $.hiresTimer;

    // Shave off a half second because we force it to wait at the end.

    var timer = sec - 0.6;

    var waiting = true

    var w = new Window("palette", title );

    var txt = w.add('statictext',undefined, description)

    var countdown = w.add('statictext',undefined, "start")

    var continueBtn = w.add('button', undefined, 'Continue');

    continueBtn.onClick = function () { waiting = false; }

    // An innocuous Photoshop Action (Reset the fg/bg colors to default)

    var idRset = charIDToTypeID( "Rset" );

    var resetFgBg = new ActionDescriptor();

    var aref = new ActionReference();

    aref.putProperty( charIDToTypeID( "Clr " ), charIDToTypeID( "Clrs" ) );

    resetFgBg.putReference( charIDToTypeID( "null" ), aref );

    try {

        w.show ();

        while(waiting && timer > 0) {

            executeAction( idRset, resetFgBg, DialogModes.NO );

            countdown.text = Math.round(timer * 10, 2) / 10

            timer -= ($.hiresTimer/1000000);

        }

        txt.text = "  CONTINUING  ";

    } catch(e) {  // Ignore errors

    }

    $.sleep(600)   // Uninterruptible... be sure "Continuing" is seen.

    w.close();

}

// Force photoshop to catch up with the display

app.refresh()

wait(10, "Pausing...", "... for 10 seconds ...")

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
People's Champ ,
Dec 06, 2017 Dec 06, 2017

Copy link to clipboard

Copied

Use

while(w.visible && waiting && timer > 0)

UPD.

There is an unpleasant feature in CC2018 on win7. Did you notice how the digits in the info panel flash, if there is an open document on which the mouse is located?

UPD2.

When you use step_by_step() in a loop, then you can move the timer panel, zoom with the mouse wheel and scroll the document with scrollbars and not use app.refresh() at all. )

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
LEGEND ,
Mar 08, 2018 Mar 08, 2018

Copy link to clipboard

Copied

Loll, third brother? DavideBarranca

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
Engaged ,
Mar 08, 2018 Mar 08, 2018

Copy link to clipboard

Copied

I have been using the old account for years, but this is the one linked to my CC subscription.

I'm the twin brother of myself 🙂

Davide Barranca - PS developer and author
www.ps-scripting.com

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
LEGEND ,
Mar 08, 2018 Mar 08, 2018

Copy link to clipboard

Copied

LATEST

hah I'm sorry for the joke. I came here again as I was in other topic now and saw that like here you answered to someone from 2 different accounts, but that time from one I didn't know yet. I thought maybe you use separate accounts for different Adobe products, but when I noticed you use them even to post in range of same topic / same product I was a little confused ). There is another advantage of your another accounts. Each of them presents higher level of abbilities. That Davide from his first account was probably real newbie yet

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