We would like to build a community for Small Basic programmers of any age who like to code. Everyone from total beginner to guru is welcome. Click here to register and share your programming journey!


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
What command should I use to make my program pause until the user presses a key?
#11
(translated by Google translator)

This will not necessarily result in the processor being idle.
While the Program is waiting for a key to be pressed, the Program can execute the Pause Method, or the Program can execute any other code you want.
As soon as the “Key Pressed” event handler routine determines that a key has been pressed, the routine will perform the actions that you wrote in the handler code.

Give us the specific code so we can fix it easily.  Shy
Reply
#12
I think Elzaimer is asking why there is no specific command in Small Basic to wait until a key is pressed in the GraphicsWindow.  Why he has to implement a small wait loop to handle this.

Code:
  frappe = ""
  While (frappe = "")
  EndWhile

Long answer -

At a low level the OS is running message loops continually checking for events and passing them to other applications that have their own message loops; they are everywhere.

Google about message loops, for example https://en.wikipedia.org/wiki/Message_lo...ft_Windows.

Small Basic gets events by requesting that it is informed by the OS when for example a key is pressed while the GraphicsWindow has focus - so when a key press is detected by th OS it is dispatched (passed around) from OS to application to window etc through layers of message loops until it finally calls your SB event subroutine.

How we handle that event (or what we do while waiting for it) is then up to us in our SB program.  Nonki's program showed one way, and I showed another.  In both cases the program keeps looking for the event and while waiting does nothing except going round its loop.  Despite this seeming odd, this is totally standard practice.

If you are concerned about wasting cpu while the loop is running you could put a small delay in the loop, say Program.Delay(10), but I wouldn't since you are interested in reaction times it would mess timings up a bit and is unnecessary.  If the loop does nothing it consumes no resources, allocates no memory or other things that would adversely affect other programs and is probably mostly optimised away by the compiler and will be insignificant compared to everything else going on.  Remember every other process is running their own message loops (getting messages about all sorts of things), including passing instructions to the cpu and gpu at extremely high rates.  The OS is quite clever at prioritising/optimising itself.

If we added a SB method to wait for next key press, it would be implemented as a message loop waiting for the event.

Short answer -

Thats how it is with programming - somethimes there isn't a ready made command.

There are other issues as well.  Consider why the code below doesn't work as maybe expected.

Code:
GraphicsWindow.Show()
GraphicsWindow.KeyDown = OnKeyDown

For i = 1 To 100
  key = ""
  While (key = "")
  EndWhile
EndFor

Sub OnKeyDown
  key = GraphicsWindow.LastKey
  GraphicsWindow.Clear()
  GraphicsWindow.DrawText(10,10,"Test "+i+" key = "+key)
EndSub

It will be instructive to work on this a bit and also Nonki's code.

The fix I gave was probably not the best way to write your program, but the simplest 'Fix' - and more infromation was given in the articles I posted links to.
[-] The following 3 users Like litdev's post:
  • AbsoluteBeginner, Elzaimer, z-s
Reply
#13
Litdev fix is the best solution to this problem i think.
ZS
Reply
#14
I wouldn't program an infinite loop without a program.delay().
One of my first experiences with Small Basic was that this simple programming language, which also comes from Microsoft and was intended for children, slowed down the Windows XP operating system (50% CPU load). On weak hardware, that's the end.  Angel

With WIN 7, the code example generates a CPU load of 8%!! With Program.delay(1) it is 0%.
If the operating system briefly gains control of the program, it saves CPU load and energy.  Smile

I mean, WINDOWS doesn't achieve an accuracy of < 10ms with the overkill of events and processes.
It is not a real-time operating system.
[-] The following 2 users Like Scout's post:
  • Elzaimer, litdev
Reply
#15
Yea I tend to agree in general, however in this case I did't see any adverse effect (<1% cpu on my PC) and the code was about timing so introducing a Delay in the wait loop looked nasty (I also get the point that timing won't be that accurate anyway).  I didn't really want to open this tin of worms all in one go, I did leave some links to where it is discussed a bit more though.

Now we have openned the tin and see some of the issues, this is how I might refactor the program, MXJJ240.000

