Kovacic

Simple Time comparison debug issue

4 posts in this topic

I am working on a larger script that will use some of the functions in the script below. In theory, it should work like a dream... but it isn't. 

 

run this, and what should happen is you get a label showing when the count started, along with a simple label that shows how long the count has been running, however after 60 seconds, the count just goes back to zero seconds and the minutes don't increment. I know I'm missing the obvious but I think I'm too tired to see it.

 

If someone has a moment, give this a shot and let me know if you see where I messed up.. Let it run for over a minute to see what happens.

 

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>
$MuhGui = GUICreate("MuhTimer", 457, 182, 192, 124)
$Start = GUICtrlCreateButton("Start", 16, 128, 75, 25)
$Stop = GUICtrlCreateButton("Stop", 104, 128, 75, 25)
$Reset = GUICtrlCreateButton("Reset", 192, 128, 75, 25)
$timeStarted = GUICtrlCreateLabel("", 32, 16, 199, 17)
$elapsedTime = GUICtrlCreateLabel(" ", 16, 56, 199, 41)
Global $checkVar, $changedVar
GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
_TimerInit()
GUISetState(@SW_SHOW)
$mode = 0
While 1
    $checkVar = _TimerRunningDiff(0, $mode)
    If $checkVar <> $changedVar Then
        GUICtrlSetData($elapsedTime, _TimerRunningDiff(0, $mode))
        $changedVar = $checkVar
    EndIf
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Start
            $Junkval = _TimerStart()
            GUICtrlSetData($timeStarted, "Timer started: " & $Junkval)
        Case $Stop
            _TimerStop()
            $JunkVal2 = _TimerDiff(0, 3)
            GUICtrlSetData($elapsedTime, $JunkVal2)
        Case $Reset
            MsgBox(0, "Debug", _TimerRunningDiff(0, 3))
            ;$Junkval  = 0
            ;$Junkval2 = 0
            ;_TimerStop()
            ;GUICtrlSetData($elapsedTime, "")
            ;GUICtrlSetData($timeStarted, "")
    EndSwitch
WEnd
Func _TimerStart($TimerID = 0)
    $TimeStart[$TimerID] = _NowCalc()
    Return $TimeStart[$TimerID]
EndFunc   ;==>_TimerStart
Func _TimerStop($TimerID = 0)
    $TimeStop[$TimerID] = _NowCalc()
    Return _NowCalc()
EndFunc   ;==>_TimerStop
Func _TimerInit()
    Global $TimeStart[1000]
    Global $TimeStartMsecs[1000]
    Global $TimeStop[1000]
EndFunc   ;==>_TimerInit
Func _TimerDiff($TimerID = 0, $Style = 0)
    $Days = _DateDiff("D", $TimeStart[$TimerID], $TimeStop[$TimerID])
    $TimeStart[$TimerID] = _DateAdd("D", $Days, $TimeStart[$TimerID])
    $Hours = _DateDiff("h", $TimeStart[$TimerID], $TimeStop[$TimerID])
    $TimeStart[$TimerID] = _DateAdd("h", $Hours, $TimeStart[$TimerID])
    $Minutes = _DateDiff("n", $TimeStart[$TimerID], $TimeStop[$TimerID])
    $TimeStart[$TimerID] = _DateAdd("n", $Minutes, $TimeStart[$TimerID])
    $Seconds = _DateDiff("s", $TimeStart[$TimerID], $TimeStop[$TimerID])
    Switch $Style
        Case 0 ; one line
            Return "Days: " & $Days & " " & "Hours: " & $Hours & " " & "Minutes: " & $Minutes & " " & "Seconds: " & $Seconds
        Case 1 ; Array
            Local $Rezult = [$Days, $Hours, $Minutes, $Seconds]
            Return $Rezult
        Case 2 ; one line small
            Return $Days & " days, " & $Hours & ":" & $Minutes & ":" & $Seconds
        Case 3 ; one line description gors as time increases
            $time = ""
            If $Days <> 0 Then $time &= "Days: " & $Days & " "
            If $Hours <> 0 Then $time &= "Hours: " & $Hours & " "
            If $Minutes <> 0 Then $time &= "Minutes: " & $Minutes & " "
            If $Seconds <> 0 Then $time &= "Seconds: " & $Seconds & " "
            Return $time
    EndSwitch
