|
|
|
Generic Timer
Added on 7/14/1999
|
A single object lets you create and query as many independent timers as you"d like. Each can be either in seconds or ticks.
When you create a new, individual timer it returns an integer. That integer is used by you from then on to access that timer within the object. Each function is commented.
--------------------------------------------
--Kraig Mentor
--v1.0 15 May 1999
--v1.1 18 June 1999
----Added comments.
----Added integer checking for 'aDuration' in the function 'gTimer_start'.
----Rewrote the functions to return either 1 or 0 where appropriate.
---- rather than symbolic error codes.
----Added error codes and the 'gTimer_getErrorString' function.
--------------------------------------------
--Copyright 1999, Kraig Mentor
--All rights reserved.
--Permission granted to use and distribute.
--------------------------------------------
property pTimerList --Contains all timer IDs and their information.
property pNextIDval --The timer ID of the last assign ID. 0 indicates no timers.
property pLastError --Symbol containing a code of the last error, if any.
--------------------------------------------
on new me
pTimerList = [:]
pNextIDval = 0
pLastError = #ok
return(me)
end on
--PUBLIC METHODS--
--tTimerVals are....[{ID as integer}:[#method:#{ticks,#seconds}, ¬
-- #start:{integer}, #stop:{integer}, ¬
-- #state:{0,1,2}]]
--#state = 0 indicates the time is not running (Not started)
--#state = 1 indicates the timer is running.
--#aState =2 indicates the timer has expired (Finished timing)
--------------------------------------------
on gTimer_createID me
--ACCEPTS: Nothing.
--RETURNS: A positve integer ID value.
--PURPOSE: Creates a unique id for each timer.
-- They are generate sequentially as integers.
pLastError = #ok
pNextIDval = pNextIDval + 1
pTimerList.addProp(pNextIDval,[#method:void, #start:void, #stop:void, #state:0])
return(pNextIDVal)
end on
--------------------------------------------
on gTimer_killID me, aID
--ACCEPTS: 'aID' as an integer. Must be non-negative.
--RETURNS: 1 if successful, 0 otherwise.
--PURPOSE: Removes a timer from the list.
--Make sure the ID is legit.
if NOT(voidP(pTimerList.getAProp(aID))) then
pTimerList.deleteProp(aID)
pLastError = #ok
return(1)
else
pLastError = #invalidTimerID
return(0)
end if
end on
--------------------------------------------
on gTimer_getTimeRemaining me, aID
--ACCEPTS: 'aID' as an integer. Must be non-negative.
--RETURNS: An integer that represents the ticks, or the milliSeconds
-- remaininging a timer if successful, 0 otherwise.
--PURPOSE: Determine the remaining time of a timer.
if NOT(voidP(pTimerList.getAProp(aID))) then
--The timer ID was located.
tTimerVals = pTimerList.getAProp(aID)
if tTimerVals.getProp(#method) = #ticks then
tRemainingTime = gTimer_getTicksRemaining(me, aID)
else
tRemainingTime = gTimer_getSecondsRemaining(me, aID)
end if
pLastError = #ok
return(tRemainingTime)
else
--The timer ID was not located.
pLastError = #invalidTimerID
return(0)
end if
end on
--------------------------------------------
on gTimer_start me, aID, aMethod, aDuration
--ACCEPTS: 'aID' as an integer. Must be non-negative.
--ACCEPTS: 'aMethod' as a sybmol. Must be either #ticks or #seconds.
-- This is the timer counting method to use.
--ACCEPTS: 'aDuration' as an integer indicating either the ticks or seconds.
--RETURNS: 1 if successful, 0 otherwise.
--PURPOSE: Start a timer.
--Make sure the duration is an integer
if NOT(integerP(aDuration)) then
pLastError = #integerExpected
return(0)
end if
--Make sure this is a valid method.
if aMethod = #ticks then
tStartStopVals = gTimer_convertTicks(me, aDuration)
else if aMethod = #seconds then
tStartStopVals = gTimer_convertSeconds(me, aDuration)
else
--Invalid method.
pLastError = #invalidMethod
return(0)
end if
if NOT(voidP(pTimerList.getAProp(aID))) then
--This is a valid timer ID.
tTimerVals = pTimerList.getProp(aID)
tTimerVals.setProp(#method, aMethod)
tTimerVals.setProp(#state, 1)
tTimerVals.setProp(#start, tStartStopVals.getProp(#start))
tTimerVals.setProp(#stop, tStartStopVals.getProp(#stop))
else
--This is not a valid timer ID.
pLastError = #invalidTimerID
return(0)
end if
end on
-------------------------------------------
on gTimer_getErrorString me, aCode
--ACCEPTS: 'aCode' as symbol. It should reference a reported error code
-- from a prior call to a handler.
--RETURNS: A text string describing the meaning of the error code.
--PURPOSE: To offer more insight into an error code's meaning.
case aCode of
#ok:
tString = "The request was completed with no apparent errors."
#integerExpected:
tString = "An integer was expected."
#invalidTimerID:
tString = "The requested timer ID was not found."
#invalidMethod:
tString = "Invalid timer method. Expected either #ticks or #seconds."
otherwise
tString = "The requested error string could not be found."
end case
return(tString)
end on
---------------------------------------------
--PRIVATE------------------------------------
---------------------------------------------
on gTimer_getTicksRemaining me, aID
--ACCEPTS: 'aID' as an integer. Must be non-negative.
--RETURNS: An integer that represents the ticks remainining.
-- Assumes that the validity of 'aID' has already been established.
--PURPOSE: Determine the remaining ticks of a timer.
gTimer_timeExpired(me, aID)
tTimerVals = pTimerList.getAProp(aID)
if tTimerVals.getProp(#state) = 2 then
tDiff = 0
else
tDiff = ABS(tTimerVals.getProp(#stop) - the ticks)
end if
return(tDiff)
end on
---------------------------------------------
on gTimer_getSecondsRemaining me, aID
--ACCEPTS: 'aID' as an integer. Must be non-negative.
--RETURNS: An integer that represents the milliSeconds remainining.
-- Assumes that the validity of 'aID' has already been established.
--PURPOSE: Determine the remaining ticks of a timer.
gTimer_timeExpired(me, aID)
tTimerVals = pTimerList.getAProp(aID)
if tTimerVals.getProp(#state) = 2 then
tDiff = 0
else
tDiff = ABS(tTimerVals.getProp(#stop) - the milliSeconds)
end if
return(tDiff)
end on
--------------------------------------------
on gTimer_timeExpired me, aID
--ACCEPTS: 'aID' as an integer. Must be non-negative.
-- Assumes the validity of 'aID' has already been verified.
--RETURNS: 1 if the timer has expired, 0 otherwise.
--PURPOSE: Determine if a timer has expired.
tTimerVals = pTimerList.getProp(aID)
if tTimerVals.getProp(#state) then
--The timer has been started (may be finished)
if tTimerVals.getProp(#method) = #ticks then
gTimer_checkTicks(me, aID)
else
gTimer_checkSeconds(me, aID)
end if
if tTimerVals.getProp(#state) = 2 then
--Timer expired
return(1)
else
--Timer still running
return(0)
end if
end if
end on
--------------------------------------------
on gTimer_checkTicks me, aID
--ACCEPTS: 'aID' as an integer. Must be non-negative.
-- Assumes the validity of 'aID' has already been verified.
--RETURNS: Nothing
--PURPOSE: Updates the #state property of a #ticks timer when it has expired.
tTimerVals = pTimerList.getProp(aID)
if the ticks > tTimerVals.getProp(#stop) then
tTimerVals.setProp(#state,2)
end if
end on
--------------------------------------------
on gTimer_checkSeconds me, aID
--ACCEPTS: 'aID' as an integer. Must be non-negative.
-- Assumes the validity of 'aID' has already been verified.
--RETURNS: Nothing
--PURPOSE: Updates the #state property of a #seconds timer when it has expired.
tTimerVals = pTimerList.getProp(aID)
if the milliSeconds > tTimerVals.getProp(#stop) then
tTimerVals.setProp(#state,2)
end if
end on
--------------------------------------------
on gTimer_convertTicks me, aDuration
--ACCEPTS: 'aDuration' as a positive integer.
-- Assumes the validity of 'aDuration' has already been verified.
--RETURNS: A property list containing the starting and stopping times.
return([#start:the ticks, #stop: the ticks + aDuration])
end on
--------------------------------------------
on gTimer_convertSeconds me, aDuration
--ACCEPTS: 'aDuration' as a positive integer.
-- Assumes the validity of 'aDuration' has already been verified.
--RETURNS: A property list containing the starting and stopping times.
tDuration = aDuration * 1000
return([#method:#seconds, #start:the milliSeconds, #stop:the milliSeconds + tDuration])
end on
|
|