www.pudn.com > SiegeOfAvalon.rar > MMTimer.pas
unit MMTimer;
{******************************************************************************}
{ }
{ Siege Of Avalon : Open Source Edition }
{ ------------------------------------- }
{ }
{ Portions created by Digital Tome L.P. Texas USA are }
{ Copyright ©1999-2000 Digital Tome L.P. Texas USA }
{ All Rights Reserved. }
{ }
{ Portions created by Team SOAOS are }
{ Copyright (C) 2003 - Team SOAOS. }
{ }
{ }
{ Contributor(s) }
{ -------------- }
{ Dominique Louis }
{ }
{ }
{ }
{ You may retrieve the latest version of this file at the SOAOS project page : }
{ http://www.sourceforge.com/projects/soaos }
{ }
{ The contents of this file maybe used with permission, subject to }
{ the GNU Lesser General Public License Version 2.1 (the "License"); you may }
{ not use this file except in compliance with the License. You may }
{ obtain a copy of the License at }
{ http://www.opensource.org/licenses/lgpl-license.php }
{ }
{ Software distributed under the License is distributed on an }
{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
{ implied. See the License for the specific language governing }
{ rights and limitations under the License. }
{ }
{ Description }
{ ----------- }
{ }
{ }
{ }
{ }
{ }
{ }
{ }
{ Requires }
{ -------- }
{ DirectX Runtime libraris on Win32 }
{ They are available from... }
{ http://www.microsoft.com. }
{ }
{ Programming Notes }
{ ----------------- }
{ }
{ }
{ }
{ }
{ Revision History }
{ ---------------- }
{ July 13 2003 - DL : Initial Upload to CVS }
{ }
{******************************************************************************}
interface
uses
Windows,
Classes,
SysUtils;
type
TAniTimer = class;
TAniTimerThread = class( TThread )
private
procedure TimerEvent;
public
AniTimer : TAniTimer;
procedure Execute; override;
end;
TAniTimer = class( TComponent )
private
AniTimerThread : TAniTimerThread;
TimerOn : Boolean;
TimerThreadPriority : TThreadPriority;
TimerPaused : Boolean;
TimerInterval : Cardinal;
TimerResolution : Cardinal;
OnTimerEvent : TNotifyEvent;
OnTimerEventHandle : Integer;
TimerName : Integer;
protected
procedure InitTimer;
procedure UpdateTimerStatus( NewOn : Boolean );
procedure UpdateTimerPriority( NewPriority : TThreadPriority );
procedure UpdateTimerInterval( NewInterval : Cardinal );
public
constructor Create( AOwner : TComponent ); override;
destructor Destroy; override;
procedure Resume;
procedure Pause;
published
property Enabled : Boolean read TimerOn write UpdateTimerStatus default False;
property TimerPriority : TThreadPriority read TimerThreadPriority write UpdateTimerPriority default tpNormal;
property Interval : Cardinal read TimerInterval write UpdateTimerInterval default 100;
property Resolution : Cardinal read TimerResolution write TimerResolution default 10;
property OnTimer : TNotifyEvent read OnTimerEvent write OnTimerEvent;
property Paused : boolean read TimerPaused;
end;
TAniTimerCallBack = procedure( NA1, NA2, AniTimerUser, NA3, NA4 : Integer ) stdcall;
EAniTimer = class( Exception );
function KillTimer( AniTimerName : Integer ) : Integer; stdcall;
external 'WinMM.dll' name 'timeKillEvent';
function SetTimer( TimerInterval, TimerResolution : Integer;
AniTimerCallBack : TAniTimerCallBack;
AniTimerUser, AniTimerFlags : Integer ) : Integer; stdcall;
external 'WinMM.dll' name 'timeSetEvent';
implementation
procedure AniTimerCallBack( NA1, NA2, AniTimerUser, NA3, NA4 : Integer ); stdcall;
const
FailName : string = 'MMTimer.AniTimerCallBack';
var
AniTimer : TAniTimer;
begin
AniTimer := TAniTimer( AniTimerUser );
if Assigned( AniTimer ) then
if not AniTimer.TimerPaused then
SetEvent( AniTimer.OnTimerEventHandle );
end;
//---------------------------------------------------------------
//TAniTimerThread
procedure TAniTimerThread.TimerEvent;
const
FailName : string = 'TAniTimerThread.TimerEvent';
begin
if Assigned( AniTimer.OnTimerEvent ) then
AniTimer.OnTimerEvent( AniTimer );
end;
procedure TAniTimerThread.Execute;
const
FailName : string = 'TAniTimerThread.Execute';
begin
while not Terminated do
begin
WaitForSingleObject( AniTimer.OnTimerEventHandle, INFINITE );
if Terminated then
break;
synchronize( TimerEvent );
end;
end;
//---------------------------------------------------------------------
//TAniTimer
constructor TAniTimer.Create( AOwner : TComponent );
begin
inherited Create( AOwner );
TimerOn := False;
TimerInterval := 100;
TimerResolution := 10;
TimerPaused := False;
TimerThreadPriority := tpNormal;
end;
destructor TAniTimer.Destroy;
begin
Enabled := False;
inherited Destroy;
end;
procedure TAniTimer.InitTimer;
const
FailName : string = 'TAniTimer.InitTimer';
begin
TimerName := SetTimer( TimerInterval, TimerResolution, @AniTimerCallBack, Integer( Self ), 1 );
if TimerName = 0 then
begin
TimerOn := False;
AniTimerThread.Terminate;
SetEvent( OnTimerEventHandle );
AniTimerThread := nil;
CloseHandle( OnTimerEventHandle );
raise EAniTimer.Create( 'AniTimer creation error.' );
end;
end;
procedure TAniTimer.UpdateTimerStatus( NewOn : Boolean );
const
FailName : string = 'TAniTimer.UpdateTimerStatus';
begin
if NewOn = TimerOn then
Exit;
if ( csDesigning in ComponentState ) then
begin
TimerOn := NewOn;
Exit;
end;
if NewOn then
begin
OnTimerEventHandle := CreateEvent( nil, False, False, nil );
AniTimerThread := TAniTimerThread.Create( True );
AniTimerThread.AniTimer := Self;
AniTimerThread.FreeOnTerminate := True;
AniTimerThread.Priority := TimerThreadPriority;
AniTimerThread.Resume;
InitTimer;
end
else
begin
KillTimer( TimerName );
AniTimerThread.Terminate;
SetEvent( OnTimerEventHandle );
AniTimerThread := nil;
CloseHandle( OnTimerEventHandle );
end;
TimerOn := NewOn;
end;
procedure TAniTimer.UpdateTimerInterval( NewInterval : Cardinal );
const
FailName : string = 'TAniTimer.UpdateTimerInterval';
begin
if NewInterval = TimerInterval then
Exit;
TimerInterval := NewInterval;
if ( csDesigning in ComponentState ) then
Exit;
if Enabled then
begin
KillTimer( TimerName );
InitTimer;
end;
end;
procedure TAniTimer.UpdateTimerPriority( NewPriority : TThreadPriority );
const
FailName : string = 'TAniTimer.UpdateTimerPriority';
begin
if NewPriority = TimerThreadPriority then
Exit;
if Assigned( AniTimerThread ) then
AniTimerThread.Priority := NewPriority;
TimerThreadPriority := NewPriority;
end;
procedure TAniTimer.Pause;
const
FailName : string = 'TAniTimer.Pause';
begin
if TimerOn then
AniTimerThread.Suspend;
TimerPaused := True;
end;
procedure TAniTimer.Resume;
const
FailName : string = 'TAniTimer.Resume';
begin
if TimerOn then
AniTimerThread.Resume;
TimerPaused := False;
end;
end.