Author Topic: PJSR: How to abort a script  (Read 1773 times)

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2129
    • View Profile
PJSR: How to abort a script
« on: 2010 April 17 08:11:40 »
Hi,

I have a script that is running with "console.abortEnabled = true;". How can I trigger this abort()? The console pause/abort button is not accessible (grayed out) when the script is running. How can I query for an abort inside the script (something like abortRequested())?

Georg
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 6688
    • View Profile
    • http://pixinsight.com/
Re: PJSR: How to abort a script
« Reply #1 on: 2010 April 20 01:34:13 »
This one is slightly more complex. Come on.

Quote
console.abortEnabled = true;

This is a necessary step, but it is not sufficient. You must allow the core application to process interface events during your running routine, or the Pause/Abort button will never have a chance to work as such.

You have several ways to implement this behavior. One of them is through the "status monitoring" feature of images in PCL/PJSR. For example, consider the following snippet:

Code: [Select]
function AVeryHeavyAndLongTask( img )
{
   // Initialize img's status monitor
   img.statusEnabled = true;
   img.initializeStatus( "Be prepared to wait, my friend", img.width*img.height*img.numberOfChannels );

   for ( var c = 0; c < img.numberOfChannels; ++c )
      for ( var y = 0; y < img.height; ++y )
      {
         // Do your heavy stuff here for a row of pixels

         // Update the status monitor of the image
         img.advanceStatus( img.width );
      }

   // In case of doubt, make sure we reach the total monitor count  
   img.completeStatus();
}

Each time your code calls Image.advanceStatus(), PixInsight Core's GUI has a chance to process all pending events, including all unprocessed mouse events for the Pause/Abort button, if any, all console and image updates, etc. The typical percent progress indicator will be incremented and shown on the console to reflect the current monitoring count, which is good because in this way you provide feedback to the user.

This also means that you should not call this function too often, or you'll get a significant performance degradation, as GUI updates and event processing are relatively expensive. You must achieve a reasonable "granularity" for your event processing by adjusting the interval (in terms of relative computational work carried out) between two successive calls to advanceStatus(). Too fine-grained processing will lead to performance degradation; too little event processing will lead to an unresponsive interface most of the time.

The second way you have to ensure proper event processing is much simpler, although less eye-candy —the eye candy and the feedback given to the user, if any, are your entire responsibility. Just call the processEvents() global function somewhere inside your main loop:

Code: [Select]
function AVeryHeavyAndLongTask( img )
{
   for ( var c = 0; c < img.numberOfChannels; ++c )
      for ( var y = 0; y < img.height; ++y )
      {
         // Do your heavy stuff here for a row of pixels

         // Process pending GUI events
         processEvents();
      }
}

The same remarks made for Image's status monitor are valid here. processEvents() performs the same tasks except no feedback is provided on the console, so the user "doesn't know" what's happening unless you do something explicitly. Note also that the Console.abortEnabled property must also be set to true before calling processEvents(), or the Pause/Abort button will be disabled anyway.

In both cases, if the user clicks Pause/Abort and says Yes to the question "Do you want to abort..." your code will receive an exception. You can catch that exception to perform any necessary cleanup, but you should terminate script execution immediately if you do that. Of course, if you don't catch the exception (with a try {} catch {} construct) your script will be aborted as soon as it is thrown.
« Last Edit: 2010 April 20 02:23:29 by Juan Conejero »
Juan Conejero
PixInsight Development Team
http://pixinsight.com/