Code archives/Miscellaneous/Duration Timers
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
These fubnctions present an alternative to the 'Timer' function of B3D. I think it may be a little slower as it iterates through types, and I'm sure there are ways to optimise it much more thoroughly, however, the main advantages over the default timer functions are the abilities to monitor them and to set timers to repeat, and decide when they should begin and end etc. There is a hard limit of 15 timers allowed, this is due to the monitoring function which returns the reference number(s) as a bitwise value. This allows multiple active timers to be returned in the one function. Timers can be updated, started or deleted once set, or set to start in a number of milliseconds time, however, a currently active timer cannot be updated, only killed. There is also functionality to allow timers to repeat again, either instantly once finished, or with the same time difference before restarting. The code has been annotated in brief, but I'll work on a demo and add it in soon. | |||||
[code] Global Total_Timers=0 ;Limit of 15 Timers. Referenced by an integer 1 - 15. Type Timer Field Reference Field Start=0 Field Duration Field Active=False Field Repeat_On_End=False Field InstantRepeat=False Field RunCount=0 Field SetTime End Type Function KillTimer(Reference) ;Destroys Timer, even if Activve and removes any Run-count info. DeadTimer.Timer=GetTimerByRef.Timer(Reference) If (DeadTimer <> Null) Delete DeadTimer End If End Function Function UpdateTimers() Local Now=MilliSecs() For iterTimer.Timer = Each Timer If (iterTimer=Null) ; Safety Check Exit End If If ((Now-(iterTimer\Start+iterTimer\SetTime))>0) If (((iterTimer\Start+iterTimer\SetTime)+iterTimer\Duration)<Now) If (Not(iterTimer\Active)) iterTimer\Active=True iterTimer\RunCount=iterTimer\RunCount+1 End If Else If (iterTimer\Repeat_On_End) If (InstantRepeat) ; Note - Instant_Repeat will continue repeating indefinitely until KILLED or Repeat switched OFf. iterTimer\Start=0 iterTimer\RunCount=iterTimer\RunCount+1 Else iterTimer\Active=False End If iterTimer\SetTime=Now Else Delete iterTimer End If End If End If Next End Function Function RetrieveTimerBeginsIn(Reference) ; Returns the time left (in milliseconds) until timer 'Reference' becomes Active. If timer is already active, errors may occur (untested) Local CheckTimer.Timer=GetTimerByRef(Reference) Return (((CheckTimer\Start+CheckTimer\SetTime))-MilliSecs()) End Function Function RetrieveDurationRemaining(Reference) ; Returns the time left (in milliseconds) until timer 'Reference' finishes. If timer is not already active, errors may occur (untested). Local CheckTimer.Timer=GetTimerByRef(Reference) Return (((CheckTimer\SetTime+CheckTimer\Start+CheckTimer\Start+Duration))-MilliSecs()) End Function Function GetTimerByRef.Timer(Reference) For iterTimer.Timer = Each Timer If (iterTimer\Reference = Reference) Return iterTimer.Timer End If Next Return Null End Function Function GetActiveTimers(Specific=False) ; Accepts and Returns bitwise operators. ; This is the reason for the hard limit on number of Timers Local nReturn=0 For iterTimer.Timer = Each Timer If (iterTimer\Active) nReturn=nReturn+(2^iterTimer\Reference) End If Next If (Specific) nReturn=(nReturn And Specific) End If Return nReturn End Function Function QuickstarttAllTimers() ; Has no effect on currently active Timers. Local Now=MilliSecs() For iterTimer.Timer = Each Timer If (iterTimer.Timer <> Null) If (Not(iterTimer\Active)) iterTimer\SetTime=(MilliSecs()-(iterTimer\Start)) iterTimer\Active=True iterTimer\RunCount=iterTimer\RunCount+1 End If End If Next End Function Function StartTimerNow(Reference,Repeat_On_End=-1) ; RepeatOnEnd will override existing if set, even for Currently Active Timers. Duration is NOT affected. StartTimer.Timer=GetTimerByRef.Timer(Reference) If (StartTimer = Null) ; Invalid Reference Return Else If (StartTimer\Active) ; Already Running Else StartTimer\SetTime=(MilliSecs()-(StartTimer\Start)) StartTimer\Active=True If (Repeat_On_End>-1) StartTimer\Repeat_On_End=Repeat_On_End End If End If End If End Function Function NewDuration(Reference,Duration) ; This WILL affect currently active timers. DurationTimer.Timer=GetTimerByRef.Timer(Reference) If (DurationTimer.Timer = Null) ; Invalid Reference Return Else DurationTimer\Duration=Duration End If End Function Function StopTimerNow(Reference,Repeat_On_End=-1,InstantRepeat=-1) StopTimer.Timer=GetTimerByRef.Timer If (StopTimer = Null) ; Invalid Reference Return Else If (Repeat_On_End>-1) StopTimer\Repeat_On_End=Repeat_On_End End If If ((StopTimer\Repeat_On_End)) If ((InstantRepeat>-1)) StopTimer\InstantRepeat=InstantRepeat End If If (InstantRepeat) ;Note - Instant_Repeat will continue repeating indefinitely until KILLED or Repeat switched OFf. ;The Duration is unaffected. Please use 'NewDuration' to change if required. Instant Repeat is perhaps ;best set to False for the purposes of this function, though the choice is still available. StopTimer\Start=0 StopTimer\SetTime=(MilliSecs()) StopTimer\RunCount=StopTimer\RunCount+1 Else StopTimer\Active=False StopTimer\SetTime=(MilliSecs()) End If Else Delete StopTimer End If End If End Function Function EnsureRepeat(Reference,InstantRepeat=False,NewDelay=-1) ; Note - Instant_Repeat will continue repeating indefinitely until KILLED or Repeat switched OFf. ; The Duration is unaffected. Please use 'NewDuration' to change if required. ; If InstantRepeat has ever been used for this timer, NewDelay can be set to restore a delay between repetitions. RepeatTimer.Timer=GetTimerByRef.Timer If (RepeatTimer = Null) ; Invalid Reference Return Else RepeatTimer\Repeat_On_End=True RepeatTimer\InstantRepeat=InstantRepeat If (Not(InstantRepeat)) RepeatTimer\Start=NewDelay Else RepeatTimer\Start=0 End If End If End Function Function CancelRepeat(Reference) ; No Repeat means timer will be destroyed once it has finished running. RepeatTimer.Timer=GetTimerByRef.Timer If (RepeatTimer = Null) ; Invalid Reference Return Else RepeatTimer\Repeat_On_End=False RepeatTimer\InstantRepeat=False End If End Function Function ResetRunCount(Reference) CountTimer.Timer=GetTimerByRef.Timer If (CountTimer = Null) ; Invalid Reference Return Else CountTimer\RunCount=0 End If End Function Function CountTimesRun(Reference) CountTimer.Timer=GetTimerByRef.Timer If (CountTimer = Null) ; Invalid Reference Return Else Return CountTimer\RunCount End If ; Just In Case (Safety Check) - This shouldn't occur ever Return-1 End Function Function AddTimer(Reference,Duration=1,StartNow=False,StartIn=0,Repeat_On_End=False,Instant_Repeat=False) ; It is up to the coder to keep track of reference numbers. using integers (or constants equivalent) 1 - 15 is advised. ; Reference: A uniqque reference number for the timer. ; Duration: How long the timer remains 'active' once started (in Milliseconds) ; Start Now: Set this Flag to True if you want to make the Timer Active immediately. If False, 'Start In' value will override. ; StartIn: Time in (Milliseconds) from the call of this function until the Timer becomes Active. ; Repeat_On_End: Set to True if you wish the timer to commence again once it has finished. (Also see 'InstantRepeat' below) ; InstantRepeat: If Repeat_On_End is set as True, this flag will cause the timer to re-commence as soon as it is finished. If False, 'Start_In' value will be used again. For iterTimer.Timer = Each Timer If iterTimer\Reference=Reference If (iterTimer=Null) ; Safety Check. Exit Else If iterTimer\Active=True ; Cannot amend an Active Timer. Return Else ; Timer in use. Amend Values insterad of making New. This method resets RunCount and Repeat info. Exit End If End If iterTimer.Timer = New Timer Total_Timers=Total_Timers+1 Exit End If Next If (iterTimer=Null) If (Total_Timers>15) ; Too Many Timers. Cannot Add New. Return Else iterTimer\Reference = Reference iterTimer\Repeat_On_End=Repeat_On_End iterTimer\Duration=Duration iterTimer\RunCount=0 iterTimer\SetTime=MilliSecs() If (StartNow) iterTimer\Start=0 iterTimer\Active=True iterTimer\RunCount=iterTimer\RunCount+1 Else iterTimer\Start=(Start_In) End If End If EndIf End Function [/code] |
Comments
None.
Code Archives Forum