Please ensure Javascript is enabled for purposes of website accessibility
Powered by Zoomin Software. For more details please contactZoomin

AVEVA™ Engineering

Progress and Interrupt Methods

  • Last UpdatedNov 14, 2022
  • 3 minute read

Form and Gadget callbacks may take a long time to execute, so it is often desirable to use the Progress Indicator on the Application Window's status bar (along the bottom) to indicate continuing progress to you. The Progress Indicator consists of a display text field and a progress bar.

You can write to the text field using:

!!FMSYS.setProgressText(!text is STRING )

You can set the %progress by:

!FMSYS.setProgress(!percent is REAL)

You can also query the current settings of both using the methods:

!real = !!FMSYS.Progress()

!string = !!FMSYS.ProgressText()

Additionally for some callback operations it may be required to allow you to interrupt the operation and choose to cancel it. The FMSYS methods Interrupt and setInterrupt allow this to be achieved.

The callback which provides the required operation, must be cyclical so that there is some repeated access point where you can report progress (approximately as a percentage of the total task), and check to see if you have clicked a stop button which you have provided on some displayed form.

In your callback function you must first notify the system of the identification of the stop button using the FMSYS method SetInterrupt:

!!FMSYS.setInterrupt(!!fmstop.stopButton )

Then at an appropriate point in the callback, check to see if the Stop button has been pressed using the FMSYS Interrupt method, and exit with a message if it has:

-- Initialise progress bar

!!FMSYS.setProgress(0)

!!FMSYS.setProgressText('Routing pipes')

do !next from 1 to 50

 ...

 !!RoutePipe( !next, . . . ) $*Route next pipe

 ...

-- Update the progress bar - first update the percentage

completion

!percent = ...

!!FMSYS.setProgress( !percent )

 -- Check if user pressed interrupt button

 if ( !!FMSYS.Interruppt() ) then

 return error 1 'Processing aborted'

  endif

enddo

Following is the PML code for a simple interrupt form !!fmstop.pmlfrm:

$* F&M test harness: Stop form for interrupt management

layout form !!fmstop dialog NoAlign

title 'STOP (!!fmstop)'

path down

para .stopText text |Press to quit task| width 20

button .stopButton |Quit| width 25 height 2

exit

define method .fmstop()

--Constructor

-- define callbacks

!this.firstShownCall = |!this.stopButton.background =

 'red'|

endmethod

Setting the progress causes any UI events to be processed and handled while the progress is running. If you want these events to be discarded, add an interrupt immediately before setting the progress. This ensures that only events on the interrupt will be handled and no other forms can be shown will the progress is running. For example:

!!FMSYS.Interrupt()

!!FMSYS.setProgress( !percent )

You can provide a form member using:

-- Flag to know if interrupt callback has been set

member .interruptCallbackSet is BOOLEAN

You can provide a button using:

-- Hidden stop button overlaps with preceding button

button .hiddenStop pixmap "AvevaSharedIcons>ID_STOP_SIGN>32" anchor right+bottom at xmin ymin

In the form constructor:

-- Hide the stop button as this is used only to register an interrupt callback

!this.hiddenStop.visible   = false

!this.interruptCallbackSet = false

Two form methods that can be called from within this form or child objects are:

---------------------------------------------------------------

--

-- Method:     .setInterruptCallback

--

-- Description: Set interrupt callback

--

---------------------------------------------------------------

define method .setInterruptCallback()

   -- F&M errors do not get caught by handles so we have to use our own flag to know if an interrupt callback has been set

  !!fmsys.setInterrupt(!this.hiddenStop)

  !this.interruptCallbackSet = true

endmethod

---------------------------------------------------------------

--

-- Method:      clearInterrupts

--

-- Description: Clear any interrupt events

--

---------------------------------------------------------------

define method .clearInterrupts()

  -- F&M errors do not get caught by handles so we have to use our own flag to know if an interrupt callback has been set

  -- Also the form must have been shown so we need to check we are not in the initialisation sequence of the form

  if (!this.interruptCallbackSet and !this.shown()) then

    -- Clear and ignore interrupts so we don't get any events inserted in the PML call stack

    !unusedCheck = !!fmsys.interrupt()

  endif

endmethod

Following is an example method to show progress in an object used by the form assuming a form name of !!interruptableForm:

---------------------------------------------------------------

--

-- Method:      showProgress

--

-- Description: Start or update progress bar with message

--

-- Arguments:

-- [#] [R/RW] [Data Type] [Description]

-- 1 R REAL Percent

-- 2 R STRING Message

--

---------------------------------------------------------------

define method .showProgress(!percent is REAL, !message is STRING)

  if (not istty) then

    -- Manage interrupts if running from form

    if (defined(!!interruptableForm)) then

      if (!percent le 1) then

        -- Called to start a load or save operation from the form so register the interrupt callback

        !!interruptableForm.setInterruptCallback()

      else

        -- Clear and ignore interrupts so we don't get any events inserted in the PML call stack

        !!interruptableForm.clearInterrupts()

      endif

    endif

    -- Show the message or clear the text if zero percent

    if (!percent eq 0 or !message.trim() ne '') then

      !!fmsys.setProgressText(!message)

    endif

    !!fmsys.setProgress(!percent)

  endif

endmethod

TitleResults for “How to create a CRG?”Also Available in