Note the silly long Delay on line 10 - clearly reduce to something that shows very low cpu in practice.

However, we can see that the Delay doesn't influence the timing because the timing is set within the event when it fires (maybe during a delay on UI thread).

I do all UI graphics updates on the main UI thread (not in an event thead - it will only do the UI update after the event thread is finished in an case and we cannot be sure exactly when it will actually happen if the main UI thread is also doing stuff).  This is the issue with the code I showed in post 13 and also probably why 'Program.Delay(2500) was commented in Elzamier's original code.

My reccomendation is to always use a game loop (with delay) and only use event subroutines to set flags that are handled predictably in sequence in the game loop.  Especially important for SB with its global variable scope.  Its hard to persude people of this without first going through some pain.

Interesting stuff and not just specific to Small Basic, understanding it here is fully transferable as is how it works under the hood in all window programs.
[-] The following 4 users Like litdev's post:
  • AbsoluteBeginner, Elzaimer, Scout, z-s
Reply
#16
Hii Elzaimer
Your code was complicated i made a short version try this: PZPS756.000
but one problem is in SB timer cant restart so may be anyone help and improve the code so that timer can restart .

(06-24-2024, 12:30 PM)AbsoluteBeginner Wrote: Also, there doesn't seem to be any code in your "test" routine that tells the program what to do if no key is pressed. Therefore, the program does not stop and does not wait for a key to be pressed.
AB Was Right See My Example I Have Used Timer.
If No Key Is Pressed In 5 Second Then It Show "You Lost Starting Again In 5 Second"
But There Is Problem That With The Timer That It Doesn't Restart When We Have Give Correct Answer.
ZS
Reply
#17
ZS,

Nice try!

Below is your main UI thread code - I always put this at the top of a program.

Code:
GraphicsWindow.BackgroundColor = "White"
GraphicsWindow.FontSize = 40
StartGame()

'Restart Program
Program.Delay(5000)
GraphicsWindow.Clear()
'Timer Should Stop Here But There Is No Such Function In SB To Stop  Timer

StartGame()

Everything else is subroutines, including events.  Note that you only call StartGame 2 times.  In the meantime within the 5 second pause the events do various stuff.  As an event program gets more complex it will be harder to debug; this is why I always recommend the event loop with small delay handling flags set in event subs.

You can use Timer methods Pause and Resume, but trying to do it this way will get complex and very hard to understand - a fun project though Smile
Reply
#18
Hello,

I now want my program (TPCQ413.000) to display at the end of the test the standard deviation of the different reaction times, to evaluate the constancy of the concentration throughout the test.
but it seems that my variable is text instead of numeric even though it comes from a mathematical calculation (lines 87 to 93)!
This can be seen on the display at the end of the test.
I do not understand...
Is it possible to define de variable types somehow ?
Reply
#19
(translated by Google translator)

Hi, Elzaimer  Shy
In fact, in Small BASIC all variables have one type: primitive.
This type allows you to process a wide variety of data. But, for such versatility you have to pay with speed.
However, there are several methods that allow you to check the type of data that is in a variable.

Array.IsArray(array)
LDUtilities.IsNumber(input)

To avoid confusion, I always use a prefix in variable names.

n_varName => numeric
b_varName => boolean
s_varName => string
lis_varName => list
arr_varName => array
shp_varName => shape

and so on.
[-] The following 2 users Like AbsoluteBeginner's post:
  • litdev, z-s
Reply
#20
In Small Basic, whether a variable is treated as number or array or string is context dependent.  The operator + works on all data types with precedence left to right.

Consider the following examples.

Code:
TextWindow.WriteLine(1+2)
TextWindow.WriteLine(1+2+"A")
TextWindow.WriteLine("A"+1+2)
TextWindow.WriteLine(Text.Append(1,2)+"A")

In your code I would also initialise SommeDesEcartsALaMoyenne to 0 before it is added to.  SB does assume variables are "" or 0 initially, but good practice to initialise something before you use it.  Also your SD calculation is unusual, usually it would be RootMeanSquare.
[-] The following 1 user Likes litdev's post:
  • Elzaimer
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)