EndFunc   ;==>_TimerDiff
Func _TimerRunningDiff($TimerID = 0, $Style = 0)
    $Days = _DateDiff("D", $TimeStart[$TimerID], _NowCalc())
    $TimeStart[$TimerID] = _DateAdd("D", $Days, $TimeStart[$TimerID])
    $Hours = _DateDiff("h", $TimeStart[$TimerID], _NowCalc())
    $TimeStart[$TimerID] = _DateAdd("h", $Hours, $TimeStart[$TimerID])
    $Minutes = _DateDiff("n", $TimeStart[$TimerID], _NowCalc())
    $TimeStart[$TimerID] = _DateAdd("n", $Minutes, $TimeStart[$TimerID])
    $Seconds = _DateDiff("s", $TimeStart[$TimerID], _NowCalc())
    Switch $Style
        Case 0 ; one line
            Return "Days: " & $Days & " " & "Hours: " & $Hours & " " & "Minutes: " & $Minutes & " " & "Seconds: " & $Seconds
        Case 1 ; Array
            Local $Rezult = [$Days, $Hours, $Minutes, $Seconds]
            Return $Rezult
        Case 2 ; one line small
            Return $Days & " days, " & $Hours & ":" & $Minutes & ":" & $Seconds
        Case 3 ; one line description gors as time increases
            $time = ""
            If $Days <> 0 Then $time &= "Days: " & $Days & " "
            If $Hours <> 0 Then $time &= "Hours: " & $Hours & " "
            If $Minutes <> 0 Then $time &= "Minutes: " & $Minutes & " "
            If $Seconds <> 0 Then $time &= "Seconds: " & $Seconds & " "
            Return $time
    EndSwitch
EndFunc   ;==>_TimerRunningDiff

 Thanks in advance!!


C0d3 is P0etry( ͡° ͜ʖ ͡°)

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Commenting out  lines 83,85,87 seems to do the trick (the ones where reset $TimeStart[$TimerID] new).

Some additional thoughts:

  • Declaring global variables in a local scope (_TimerInit) is a terrible thing to do.
  • If you got lines of code that only get called a single time in the entire script it's usually not necessairy to pack them into their own function, unless you're really forced to do so.
  • _TimerDiff and _TimerRunningDiff seem to be almost the same, maybe merge that into one function
  • Using While loops without any Sleep in it can use up one CPU core up to 100%. A Sleep(50) is already enough to prevent this.
Edited by Radiance

Share this post


Link to post
Share on other sites
4 hours ago, Radiance said:

Commenting out  lines 83,85,87 seems to do the trick (the ones where reset $TimeStart[$TimerID] new).

Some additional thoughts:

  • Declaring global variables in a local scope (_TimerInit) is a terrible thing to do.
  • If you got lines of code that only get called a single time in the entire script it's usually not necessairy to pack them into their own function, unless you're really forced to do so.
  • _TimerDiff and _TimerRunningDiff seem to be almost the same, maybe merge that into one function
  • Using While loops without any Sleep in it can use up one CPU core up to 100%. A Sleep(50) is already enough to prevent this.

 

Declaring globals inside a func is not something I normally do.. I would chalk this up to a point of weakness for me haha.

Commenting those lines out did work, but the seconds seem to keep counting, which is no worry, I just have to get creative with that part.

the reason for so many functions like that is, I plan on making them transferable to other scripts easily. Might not be the most efficient, but I never really learned to code, just picked it up as I went along. I'll learn one day, haha.

_TimerDiff and _TimerRunningDiff were initially supposed to be used separate, one while the clock was running, and one while its not. I'm seeing now that I'm not super tired that they really can just be merged into one.

I will look into that sleep idea. the only reason I have been avoiding them is on a rare occasion, people hit that button on a sleep cycle and it seems to not do anything. In a perfect world, I would be using OnEvent tricks. I cant find a good example, but its when you declare a button, then right after it, you have an 'OnClick' type call that will cause the gui to keep an eye out for that click.

 

I will play with this and try to make that work.. thanks!!

 

1 person likes this

C0d3 is P0etry( ͡° ͜ʖ ͡°)

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

kovacic,

