! Test switching of pipe inputs and make sure that the pipe does not block
! following a switching of pipe inputs by a primitive during restart. See
! %TEST_RESTART_BLOCKING2 for a non-interactive version of this test.
!
! Author:  J. Czechowski IV
!
startmacro
  switch INTERACTIVE interAct  GET DEF=TRUE  SDEF=TRUE
  switch BASELINE    baseline  GET DEF=FALSE SDEF=TRUE
  switch DEBUGPLOT   debugplot GET DEF=FALSE SDEF=TRUE

  invoke stateList nxm.sys.lib.Command.stateList
  set sfreq1 1000
  set sfreq2 4000

  if interAct then
    info "This test may produce warnings saying 'NOOP restarted, but did not reconnect...'."

    set instructions "1) Set 'Suspend Unused' to 'Yes'\n&
                      (suspends the unused instance of WAVEFORM)\n&
                      2) Change 'Input to NOOP'\n&
                      => Raster sfreq switches between ^{sfreq1} and ^{sfreq2}\n&
                      => The _NOOP pipe should always be flowing.\n&
                      => The other two pipes should not get filled up, but the pipe may stop when suspended."

    if debugplot then
      set fname "test_restart_blocking_plotdebug.prm"
      erase/WARN=N fname
    endif
    pipe init
      panel/msgid=MAIN/setup/controls=gc

      waveform/id=wave1/throttle=real _wave1 "SF" Inf sin freq=sfreq1 amp=1e4 delta=1e-4
      waveform/id=wave2/throttle=real _wave2 "SF" Inf sin freq=sfreq2 amp=1e4 delta=1e-4

      noop/tl=1 _wave1 _noop

      fft/dbf _noop _fft{form=sb} nfft=1k over=0
      plot/id=idplot/READOUT=Show|OnAxis|T|dT _fft /lpb=16

      if debugplot then
        noop/id=NoopToFile _fft ^{fname}{FLAGS=APPEND}
      endif

      gcontrol label  macro   "MACRO"
      gcontrol menu main "Exit with Status = " "PASS,FAIL" /tleft
      gcontrol text idtext "Instructions" "^instructions" 24 10 /title

      gcontrol choice  input  "Input to NOOP: " "_WAVE1,_WAVE2" "_WAVE1" /tleft
      gcontrol choice  unused "Suspend Unused:" "Yes,No" "No" /tleft

      gcontrol label   status "Pipe/Process Status"
      gcontrol choice  state1 "WAVE1 State:" "^stateList" /tleft /msg=no /edit=no
      gcontrol pipemon pmon1  _wave1
      gcontrol choice  state2 "WAVE2 State:" "^stateList" /tleft /msg=no /edit=no
      gcontrol pipemon pmon2  _wave2
      gcontrol choice  stateN "NOOP  State:" "^stateList" /tleft /msg=no /edit=no
      gcontrol pipemon pmon   _noop
      gcontrol choice  stateF "FFT  State:" "^stateList" /tleft /msg=no /edit=no
      gcontrol pipemon pmon   _FFT

      set gc.main.itemColors   {PASS=GREEN,FAIL=RED}
      set gc.unused.itemColors {Yes=YELLOW,No=GREEN}
      set gc.state1.itemColors {Process=GREEN,Suspend=YELLOW}
      set gc.state2.itemColors {Process=GREEN,Suspend=YELLOW}
      set gc.stateN.itemColors {Process=GREEN,Suspend=YELLOW}
      set gc.stateF.itemColors {Process=GREEN,Suspend=YELLOW}

      set gc.state1.value reg.wave1.state
      set gc.state2.value reg.wave2.state
      set gc.stateN.value reg.noop.state

      set REG.PANEL.TIMERS   1
      set REG.PANEL.TIMER(0) 1
    pipe off

    if debugplot then
      plot fname
      erase fname
    endif
  endif
endmacro

!******************************************************************************!
procedure processMessage m:msg
  if msg.name eqs "MAIN" then
    assert/text="^reg.main.name: User indicated tests" msg.data eqss "PASS"
    pipe stop

  elseif msg.name eqs "TIMER" then
    ! update gcontrols with current pipe states
    set gc.state1.value reg.wave1.state
    set gc.state2.value reg.wave2.state
    set gc.stateN.value reg.noop.state
    set gc.stateF.value reg.fft.state

  elseif msg.name eqs "UNUSED" then
    if msg.data isTrue then
      call suspendUnused gc.input.value
    else
      call suspendUnused "NONE"
    endif

  elseif msg.name eqs "INPUT" then
    if gc.unused.value isTrue then
      call suspendUnused msg.data
      pause 1                      ! <-- Force a read with no data left in the pipe (Bug 930).
    endif

    set reg.noop.setArg("IN") msg.data
    set reg.noop.setState     "Restart"

  else
    say "Unhandled message name=^msg.name info=^msg.info fid=^msg.fid data=^msg.data"
  endif
return

!******************************************************************************!
procedure suspendUnused s:toUse
  if toUse eqs "NONE" then
    set reg.wave1.setState "Resume"
    set reg.wave2.setState "Resume"
  elseif toUse eqs "_WAVE1" then
    set reg.wave1.setState "Resume"
    set reg.wave2.setState "Pause"
  elseif toUse eqs "_WAVE2" then
    set reg.wave1.setState "Pause"
    set reg.wave2.setState "Resume"
  else
    set reg.wave1.setState "Resume"
    set reg.wave2.setState "Resume"
  endif
return
