Silverfrost Forums

Welcome to our forums

Process button pushes on interrupt?

2 Dec 2021 1:15 #28537

This may be a very simple question, as I am not an expert. I want to do Monte-Carlo type calculations, where the math is put in a loop, and the software crunches until a termination criterion is met. Typically one shows the value(s) to the operator while the converging is in process, and the operator halts (via button press) when things look ok. I'm fairly well versed on setting up buttons and other such things, but the program comes to a halt while awaiting a user button press. Is there a way to set up a calculation such that somewhere in the loop the software checks for a button press, but then continues the loop if no press is detected? In the old days we called that responding to an 'interrupt.'

2 Dec 2021 5:34 #28538

Clearwin+does provide for this functionality via menu %mn option.

By creating a menu option for interupt, you can run your calculation and at selected stages (say start or end of each DO) test if the interupt option has been selected.

The following code provides an example for the code required, although it may not be complete.

First example shows; setting initial variables; then looping. In loop, first 'call user_look' to look for user interupt then perform 'work' with 'i = copy_graphics_region@' then final stage is delay to show display ( not reguired but may be of interest)

!
!  do loop code that includes interupt test and delay test for uniform display flow
!
      on_run   = 0                 !  turn off normal menu
      on_stop  = 1                 !  turn on interrupt menu
      run_flag = .true.            !  program run is enabled
      quiton   = .false.           !  quit interrupt enabled
      call window_update@ (on_run)
      call window_update@ (on_stop)
      call window_update@ (run_flag)
      call window_update@ (quiton)
!
      call permit_another_callback@
!
!      now cycle through each screen display
!
      num = wobble_num_screens*(2*wobble_tot_screens+1)           ! run for 60 seconds
      DO k = 0, num
         CALL elapse_second (CPUS)
!
         II = MOD (k,WOBBLE_NUM_SCREENS*2)
         IF (II > WOBBLE_NUM_SCREENS) II = WOBBLE_NUM_SCREENS*2-II
!
         call user_look            ! look for user interupt
!z         CALL QUITEST
          IF (QUITON) then
            call screen_report ('QUITON recognised')
            EXIT
          end if
          if (.not.run_flag) then
            call screen_report ('run_flag recognised')
            EXIT
          end if
!
         i = copy_graphics_region@ (w_handle,   6,6,nxpix,nypix,          &
                                    handle(ii), 6,6,nxpix,nypix, srccopy)
 
!        delay based on screen update time
!
         call elapse_second (cpue)
         wait = delay - (cpue-cpus)
         if (wait.gt.0.02) then
            call sleep@ (wait)
            call elapse_second (cpuw)
            write (98,1007) k,ii, ' paint=',cpue-cpus, ' target=',delay, ' : left=',wait, ' sleep=',cpuw-cpue
         else
            write (98,1007) k,ii, ' paint=',cpue-cpus, ' target=',delay
         end if
         write (string,1004) 'Recover display', ii, cpue-cpus
         call screen_report (string(1:26))
!
      END DO
2 Dec 2021 6:15 #28539

ctd : next part of code shows: menu setup to provide interrupt button and user_look to test for interupt being selected.

subroutine user_look
!
!  Temporary suspension of program to enable update of interupt
!   this should be equivalent to QUITEST
!   it should be only called in wobble mode
      include <clearwin.ins>
      call temporary_yield@
      return
end subroutine user_look

subroutine Saplot_Others_Menu
!
! These menu options include Interupt
    include <JDC_menu.ins>
!
    integer*4 i
    integer*4 last_view_func,                 &
              next_view_func,                 &
              option_update_plot,             &
              Screen_dump_func,               &
              detect_interupt_func,           &
              exit_func,                      &
              Help_func
    external  last_view_func,                 &
              next_view_func,                 &
              option_update_plot,             &
              Screen_dump_func,               &
              detect_interupt_func,           &
              exit_func,                      &
              Help_func
!
    i = winio@  ('%mn[~<Last]&',          on_run,  last_view_func)
    i = winio@  ('%mn[~>Next]&',          on_run,  next_view_func)
!
    i = winio@ ('%mn[~&Update]&',         on_run,  option_update_plot)
!
    i = winio@ ('%mn[~&Dump]&',           on_run,  Screen_dump_func)
!
    i = winio@ ('%mn[~&Interupt]&',       on_stop, detect_interupt_func)
!
    i = winio@ ('%mn[Exit]&',                      exit_func)
    i = winio@ ('%mn[~&Help]&',           on_run,  Help_func)
!
end subroutine Saplot_Others_Menu

integer*4 function detect_interupt_func()
!
!  Called when user interupts the program
!   run_flag & quiton are set to .true.
!
!    in general on_stop should be 0, then set to 1 when interupt is enabled
!    in this case user_look should be called regularly to enable looking at the interupt state
!
!    when interupt is enabled (on_stop = 1 and run_flag=quiton=.false.)
!    runing will proceed until quiton is changed to true
!         on_run   = 0
!         on_stop  = 1
!         run_flag = .true.
!         call window_update@ (on_run)
!         call window_update@ (on_stop)
!         call temporary_yield@
!         call permit_another_callback@
!         call perform_graphics_update@
!  initialise in crtclr for start of graphics display ?
!
      include <JDC_menu.ins>
      include 'quitcm.ins'
      integer*4 i
!      call crt_interupt   ! set screen mode to menu
!      call screen_report ('Simulation interupted')
!
      call call_back_statistics ('detect_interupt_func', 3)
!
      i = winio@ ('%si? Interrupt has been selected&')
      i = winio@ ('%nl%cn%bt[OK]')
!
      if (i > 0) then
         run_flag = .false.
         quiton   = .true.
         call window_update@ (run_flag)
         call window_update@ (quiton)
         write (98,'(a)') 'Interrupt detected'
      end if
!
      detect_interupt_func = 1
end function detect_interupt_func

I could have cleaned out unnecessary other code, but is somewhat relevant Please excuse some of the incorrect comments as this code coveres a range of O/S implementations, prior to Clearwin+ (eg QUIT_TEST and QUITON)

2 Dec 2021 8:06 #28540

Basically the solution is to call temporary_yield@() within the loop (either every cycle or every n cycles). This allows your application to process mouse move events and to detect when a button has been pressed or a menu item has been selected etc..

7 Dec 2021 1:42 #28578

Thank you Paul. I was able to bring up one of your examples and it seems to work fine.

Please login to reply.