This may give you some ideas for alternatives.  Proof of concept only...

#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <array.au3>

#AutoIt3Wrapper_Add_Constants=n

Local Enum $iCtlLbl1, $iTimer, $iDays, $iHours, $iMinutes, $iSeconds, $iCtlBtnStart, $iCtlBtnStop, $iCtlBtnPause, $iEnd
Local $aControlArray[1][$iEnd]

Local $hGui = GUICreate('Timer Demo')
GUISetStyle(-1, $WS_EX_COMPOSITED, $hGui)

For $i = 0 To 12
    GUICtrlCreateLabel('Timer #' & $i + 1, 10, $i * 30 + 10, 50, 20, BitOR($SS_CENTER, $SS_CENTERIMAGE))
    $aControlArray[$i][$iCtlLbl1] = GUICtrlCreateLabel('', 60, $i * 30 + 10, 200, 20, $SS_SUNKEN)
    ReDim $aControlArray[UBound($aControlArray) + 1][$iEnd]
Next
For $i = 0 To 12
    $aControlArray[$i][$iCtlBtnStart] = GUICtrlCreateButton('Start', 270, $i * 30 + 11, 35, 15)
    GUICtrlSetFont(-1, 7, 800)
    GUICtrlSetBkColor(-1, 0x00ff00)
Next
For $i = 0 To 12
    $aControlArray[$i][$iCtlBtnStop] = GUICtrlCreateButton('Stop', 310, $i * 30 + 11, 35, 15)
    GUICtrlSetFont(-1, 7, 800)
    GUICtrlSetBkColor(-1, 0xff0000)
Next

GUISetState()

AdlibRegister('_UpdateTimers', 500)

Local $iMsg

While 1

    $iMsg = GUIGetMsg()

    Switch $iMsg
        Case $gui_event_close
            Exit
        Case $aControlArray[0][$iCtlBtnStart] To $aControlArray[UBound($aControlArray) - 2][$iCtlBtnStart]
            For $i = 0 To UBound($aControlArray) - 1
                If $aControlArray[$i][$iCtlBtnStart] = $iMsg Then
                    _StartTimer($i)
                    ExitLoop
                EndIf
            Next
        Case $aControlArray[0][$iCtlBtnStop] To $aControlArray[UBound($aControlArray) - 2][$iCtlBtnStop]
            For $i = 0 To UBound($aControlArray) - 1
                If $aControlArray[$i][$iCtlBtnStop] = $iMsg Then
                    _StopTimers($i)
                    ExitLoop
                EndIf
            Next
    EndSwitch

WEnd

Func _StartTimer($idx)
    $aControlArray[$idx][$iTimer] = TimerInit()
    _UpdateTimers()
EndFunc   ;==>_StartTimer

Func _UpdateTimers()
    Local $aTime
    For $i = 0 To UBound($aControlArray) - 1
        If $aControlArray[$i][$iTimer] > 0 Then
            $aTime = _TicksToTimeEX($aControlArray[$i][$iTimer])
            $aControlArray[$i][$iDays] = $aTime[3]
            $aControlArray[$i][$iHours] = $aTime[2]
            $aControlArray[$i][$iMinutes] = $aTime[1]
            $aControlArray[$i][$iSeconds] = $aTime[0]
            GUICtrlSetData($aControlArray[$i][$iCtlLbl1], StringFormat('%02i : %02i : %02i : %02i ', $aTime[3], $aTime[2], $aTime[1], $aTime[0]))
        EndIf
    Next
EndFunc   ;==>_UpdateTimers

Func _StopTimers($idx)
    $aControlArray[$idx][$iTimer] = 0
EndFunc   ;==>_StopTimers

Func _TicksToTimeEX($Ticks)

    Local $diff = Int(TimerDiff($Ticks) / 1000)
    Local $aRET = [0, 0, 0, 0]

    $aRET[0] = Mod($diff, 60)
    $aRET[1] = Mod(Int($diff / 60), 60)
    $aRET[2] = Int($diff / 60 ^ 2)
    If $aRET[2] > 23 Then
        $aRET[3] = Floor($aRET[2] / 24)
        $aRET[2] -= $aRET[3] * 24
    EndIf

    Return $aRET

EndFunc   ;==>_TicksToTimeEX

kylomas

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now