animeaime
Joined: 04 Nov 2008 Posts: 1045
|
Posted: Sat Apr 11, 2009 5:50 pm Post subject: [Func] ETA - Estimated time of arrival |
|
|
Functions: ETA and helper functions
Description
- ETA returns a formatted time for the estimated finish time of a loop, file download, etc.
- Supports tracking multiple ETAs simultaneously
- Supports pausing (and resuming) an ETA timer
Download
ETA.zip
Requirements
None
Functions
ETA_Start(ByRef PreviousTime, ByRef TimeTaken, ByRef TimerIndex = 0)
Initializes values to be used by ETA.
Parameters
PreviousTime - variable to store the previous time (the "Timer" variable)
TimeTaken - variable to store how long the timer has been running so far
TimerIndex - variable to store the timer index (initializes it to 0)
ETA(CurrentValue, TotalValue, ByRef PreviousTime, ByRef TimeTaken)
Returns the estimated finish time given the specified current value, total value, previous time, and time taken; updates PreviousTime and TimeTaken accordingly.
ReturnValue
A formatted string represing the estimated finish time.
Format
If ETA is less than a minute:
0:ss
If ETA is less than an hour (but more than a minute):
m:ss
Else:
h:mm:ss
Remarks
CurrentValue and TotalValue must be positive numbers - either can be a decimal.
Supports percentages by specifing 100 for TotalValue and the percentage for CurrentValue.
Can be used to show the ETA for a file download. Specify the file size (in bytes) for TotalValue and the size (in bytes) already downloaded for CurrentValue.
ETA_Stop(ByRef PreviousTime, ByRef TimeTaken)
1) Stops the specified timer
2) Updates TimeTaken (if the timer was previously running, and not paused)
3) Sets PreviousTime to -2, to signify the timer is stopped (see example 2 below, for use)
4) Returns TimeTaken (in seconds)
Note: Although this function is not required to be called, it can be used to store the time taken (in seconds) for the timer into a variable. Additionally, this function sets PreviousTime to -2, to signify the timer is stopped - this allows an easy check to see if the timer is stopped (see example 2 below).
Note: Do not call this function if you intend to start the timer back up - instead, call ETA_Pause.
ETA_Pause(ByRef PreviousTime, ByRef TimeTaken)
1) Pauses the specified timer. Does nothing if the timer was already paused (or stopped).
2) Updates TimeTaken
3) Sets PreviousTime to -1, to signify the timer is paused (see example 2 below, for use)
ETA_Resume(ByRef PreviousTime)
Resumes the specified Timer. Does nothing if the timer wasn't paused.
Code
| Code: | ;for all functions, PreviousTime is the "timer" - the previous time is stored
/*
calculates ETA
(supports "pausing")
returns the formatted ETA
*/
ETA(CurrentValue, TotalValue, ByRef PreviousTime, ByRef TimeTaken)
{
/*
values MUST start at 0 and have a constant step
(CurrentValue or TotalValue can be a decimal value)
e.g.
A_Index (in a loop),
percentages (TotalValue = 100),
file download (use bytes for values),
etc.
*/
/*
Derivation of formula
ETA = TimeRequired - TimeTaken
TimeTaken / CurrentValue = TimeRequired / TotalValue
TimeRequired = TimeTaken / CurrentValue * TotalValue
TimeRequired - TimeTaken = TimeTaken / CurrentValue * TotalValue - TimeTaken
ETA = TimeTaken * (TotalValue / CurrentValue - 1)
*/
if (PreviousTime >= 0)
{
;timer is not "paused" and not stopped
TimeTaken += A_TickCount - PreviousTime
PreviousTime := A_TickCount
}
;divide by 1000 to convert from milliseconds to seconds
ETA := round(TimeTaken * (TotalValue - CurrentValue) / CurrentValue / 1000)
;ETA is less than a minute
if (ETA < 60)
return "0:" . (ETA < 10 ? "0" : "") . ETA
seconds := mod(ETA, 60)
ETA //= 60
;ETA is less than an hour
if (ETA < 60)
return ETA ":" . (seconds < 10 ? "0" : "") . seconds
minutes := mod(ETA, 60)
ETA //= 60
;else, ETA is greater than an hour
return ETA ":" . (minutes < 10 ? "0" : "") . minutes
. ":" . (seconds < 10 ? "0" : "") . seconds
}
;initializes a Timer
;pass variables to use for each the
; previous time, time taken, and timer index (optional)
ETA_Start(ByRef PreviousTime, ByRef TimeTaken, ByRef TimerIndex = 0)
{
PreviousTime := A_TickCount
TimeTaken := 0
TimerIndex := 0
}
;"stops" an ETA timer
;(use ETA_Pause if you plan to continue the timer later)
;updates TimeTaken, and returns this value (in seconds)
;sets PreviousTime to -2, to signify the time is done
ETA_Stop(ByRef PreviousTime, ByRef TimeTaken)
{
;only if timer is "ticking"
if (PreviousTime >= 0)
TimeTaken += A_TickCount - PreviousTime
PreviousTime := -2
return round(TimeTaken / 1000)
}
;"pauses" an ETA timer
ETA_Pause(ByRef PreviousTime, ByRef TimeTaken)
{
;already paused (or stopped)
if (PreviousTime < 0)
return
TimeTaken += A_TickCount - PreviousTime
PreviousTime := -1
}
;"resumes" a "paused" ETA timer
ETA_Resume(ByRef PreviousTime)
{
;you don't need to pass TimeTaken, because the time taken doesn't increase
;(since the timer was paused)
;wasn't paused
if (PreviousTime != -1)
return
PreviousTime := A_TickCount
} |
Example 1
| Code: | #SingleInstance Force
#NoEnv
;initialize an ETA timer
ETA_Start(Timer1, Timer1Time)
;loops for about 15 seconds
LoopCount := 150
Loop, %LoopCount%
{
Sleep, 100
ToolTip, % ETA(A_Index, LoopCount, Timer1, Timer1Time)
} |
Example 2
| Code: | #SingleInstance Force
#NoEnv
;each loop loops for about 5 seconds (4 loops = 20 seconds)
LoopCount := 50
;initialize an ETA timer
ETA_Start(Timer1, Timer1Time, Index1)
;Store the total count
TotalValue1 := 4 * LoopCount
;initialize an ETA timer
ETA_Start(Timer2, Timer2Time, Index2)
;Store the total count
TotalValue2 := 2 * LoopCount
Loop, %LoopCount%
{
Sleep, 100
;store pause state
isPaused1 := (Timer1 = -1) ? " (Paused)" : ""
isPaused2 := (Timer2 = -1) ? " (Paused)" : ""
;stores done state
isDone1 := (Timer1 = -2) ? " (Done)" : ""
isDone2 := (Timer2 = -2) ? " (Done)" : ""
;increase indexes
Index1++
Index2++
ToolTip, % "Loop #1`n`n"
. "Timer1: " ETA(Index1, TotalValue1, Timer1, Timer1Time) . "`n"
. isDone1 . isPaused1
. "Timer2: " ETA(Index2, TotalValue2, Timer2, Timer2Time)
. isDone2 . isPaused2
}
;pause Timer2
ETA_Pause(Timer2, Timer2Time)
Loop, %LoopCount%
{
Sleep, 100
;store pause state
isPaused1 := (Timer1 = -1) ? " (Paused)" : ""
isPaused2 := (Timer2 = -1) ? " (Paused)" : ""
;stores done state
isDone1 := (Timer1 = -2) ? " (Done)" : ""
isDone2 := (Timer2 = -2) ? " (Done)" : ""
;increase indexes
Index1++
;don't increase Index2 (Timer2 is paused)
ToolTip, % "Loop #2`n`n"
. "Timer1: " ETA(Index1, TotalValue1, Timer1, Timer1Time) . "`n"
. isDone1 . isPaused1
. "Timer2: " ETA(Index2, TotalValue2, Timer2, Timer2Time)
. isDone2 . isPaused2
}
;resume Timer2
ETA_Resume(Timer2)
Loop, %LoopCount%
{
Sleep, 100
;store pause state
isPaused1 := (Timer1 = -1) ? " (Paused)" : ""
isPaused2 := (Timer2 = -1) ? " (Paused)" : ""
;stores done state
isDone1 := (Timer1 = -2) ? " (Done)" : ""
isDone2 := (Timer2 = -2) ? " (Done)" : ""
;increase indexes
Index1++
Index2++
ToolTip, % "Loop #3`n`n"
. "Timer1: " ETA(Index1, TotalValue1, Timer1, Timer1Time) . "`n"
. isDone1 . isPaused1
. "Timer2: " ETA(Index2, TotalValue2, Timer2, Timer2Time)
. isDone2 . isPaused2
}
/*
Timer2 is done
calling ETA_Stop is not required;
it can be used to store the "total time required" into a variable.
*/
TotalTime2 := ETA_Stop(Timer2, Timer2Time)
Loop, %LoopCount%
{
Sleep, 100
;store pause state
isPaused1 := (Timer1 = -1) ? " (Paused)" : ""
isPaused2 := (Timer2 = -1) ? " (Paused)" : ""
;stores done state
isDone1 := (Timer1 = -2) ? " (Done)" : ""
isDone2 := (Timer2 = -2) ? " (Done)" : ""
;increase indexes
Index1++
;don't increase Index2 (Timer2 is already finished)
ToolTip, % "Loop #4`n`n"
. "Timer1: " ETA(Index1, TotalValue1, Timer1, Timer1Time) . "`n"
. isDone1 . isPaused1
. "Timer2: " ETA(Index2, TotalValue2, Timer2, Timer2Time)
. isDone2 . isPaused2
}
;Timer1 is done
TotalTime1 := ETA_Stop(Timer1, Timer1Time)
ToolTip
MsgBox, % "Timer1 took " TotalTime1 " seconds.`n"
. "Timer2 took " TotalTime2 " seconds." |
How to use
Extract the zip's contents to a library folder for automatic inclusion - StdLib compliant.
A copy of the above examples can be found in the "Func Examples" folder.
Download ETA function _________________ As always, if you have any further questions, don't hesitate to ask.
Add OOP to your scripts via the Class Library. Check out my scripts. |
|