Newbie - Timers and Send an example
Stephen King
st.king42 at ntlworld.com
Wed Dec 10 14:16:52 EST 2003
Erik,
I have put together a very simple stack to show the differences between 3
methods to give as an example. if you want the stack, just email me off
list. Note that the differences in timing show best when another process is
running in background (I used a render package to get reasonable errors- but
I do have a 3GHz machine). The stack is not elegant as its just to show
different approaches - also I haven't really got used to the usual naming
convention yet!
# There are two Buttons sending TimerStart and TimerStop
#Fields are
#Send (message) This fld gives timer output based on SEND only
#Adjusted This fld gives timer output based on Send with time adjusted
dynamically
#System This field gives time with SEND acting as an interrupt to get
current system time
#Timer (clock) This field shows Elapsed time between Start and Stop from
System clock
#SendTime This fld shows how the dynamic adjustment behaves
#StopTimer This fld is a value used to finish timing loops if STOP not
pressed.
Global TimerStart
Global TimerlastAdjusted # Time at last SEND message for adjusted loop
Global AdjustOffset #SEND time for adjusted loop
Global StopRequest
On TimerStart
Put "0" into fld "Clock" # clear flds
Put "0" into fld "Send"
Put "0" into fld "Adjusted"
Put "0" into fld "System"
Put 30 into AdjustOffset # first SEND is after 30mS so this is the time
expected by adjust loop
Put false into StopRequest
put the milliseconds into TimerStart # record start time
put TimerStart into TimerlastAdjusted #Establish reference time for
adjust loop
put TimerStart + fld "StopTime" * 1000 into StopTimer # define Stop time
in terms of system milliseconds
SendLoop # Start loop using SEND only
send "AdjustedLoop" to card "Timer" in AdjustOffset milliSeconds # Start
Loop adjusting time dynamically
send "SystemLoop" to card "Timer" in 60 milliSeconds # Start Loop using
system time
# Offset Start times to make sure that the processes do not clash.
# Do something to occupy the program a bit until Stop time elapses
repeat until the milliseconds > StopTimer
wait for 2 milliseconds with messages
LoadingLoop
end repeat
TimerStop
end TimerStart
On TimerStop # If stop button pressed
put true into StopRequest
put (the milliseconds - TimerStart)/1000 into field "Clock"
end TimerStop
On SendLoop # this timer simply uses SEND message to increment field
if StopRequest <> true then Send "SendLoop" to me in 100milliseconds #
SEND message again
put 0.1 + fld "Send" into field "send"
end SendLoop
On AdjustedLoop
put the milliseconds into TimeNow
#determine actual elapsed time and compare with 100mS
Put (TimeNow - TimerLastAdjusted) into ElapsedTime
put ElapsedTime into fld "SendTime" # Just display how the SEND time is
being adjusted
if StopRequest <> true then Send "AdjustedLoop" to me in round(100*
(AdjustOffset/ElapsedTime)) milliseconds
# If time was different to AdjustOffset (expected time), then reduce or
increase it accordingly
# making sure it is still an integer. Note this is a very simple algorithmit
can be cleverer
Put 100 into AdjustOffset # This is just to change the 30 from the first
run of this loop to the 100 expected
Put TimeNow into TimerlastAdjusted # Save this time as reference for
next
Put 0.1 + field "Adjusted" into Field "Adjusted" # Update the fld with
the target loop time
end AdjustedLoop
On SystemLoop
put the milliseconds into TimeNow
if StopRequest <> true then Send "SystemLoop" to me in 100 milliSeconds
Put (TimeNow-TimerStart)/1000 into fld "System" # simply read system
time, take away start and this is the current time
end SystemLoop
On LoadingLoop # this is to add a bit of load. best done by running more
processes in background.
repeat 5000 times
put 1 into n
end repeat
end LoadingLoop
You should find that with minimal processes and a fast machine, all are
probably within 0.5% of each other. The adjusted timing fld SendTime hovers
around 98-102. Running background process then the straight SEND lags most
behind (in my tests upto 5 seconds in a minute) and the adjusted keeps
pretty well on track but the timing adjustment varies considerably from
80-120 as it continually tries to adjust the variation in SEND. The system
timer always tracks (by definition).
An important note is what happens if the user moves the window! while the
mouse is pressed on the window top border, the app stops (anyone know how to
stop this?). The Raw SEND approach just loses time (no messages sent). The
Adjusted approach goes AWOL for quite a while as it finds there has been a
massive delay in one loop and reduces the next dramatically then finds the
following was too short. This oscillates and may or may not settle down. The
SEND reading system time simply catches up.
Hope this hasn't been too long winded and is helpful.
Cheers
Steve
More information about the use-livecode
mailing list