Results 1 to 14 of 14

Thread: High Precision Timer

Threaded View

  1. #1

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,375

    High Precision Timer

    Below is a high precision timer that uses the QueryPerformance API's. I tried to structure it just like a normal timer would be so that it makes it easier to use.

    My might you want to use this timer over normal timer? Well, in my case I needed a game loop that will be consistently executed. With the normal timer, any intervals around 15 - 20 milliseconds are no longer accurate and for a game loop you want an interval of 16.6 milliseconds(60 FPS).

    Here is the code:
    Code:
    Option Strict On
    Option Explicit On
    <System.ComponentModel.DefaultEvent("Tick")> _
    Public Class PrecisionTimer
        Inherits System.ComponentModel.Component
    
        Private frequency As Long
        Private waitThread As Threading.Thread
    
    #Region "Api"
    
        Private Declare Function QueryPerformanceCounter Lib "kernel32" (ByRef lpPerformanceCount As Long) As Integer
        Private Declare Function QueryPerformanceFrequency Lib "kernel32" (ByRef lpFrequency As Long) As Integer
    
    #End Region
    
    #Region "Events"
    
        Public Event Tick(ByVal sender As Object, ByVal e As EventArgs)
    
    #End Region
    
    #Region "Methods"
    
        Private Sub CheckCompatibility()
            Dim test As Long
            If Not CBool(QueryPerformanceCounter(test)) Then
                Throw New Exception("High-resolution counter is not supported for this computer.")
            End If
        End Sub
    
        Public Sub Start()
            Me.Enabled = True
            waitThread = New Threading.Thread(AddressOf Wait)
            waitThread.IsBackground = True
            waitThread.Start()
        End Sub
    
        Public Sub [Stop]()
            Me.Enabled = False
        End Sub
    
        Private Sub Wait()
            Dim counter1, counter2 As Long
            QueryPerformanceCounter(counter1)
    
            If Me.LowerCpuUsage Then
    
                Do
                    QueryPerformanceCounter(counter2)
                    Threading.Thread.Sleep(2)
                Loop Until (counter2 - counter1) / (frequency / 1000) >= Me.Interval
    
            Else
    
                Do
                    QueryPerformanceCounter(counter2)
                Loop Until (counter2 - counter1) / (frequency / 1000) >= Me.Interval
    
            End If
    
            Console.WriteLine((counter2 - counter1) / (frequency / 1000))
    
            RaiseEvent Tick(Me, EventArgs.Empty)
    
            If Me.AutoReset Then
                Me.Enabled = False
            ElseIf Me.Enabled Then
                waitThread = New Threading.Thread(AddressOf Wait)
                waitThread.Start()
            End If
    
        End Sub
    
    #End Region
    
    #Region "New Constructor"
    
        Sub New()
            Call CheckCompatibility()
            QueryPerformanceFrequency(frequency)
            Me.Interval = 100
        End Sub
    
        Sub New(ByVal interval As Double)
            Call CheckCompatibility()
            QueryPerformanceFrequency(frequency)
            Me.Interval = interval
        End Sub
    
    #End Region
    
    #Region "Properties"
    
        Public Property AutoReset As Boolean
        Private pEnabled As Boolean
        Public Property Enabled() As Boolean
            Get
                Return pEnabled
            End Get
            Set(ByVal value As Boolean)
                If pEnabled <> value Then
                    pEnabled = value
                    If pEnabled Then RaiseEvent Tick(Me, EventArgs.Empty)
                End If
            End Set
        End Property
        Public Property Interval As Double
        Public Property LowerCpuUsage As Boolean
    
    #End Region
    
    End Class
    I'd like to thank Jacob Roman for introducing me to the QueryPerformance API's.
    Last edited by dday9; Jul 11th, 2014 at 05:18 PM.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width