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