[Skip top navbar]

Andrew Gregory's Web Pages

Guilderton Lighthouse 30°20'24"S 115°29'31"E

-

Asynchronous Event Handling


This is basically a discussion on how the Synchronous Application Manager module works. See it for more details.


Introduction

As discussed in the Event-Driven Programming tutorial, GETEVENT is the command that should be used to get events. The Asynchronous I/O tutorial then showed how to program for any sort of asynchronous I/O. It finished up by saying that the two systems were completely incompatible!

The solution is to turn the GETEVENT command into just another instance of asynchronous I/O. It then becomes possible to apply the general asynchronous I/O framework to those events.


The Code

Where GETEVENT was used like:

LOCAL event%( 6 ) GETEVENT event%()

The asynchronous I/O version of it is:

LOCAL estat%, event%( 6 ) IOC( -2, 14, estat%, event%(), #0 )

It is otherwise identical to GETEVENT.

As a comparison:

GETEVENT and IOC comparison
GETEVENTAsynchronous I/O
PROC mainloop:
  GLOBAL done%

  LOCAL a%( 6 ), keycode%, keymod%, keyrep%, syscmd$( 255 )

  done% = 0
  
  
  
  DO

    GETEVENT a%()


    IF ( a%( 1 ) AND $400 ) = 0
      REM it's a keypress
      keycode% = a%( 1 )
      keymod% = a%( 2 ) AND $00FF
      keyrep% = a%( 2 ) / 256
      hdlKey:( keycode%, keymod%, keyrep% )

    ELSEIF a%( 1 ) = $401
      REM program has come to the foregound

    ELSEIF a%( 1 ) = $402
      REM program has gone to the background

    ELSEIF a%( 1 ) = $403
      REM machine has switched on

    ELSEIF a%( 1 ) = $404
      REM system command
      syscmd$ = GETCMD$
      hdlCmd:( LEFT$( syscmd$, 1 ), MID$( syscmd$, 2, 255 ) )

    ELSEIF a%( 1 ) = $405
      REM date has changed

    ELSE
      REM some unknown event (should never happen)

    ENDIF










  UNTIL done%

ENDP

REM Handle keypresses
PROC hdlKey:( keycode%, keymod%, keyrep% )

  IF keycode% = 27
    done% = 1 :REM allow main loop to exit

  ELSE
    REM do something with the key
    PRINT REPT$( CHR$( keycode% ), keyrep% );

  ENDIF

ENDP

REM Handle system command events
PROC hdlCmd:( syscmd$, sysfile$ )

  IF syscmd$ = "X"
    done% = 1 :REM allow main loop to exit

  ENDIF

  REM there are other "O" open and "C" close commands
  REM - see the Programming Manual

ENDP
PROC mainloop:
  GLOBAL done%

  LOCAL a%( 6 ), keycode%, keymod%, keyrep%, syscmd$( 255 ), stat%

  done% = 0

  IOC( -2, 14, stat%, a%(), #0 )

  DO

    IOWAIT
    IF stat% <> -46

      IF ( a%( 1 ) AND $400 ) = 0
        REM it's a keypress
        keycode% = a%( 1 )
        keymod% = a%( 2 ) AND $00FF
        keyrep% = a%( 2 ) / 256
        hdlKey:( keycode%, keymod%, keyrep% )

      ELSEIF a%( 1 ) = $401
        REM program has come to the foregound

      ELSEIF a%( 1 ) = $402
        REM program has gone to the background

      ELSEIF a%( 1 ) = $403
        REM machine has switched on

      ELSEIF a%( 1 ) = $404
        REM system command
        syscmd$ = GETCMD$
        hdlCmd:( LEFT$( syscmd$, 1 ), MID$( syscmd$, 2, 255 ) )

      ELSEIF a%( 1 ) = $405
        REM date has changed

      ELSE
        REM some unknown event (should never happen)

      ENDIF

      IF NOT done%
        REM new event read
        IOC( -2, 14, stat%, a%(), #0 )
      ENDIF

    REM could add in here ELSEIF tests on other status words

    ENDIF

  UNTIL done%

ENDP

REM Handle keypresses
PROC hdlKey:( keycode%, keymod%, keyrep% )

  IF keycode% = 27
    done% = 1 :REM allow main loop to exit

  ELSE
    REM do something with the key
    PRINT REPT$( CHR$( keycode% ), keyrep% );

  ENDIF

ENDP

REM Handle system command events
PROC hdlCmd:( syscmd$, sysfile$ )

  IF syscmd$ = "X"
    done% = 1 :REM allow main loop to exit

  ENDIF

  REM there are other "O" open and "C" close commands
  REM - see the Programming Manual

ENDP

-