timers during heavy load

stevefan

Member
Licensed User
Longtime User
I want my program to update a label every 500ms.

do while <some condition>
'cpu intensive stuff here mainly string manipulation
label1.text=somestring
doevents
sleep(500)
loop

The problem is that the heavy cpu stuff takes up to 200ms or so, leading

to variation in delay between label updates, when I need it to be

smooth, from a visual perspective.

I replaced the sleep, instead after updating the form I start a timer,

then do the string processing, and then waiting for the timer to expire

before the label update, but get the same result.

do while ...
'cpu intensive stuff
do while tmr1.enabled=true
doevents
loop
label1.text=somestring
tmr1.enabled=true
loop

sub tmr1_tick
tmr1.enabled=false
end sub

The cpu intensive stuff appears to affect when the timer expires. Should

I be looking at the date/time functions to look for absolute rather than

relative times? If so, any pointers to help me?


Steve
 

agraham

Expert
Licensed User
Longtime User
You don't need to disable and re-enable the timer, this is interrupting the regular "beat" of the timer and adding the cpu internsive time to each timer event. Just let the timer run and put the label updating line in the timer.

Am right in guessing that you haven't written for a message driven environment before? You should structure your program to avoid loop's like in your example, that just burns processor cycles and stops other things happening. In general code in such environments runs in response to some stimulus - in your case probably either user input or the timer. When not running code the operating system will ensure that your app is idle letting other programs use the CPU. In the case of B4PPC you set things up in AppStart, start the timer, and let your code "run off the end" of AppStart. As long as you have shown a form in AppStart your program will not end but will be sitting idle ready to handle any messages.

Without knowing the details of your app my guess is that your program would be better sticking everything in the timer sub as below with the user interface setting global variables that the cpu intensive stuff monitors to decide what to do

B4X:
Sub Globals
  ' variables to control the timer code
End Sub

Sub AppStart
  Form1.Show
  tmr1.enabled = true
End Sub

Sub tmr1_tick
  label1.text=somestring ' do this early to get constant update times
  cpu intensive stuff ' takes a variable time to run
End Sub

Sub SomeControl_Events
  ' twiddle the global variables as necessary
End Sub
 
Last edited:

stevefan

Member
Licensed User
Longtime User
Thanks

Thanks for your suggestions, you are right I learned programming in the 70's-80's and have been picking it up again as a hobby. I used pocketC for a couple of years then renewed my interest when I discovered basic4ppc. You have put me back on the right track.

My app is a game. It is a series of soccer matches. The matches are divided into 90 minutes (not really minutes, actually about 50ms), with a minute counter displayed. At random minutes, the minute counter stops and an "incident" is played. An "incident" consists of a series of actions eg

Hunt wins possession
Sends in a cross
Doyle powers a header
Just over the bar

The incident is displayed using labels and a sound "ooh" "aah" is played at the same time. The above commentary appears line by line with a half second or so delay between each line. The heavy processing is generating each line, working out what is going to happen next, doing string substitution to randomize some of the words etc. The user can press a button to interrupt the play to change tactics and substitute players. I stop the minute timer while they do this.

Code similar to...

App_Start
minute=0
tmrminute.interval=50
tmrMinute.tick
end sub

Sub tmrMinute_tick

tmrMinute.enabled=false 'stop the timer while we play an incident
labelminute.text=minute
if minute=90 then
'match over, update league tables etc
else if <user pressed tactics button during incident> then
'deal with user interaction, substitutions and so on
else if rnd(0,10)=0 then 'in other words not every minute has an incident
playincident 'at the end of the incident I increment the minute variable and start the timer again
else
minute=minute+1 'for display
tmrMinute.enabled=true
end if

end sub

Now I will work on restructuring the playincident along the line you suggest.

Steve

Sorry for the bad formatting, didnt quite come out as intended
 
Last edited:
Top