Skip to main content
gamedev.net
🔒 Locked

A C# Timer

Started by jonnii Aug 29, 2003 at 7:50 PM 4 replies 900+ views
Original Post
jonnii
jonnii
Hay, I need to make a timer class for my little C# app, which will do a 101 things like profiling and keeping my animations smooth =) However i''m new to the language and i''m not sure if there''s something similar to the preformance counter! Could anyone help me out? thanks
-jonnii=========jon@voodooextreme.comwww.voodooextreme.com
alexmoura
alexmoura
Check the System.timers.Timer class it will probably do whatever you need.
Also, check the System.Diagnostics namespace - it has performance counters.

"I woke up sweating and clutching my pillow. Thankfully the powerful and reassuring visage of Optimus Prime staring back at me from my pillow case served to ease my frayed nerves. Like the giant robotic father I never had he always knows just what to say" - Gabe, Penny-Arcade

Alexandre Moura
jonnii
jonnii
thanks
-jonnii=========jon@voodooextreme.comwww.voodooextreme.com
Arild Fines
Arild Fines
If you need high precision, you pretty much need to P/Invoke QueryPerformanceCounter|Frequency. This is how I do it:


// $Id: Timer.cs 747 2003-06-07 16:43:22Z Arild $

using System;
using System.Runtime.InteropServices;

namespace Utils
{
/// <summary>

/// A high precision timer for performance measurement purposes.

/// </summary>

public class Timer
{
public Timer()
{
this.startTime = 0;
this.endTime = 0;

QueryPerformanceFrequency( out this.frequency );
}


public void Start()
{
QueryPerformanceCounter( out this.startTime );
}

public void End()
{
QueryPerformanceCounter( out this.endTime );
}

public double Interval
{
[System.Diagnostics.DebuggerStepThrough]
get{ return (double)(this.endTime-this.startTime)/(double)frequency; }
}


[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);

private long startTime;
private long endTime;
private long frequency;
}
}


--
AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.
[Project site] [Blog] [RSS] [Browse the source] [IRC channel]
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
jonnii
jonnii
thats what i figured... so i did that =)

C# really does make things so much easier...
-jonnii=========jon@voodooextreme.comwww.voodooextreme.com
unferth
unferth
For some variety, here is the timer class I am using. It's a slightly modified version of the Timer class that comes with the DirectX9 SDK. It uses QueryPerformanceCounter if supported, but falls back onto timeGetTime if not. It's quite a bit larger than Arild's version, but has a bit more functionality.


// ripped from microsoft

using System;
using System.IO;
using System.Runtime.InteropServices;


