View Full Version : Converting cross-platform C++ timer code to pascal...
paul_nicholls
15-08-2011, 06:30 AM
Hi all,
I found this page today:
http://www.songho.ca/misc/timer/timer.html
and I want to convert it over to pascal so I can have a high-resolution timer that works in Delphi and Freepascal :)
Any ideas how I can go about converting it the non-Delphi part? I am not sure what FPC units I would need for the time of day stuff - they use time.h...
cheers,
Paul
paul_nicholls
15-08-2011, 06:57 AM
This is my conversion attempt, but I'm sure it won't compile under Linux/Mac OSX as I don't know the correct units to include for those platforms:
unit xeEngine_timer;
interface
{$I xeEngine_include.inc}
procedure Timer_Init; cdecl; // initialize timer (like constructor)
procedure Timer_Start; cdecl; // start timer
procedure Timer_Stop; cdecl; // stop the timer
function Timer_GetElapsedTime: Double; cdecl; // get elapsed time in second
function Timer_GetElapsedTime_Sec: Double; cdecl; // get elapsed time in second (same as getElapsedTime)
function Timer_GetElapsedTime_mSec: Double; cdecl; // get elapsed time in milli-second
function Timer_GetElapsedTime_uSec: Double; cdecl; // get elapsed time in micro-second
implementation
uses
{$ifdef windows}
windows
{$endif}
;
var
startTimeInMicroSec : Double; // starting time in micro-second
endTimeInMicroSec : Double; // ending time in micro-second
stopped : Boolean; // stop flag
{$ifdef windows}
frequency : Int64; // ticks per second
startCount : Int64; //
endCount : Int64; //
{$else}
startCount : timeval; //
endCount : timeval //
{$endif}
procedure Timer_Init;
begin
{$ifdef windows}
QueryPerformanceFrequency(frequency);
startCount := 0;
endCount := 0;
{$else}
startCount.tv_sec := 0;
startCount.tv_usec := 0;
endCount.tv_sec := 0;
endCount.tv_usec := 0;
{$endif}
stopped := False;
startTimeInMicroSec := 0;
endTimeInMicroSec := 0;
end;
procedure Timer_Start;
begin
stopped := False; // reset stop flag
{$ifdef windows}
QueryPerformanceCounter(startCount);
{$else}
gettimeofday(startCount, nil);
{$endif}
end;
procedure Timer_Stop;
begin
stopped := True; // set timer stopped flag
{$ifdef windows}
QueryPerformanceCounter(endCount);
{$else}
gettimeofday(endCount, NULL);
{$endif}
end;
function Timer_GetElapsedTime: Double;
begin
Result := Timer_GetElapsedTime_Sec;
end;
function Timer_GetElapsedTime_Sec: Double;
begin
Result := Timer_GetElapsedTime_uSec * 0.000001;
end;
function Timer_GetElapsedTime_mSec: Double;
begin
Result := Timer_GetElapsedTime_uSec * 0.001;
end;
function Timer_GetElapsedTime_uSec: Double;
begin
{$ifdef windows}
if not stopped then
QueryPerformanceCounter(endCount);
startTimeInMicroSec := startCount * (1000000.0 / frequency);
endTimeInMicroSec := endCount * (1000000.0 / frequency);
{$else}
if not stopped then
gettimeofday(endCount, nil);
startTimeInMicroSec := (startCount.tv_sec * 1000000.0) + startCount.tv_usec;
endTimeInMicroSec := (endCount.tv_sec * 1000000.0) + endCount.tv_usec;
{$endif}
Result := endTimeInMicroSec - startTimeInMicroSec;
end;
end.
What do you guys/gals think?
cheers,
Paul
Andru
15-08-2011, 12:13 PM
gettimeofday
Will not work with FreePascal. You should use fpGetTimeOfDay instead, and unit Unix.
phibermon
15-08-2011, 07:33 PM
you may want to wrap it up in a class or put the timer vars in a record that you can pass to the functions to allow multiple timers.
paul_nicholls
15-08-2011, 08:36 PM
@Andru: thanks mate, that sort of information was what I was hoping for :)
@philbermon: I think I will go the record route, thanks for the idea!
cheers,
Paul
Carver413
15-08-2011, 09:12 PM
The X window system I am working on has a 3 stage timer built into the TApplication. it is a stak based timer adding timers is as easy as
Application.AddMsTask('OnTimer',Window,@OnTimer,10 );
Application.AddSecTask('OnTimer',Window,@OnTimer,1 3);
Application.AddMinTask('OnTimer',Window,@OnTimer,2 2);
the Ontimer is the event handling code and if it return's a True the event will remove itself.
to test it I opened 12 windows with a rotationing object in each. it seems to work very well as long as the load can be handled. I've only tested the AddMsTask so far but I see no reason why the others shouldn't work as expected. My system is built around a very custom linked list design. that allows for managing many lists from a single object. so it made since to build the timer functions into the application rather then creating a bunch of timer objects. this way all events are processed in a single loop including all of the X events.
code_glitch
15-08-2011, 09:44 PM
Turns out that Andru's right as always. Seems like his soltuion works for me on a Ubuntu 10.10 x64 Box with fpc 2.4.0 (ppcx64) if anyone is after the technicalities. Good find though.
Carver413
15-08-2011, 09:54 PM
I believe the correct unit is SysUtils as this has crossplatform support.
http://www.freepascal.org/docs-html/rtl/sysutils/index.html
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.