locked
How does this program appear to loop? RRS feed

  • Question

  • I am just learning Small Basic.  I've programmed in other languages as a hobby for years, so I think I understand how programs work...more or less.  I have always understood that in order for commands to be executed over and over, the program has to loop in some way.  But the following program appears to loop...the two command lines continually execute awaiting key input, but there is no "loop" in the program.  How does Small Basic do that?  Thanks.

    GraphicsWindow.Height = 300
    GraphicsWindow.Width = 300
    GraphicsWindow.Title = "Graphics Window"
    shape1 = Shapes.AddRectangle(100,50)
    Shapes.Move (shape1, 100, 125)
    return = "Return"
    GraphicsWindow.KeyDown = keydown
    GraphicsWindow.KeyUp = keyup


    Sub keyup
      If GraphicsWindow.Lastkey = "Return" Then
        Shapes.Rotate(shape1,0)
      EndIf
    EndSub

    Sub keydown
      If GraphicsWindow.LastKey = "Return" Then
        Shapes.Rotate (shape1, 90)
      EndIf
    EndSub
     

    Wednesday, August 8, 2018 10:23 AM

Answers

  • When you have e.g GraphicsWindow.KeyDown in your program (and the corresponding Sub), SmallBasic assumes you want to  do something on keydown, so the program does't end but keep waiting for a key. When a key is pressed, the Sub is executed, and the program waits again. If you want the program to stop on e.g. a Q , you need in the Sub:

    If GraphicsWindow.LastKey="Q" Then

      Program.End()

    EndIf


    Jan [ WhTurner ] The Netherlands


    • Edited by WhTurner33Editor Wednesday, August 8, 2018 11:28 AM
    • Proposed as answer by litdev Friday, August 10, 2018 7:37 PM
    • Marked as answer by Rizdek Sunday, August 12, 2018 2:00 PM
    Wednesday, August 8, 2018 11:25 AM
    Answerer
  • Whenever you register an event handler, like
    GraphicsWindow.KeyDown = KeyDown

    it has to loop continuously at a special resolution (about 20-30 ms) in the background to detect,  if that event has been raised. This is managed by .NET automatically and with no "loop" in the program.

    Not just for KeyDown, but also for all the other events like MouseDown, ButtonClicked etc.

    You can see it by running following modification (using the 'AnyKey' key :-) ).
    Press down a key and hold it pressed as long as you want. After releasing it you'll see that in the meantime there has been a lot of ...x "loops" in the background (= attempts/queries to detect a raised event)

    GraphicsWindow.Height = 300
    GraphicsWindow.Width = 300
    GraphicsWindow.Title = "Graphics Window"
    shape1 = Shapes.AddRectangle(100,50)
    Shapes.Move(shape1, 100,125)
    
    GraphicsWindow.KeyDown = KeyDown
    GraphicsWindow.KeyUp = KeyUp
    
    Sub KeyDown
      'If GraphicsWindow.LastKey = "Return" Then
      Shapes.Rotate(shape1, 90)
      
      If n < 1 Then
        last = Clock.ElapsedMilliseconds
        GraphicsWindow.Title = "Release key whenever u want"
      EndIf
      n = n + 1
      'EndIf
    EndSub
    
    Sub KeyUp
      'If GraphicsWindow.Lastkey = "Return" Then
      Shapes.Rotate(shape1, 0)
      
      dur = Clock.ElapsedMilliseconds - last
      t = Math.Round(100*dur/n) / 100 ' ~ 30 ms/loop (300 ticks a 100 µs) ->  ~ 33.33 Hz
      f = Math.Round(100 * 1000*n/dur) / 100    ' f = 1000/t = 1000 *n/dur
      GraphicsWindow.Title = n +"x in "+ dur +" ms , "+ t +" ms/loop = "+ f +" Hz"
      n = 0
      'EndIf
    EndSub

    • Proposed as answer by litdev Friday, August 10, 2018 7:37 PM
    • Marked as answer by Rizdek Sunday, August 12, 2018 1:59 PM
    Wednesday, August 8, 2018 9:42 PM
    Answerer

All replies

  • When you have e.g GraphicsWindow.KeyDown in your program (and the corresponding Sub), SmallBasic assumes you want to  do something on keydown, so the program does't end but keep waiting for a key. When a key is pressed, the Sub is executed, and the program waits again. If you want the program to stop on e.g. a Q , you need in the Sub:

    If GraphicsWindow.LastKey="Q" Then

      Program.End()

    EndIf


    Jan [ WhTurner ] The Netherlands


    • Edited by WhTurner33Editor Wednesday, August 8, 2018 11:28 AM
    • Proposed as answer by litdev Friday, August 10, 2018 7:37 PM
    • Marked as answer by Rizdek Sunday, August 12, 2018 2:00 PM
    Wednesday, August 8, 2018 11:25 AM
    Answerer
  • Whenever you register an event handler, like
    GraphicsWindow.KeyDown = KeyDown

    it has to loop continuously at a special resolution (about 20-30 ms) in the background to detect,  if that event has been raised. This is managed by .NET automatically and with no "loop" in the program.

    Not just for KeyDown, but also for all the other events like MouseDown, ButtonClicked etc.

    You can see it by running following modification (using the 'AnyKey' key :-) ).
    Press down a key and hold it pressed as long as you want. After releasing it you'll see that in the meantime there has been a lot of ...x "loops" in the background (= attempts/queries to detect a raised event)

    GraphicsWindow.Height = 300
    GraphicsWindow.Width = 300
    GraphicsWindow.Title = "Graphics Window"
    shape1 = Shapes.AddRectangle(100,50)
    Shapes.Move(shape1, 100,125)
    
    GraphicsWindow.KeyDown = KeyDown
    GraphicsWindow.KeyUp = KeyUp
    
    Sub KeyDown
      'If GraphicsWindow.LastKey = "Return" Then
      Shapes.Rotate(shape1, 90)
      
      If n < 1 Then
        last = Clock.ElapsedMilliseconds
        GraphicsWindow.Title = "Release key whenever u want"
      EndIf
      n = n + 1
      'EndIf
    EndSub
    
    Sub KeyUp
      'If GraphicsWindow.Lastkey = "Return" Then
      Shapes.Rotate(shape1, 0)
      
      dur = Clock.ElapsedMilliseconds - last
      t = Math.Round(100*dur/n) / 100 ' ~ 30 ms/loop (300 ticks a 100 µs) ->  ~ 33.33 Hz
      f = Math.Round(100 * 1000*n/dur) / 100    ' f = 1000/t = 1000 *n/dur
      GraphicsWindow.Title = n +"x in "+ dur +" ms , "+ t +" ms/loop = "+ f +" Hz"
      n = 0
      'EndIf
    EndSub

    • Proposed as answer by litdev Friday, August 10, 2018 7:37 PM
    • Marked as answer by Rizdek Sunday, August 12, 2018 1:59 PM
    Wednesday, August 8, 2018 9:42 PM
    Answerer