namespace project3.utils
{
/// <summary>

/// Enumeration for various actions our timer can perform

/// </summary>

public enum TimerAction
{
Reset,
Start,
Stop,
Advance,
GetAbsoluteTime,
GetApplicationTime,
GetElapsedTime
};

/// <summary>

/// Generic utility functions for our samples

/// </summary>

public class HPTimer
{
#region Timer Internal Stuff
[System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously

[DllImport("kernel32")]
private static extern bool QueryPerformanceFrequency(ref long PerformanceFrequency);
[System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously

[DllImport("kernel32")]
private static extern bool QueryPerformanceCounter(ref long PerformanceCount);
[System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously

[DllImport("winmm.dll")]
public static extern int timeGetTime();
private bool isTimerInitialized = false;
private bool m_bUsingQPF = false;
private bool m_bTimerStopped = true;
private long m_llQPFTicksPerSec = 0;
private long m_llStopTime = 0;
private long m_llLastElapsedTime = 0;
private long m_llBaseTime = 0;
private double m_fLastElapsedTime = 0.0;
private double m_fBaseTime = 0.0;
private double m_fStopTime = 0.0;
#endregion

public HPTimer() { /* Private Constructor not anymore*/ }

/// <summary>

/// Performs timer opertations. Use the following commands:

///

/// TimerAction.Reset - to reset the timer

/// TimerAction.Start - to start the timer

/// TimerAction.Stop - to stop (or pause) the timer

/// TimerAction.Advance - to advance the timer by 0.1 seconds

/// TimerAction.GetAbsoluteTime - to get the absolute system time

/// TimerAction.GetApplicationTime - to get the current time

/// TimerAction.GetElapsedTime - to get the time that elapsed between TIMER_GETELAPSEDTIME calls

///

/// </summary>

public float Timer(TimerAction command)
{
if (!isTimerInitialized)
{
isTimerInitialized = true;

// Use QueryPerformanceFrequency() to get frequency of timer. If QPF is

// not supported, we will timeGetTime() which returns milliseconds.

long qwTicksPerSec = 0;
m_bUsingQPF = QueryPerformanceFrequency(ref qwTicksPerSec);
if (m_bUsingQPF)
m_llQPFTicksPerSec = qwTicksPerSec;
}
if (m_bUsingQPF)
{
double time;
double fElapsedTime;
long qwTime = 0;

// Get either the current time or the stop time, depending

// on whether we're stopped and what command was sent

if (m_llStopTime != 0 && command != TimerAction.Start && command != TimerAction.GetAbsoluteTime)
qwTime = m_llStopTime;
else
QueryPerformanceCounter(ref qwTime);

// Return the elapsed time

if (command == TimerAction.GetElapsedTime)
{
fElapsedTime = (double) (qwTime - m_llLastElapsedTime) / (double) m_llQPFTicksPerSec;
m_llLastElapsedTime = qwTime;
return (float)fElapsedTime;
}

// Return the current time

if (command == TimerAction.GetApplicationTime)
{
double fAppTime = (double) (qwTime - m_llBaseTime) / (double) m_llQPFTicksPerSec;
return (float)fAppTime;
}

// Reset the timer

if (command == TimerAction.Reset)
{
m_llBaseTime = qwTime;
m_llLastElapsedTime = qwTime;
m_llStopTime = 0;
m_bTimerStopped = false;
return 0.0f;
}

// Start the timer

if (command == TimerAction.Start)
{
if (m_bTimerStopped)
m_llBaseTime += qwTime - m_llStopTime;
m_llStopTime = 0;
m_llLastElapsedTime = qwTime;
m_bTimerStopped = false;
return 0.0f;
}

// Stop the timer

if (command == TimerAction.Stop)
{
if (!m_bTimerStopped)
{
m_llStopTime = qwTime;
m_llLastElapsedTime = qwTime;
m_bTimerStopped = true;
}
return 0.0f;
}

// Advance the timer by 1/10th second

if (command == TimerAction.Advance)
{
m_llStopTime += m_llQPFTicksPerSec/10;
return 0.0f;
}

if (command == TimerAction.GetAbsoluteTime)
{
time = qwTime / (double) m_llQPFTicksPerSec;
return (float)time;
}

return -1.0f; // Invalid command specified

}
else
{
// Get the time using timeGetTime()

double time;
double fElapsedTime;

// Get either the current time or the stop time, depending

// on whether we're stopped and what command was sent

if (m_fStopTime != 0.0 && command != TimerAction.Start && command != TimerAction.GetAbsoluteTime)
time = m_fStopTime;
else
time = timeGetTime() * 0.001;

// Return the elapsed time

if (command == TimerAction.GetElapsedTime)
{
fElapsedTime = (double) (time - m_fLastElapsedTime);
m_fLastElapsedTime = time;
return (float) fElapsedTime;
}

// Return the current time

if (command == TimerAction.GetApplicationTime)
{
return (float) (time - m_fBaseTime);
}

// Reset the timer

if (command == TimerAction.Reset)
{
m_fBaseTime = time;
m_fLastElapsedTime = time;
m_fStopTime = 0;
m_bTimerStopped = false;
return 0.0f;
}

// Start the timer

if (command == TimerAction.Start)
{
if (m_bTimerStopped)
m_fBaseTime += time - m_fStopTime;
m_fStopTime = 0.0f;
m_fLastElapsedTime = time;
m_bTimerStopped = false;
return 0.0f;
}

// Stop the timer

if (command == TimerAction.Stop)
{
if (!m_bTimerStopped)
{
m_fStopTime = time;
m_fLastElapsedTime = time;
m_bTimerStopped = true;
}
return 0.0f;
}

// Advance the timer by 1/10th second

if (command == TimerAction.Advance)
{
m_fStopTime += 0.1f;
return 0.0f;
}

if (command == TimerAction.GetAbsoluteTime)
{
return (float) time;
}

return -1.0f; // Invalid command specified

}
}
}
}


edit: oh, it's "source" and not "code"

[edited by - unferth on August 30, 2003 2:04:56 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.