Модератор: Модераторы
StartTime : TTimeVal;
GetTimeOfDay(StartTime, nil);
...
tv : TTimeVal;
GetTimeOfDay(tv, nil);
Result := 1000 * (tv.tv_sec - StartTime.tv_sec) + tv.tv_usec div 1000;
FedeX писал(а):MSE немного староватая валяеться
Serafim писал(а):Тут пробелы не отображаются. Суть в том, что просто при включении в uses модуля Crt каждое сообщение печатаемое с новой строки начинает уходить вправо на один символ по сравнению с началом предыдущего сообщения.
{ MSEgui Copyright (c) 1999-2008 by Martin Schreiber
See the file COPYING.MSE, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
}
unit msetimer;
{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif}
interface
uses
Classes,msetypes,mseevent,mseguiglob,mseclasses;
type
tsimpletimer = class(tnullinterfacedobject)
private
fenabled: boolean;
finterval: integer;
fontimer: notifyeventty;
procedure setenabled(const Value: boolean);
procedure setinterval(const Value: integer);
protected
procedure dotimer;
public
constructor create(interval: integer; ontimer: notifyeventty; active: boolean);
//activates timer
destructor destroy; override;
property interval: integer read finterval write setinterval;
//in microseconds, <= 0 -> single shot, max +-2000 seconds
//restarts timer if active
property ontimer: notifyeventty read fontimer write fontimer;
property enabled: boolean read fenabled write setenabled default true;
//last!
end;
ttimer = class(tmsecomponent)
private
ftimer: tsimpletimer;
fenabled: boolean; //for design
function getenabled: boolean;
procedure setenabled(const avalue: boolean);
function getinterval: integer;
procedure setinterval(const avalue: integer);
function getontimer: notifyeventty;
procedure setontimer(const Value: notifyeventty);
protected
procedure doasyncevent(var atag: integer); override;
public
constructor create(aowner: tcomponent); override;
destructor destroy; override;
published
property interval: integer read getinterval write setinterval default 1000000;
//in microseconds, <= 0 -> single shot, max +-2000 seconds
//restarts timer if enabled
property ontimer: notifyeventty read getontimer write setontimer;
property enabled: boolean read getenabled write setenabled default false;
//last!
end;
procedure tick(sender: tobject);
procedure init;
procedure deinit;
implementation
uses
msesysintf,SysUtils,mseapplication,msesys,msesysutils;
const
enabletimertag = 8346320;
type
ptimerinfoty = ^timerinfoty;
timerinfoty = record
nexttime: cardinal;
interval: cardinal;
prevpo,nextpo: ptimerinfoty;
ontimer: objectprocty;
end;
var
first: ptimerinfoty;
mutex: mutexty;
rewaked: boolean;
procedure extract(po: ptimerinfoty);
//mutex has to be locked
begin
if first = po then begin
first:= po^.nextpo;
if first <> nil then begin
first^.prevpo:= nil;
end;
end;
if po^.prevpo <> nil then begin
po^.prevpo^.nextpo:= po^.nextpo;
end;
if po^.nextpo <> nil then begin
po^.nextpo^.prevpo:= po^.prevpo;
end;
end;
procedure insert(po: ptimerinfoty); //mutex has to be locked
var
po1,po2: ptimerinfoty;
ca1: cardinal;
begin
ca1:= po^.nexttime;
po2:= po;
po1:= po^.nextpo;
if po1 = nil then begin
po1:= first;
end;
// while (po1 <> nil) and (integer(po1^.nexttime-ca1) < 0) do begin //todo!!!!!: FPC bug 4768
while (po1 <> nil) and later(po1^.nexttime,ca1) do begin
po2:= po1;
po1:= po1^.nextpo;
end;
if po1 = nil then begin //last
if po2 = po then begin //single
po^.prevpo:= nil;
first:= po;
end
else begin //last
po^.prevpo:= po2;
po2^.nextpo:= po;
end;
po^.nextpo:= nil;
end
else begin
if po1^.prevpo = nil then begin //first
po^.prevpo:= nil;
po1^.prevpo:= po;
first:= po;
po^.nextpo:= po1;
end
else begin
po^.prevpo:= po1^.prevpo;
po^.prevpo^.nextpo:= po;
po1^.prevpo:= po;
po^.nextpo:= po1;
end;
end;
end;
procedure killtimertick(aontimer: objectprocty);
var
po1: ptimerinfoty;
begin
sys_mutexlock(mutex);
po1:= first;
while po1 <> nil do begin
if issamemethod(tmethod(po1^.ontimer),tmethod(aontimer)) then begin
po1^.ontimer:= nil;
end;
po1:= po1^.nextpo;
end;
sys_mutexunlock(mutex);
end;
procedure starttimer(const reftime: cardinal);
var
int1: integer;
begin
int1:= first^.nexttime-reftime;
if int1 < 1000 then begin
application.postevent(tevent.create(ek_timer));
end
else begin
application.settimer(int1);
end;
end;
procedure settimertick(ainterval: integer; aontimer: objectprocty);
var
po: ptimerinfoty;
time: cardinal;
begin
new(po);
sys_mutexlock(mutex);
time:= sys_gettimeus;
fillchar(po^,sizeof(timerinfoty),0);
with po^ do begin
if ainterval < 0 then begin
nexttime:= time + cardinal(-ainterval);
interval:= 0;
end
else begin
nexttime:= time + cardinal(ainterval);
interval:= ainterval;
end;
ontimer:= aontimer;
end;
insert(po);
if first = po then begin
starttimer(time);
end
else begin
if later(first^.nexttime,time) then begin
rewaked:= true;
application.postevent(tevent.create(ek_timer)); //timerevent is ev. lost
end;
end;
sys_mutexunlock(mutex);
end;
procedure tick(sender: tobject);
var
time: cardinal;
po,po2: ptimerinfoty;
ontimer: objectprocty;
begin
sys_mutexlock(mutex);
rewaked:= false;
if first <> nil then begin
time:= sys_gettimeus;
po:= first;
while (po <> nil) and laterorsame(po^.nexttime,time) do begin
extract(po);
ontimer:= po^.ontimer;
po2:= po^.nextpo;
if (po^.interval = 0) or not assigned(ontimer) then begin
//single shot or killed, remove item
dispose(po);
end
else begin
repeat
inc(po^.nexttime,po^.interval)
until later(time,po^.nexttime);
insert(po);
end;
if assigned(ontimer) then begin
try
ontimer;
except
application.handleexception(sender);
end;
end;
po:= po2;
end;
if first <> nil then begin
starttimer(time);
end;
end;
sys_mutexunlock(mutex);
end;
procedure init;
begin
sys_mutexcreate(mutex);
end;
procedure deinit;
var
po1,po2: ptimerinfoty;
begin
sys_mutexlock(mutex);
po1:= first;
while po1 <> nil do begin
po2:= po1;
po1:= po1^.nextpo;
dispose(po2);
end;
first:= nil;
sys_mutexunlock(mutex);
sys_mutexdestroy(mutex);
end;
{ tsimpletimer }
constructor tsimpletimer.create(interval: integer; ontimer: notifyeventty;
active: boolean);
begin
finterval:= interval;
fontimer:= ontimer;
setenabled(active);
end;
destructor tsimpletimer.destroy;
begin
enabled:= false;
inherited;
end;
procedure tsimpletimer.dotimer;
begin
if finterval <= 0 then begin
fenabled:= false;
end;
if assigned(fontimer) then begin
fontimer(self);
end;
end;
procedure tsimpletimer.setenabled(const Value: boolean);
begin
if fenabled <> value then begin
sys_mutexlock(mutex);
fenabled := Value;
if not value then begin
killtimertick({$ifdef FPC}@{$endif}dotimer);
end
else begin
settimertick(finterval,{$ifdef FPC}@{$endif}dotimer);
end;
sys_mutexunlock(mutex);
end;
end;
procedure tsimpletimer.setinterval(const Value: integer);
begin
if (value > 2000000000) or (value < -2000000000) then begin
raise exception.create('Invalid timer interval ' + inttostr(value));
end;
finterval:= Value;
if fenabled then begin
sys_mutexlock(mutex);
killtimertick({$ifdef FPC}@{$endif}dotimer);
settimertick(finterval,{$ifdef FPC}@{$endif}dotimer);
sys_mutexunlock(mutex);
end;
end;
{ ttimer }
constructor ttimer.create(aowner: tcomponent);
begin
ftimer:= tsimpletimer.create(1000000,nil,false);
inherited;
end;
destructor ttimer.destroy;
begin
ftimer.Free;
inherited;
end;
function ttimer.getenabled: boolean;
begin
if csdesigning in componentstate then begin
result:= fenabled;
end
else begin
result:= ftimer.enabled;
end;
end;
procedure ttimer.setenabled(const avalue: boolean);
begin
if not (csdesigning in componentstate) then begin
if not application.ismainthread then begin
sys_mutexlock(mutex);
fenabled:= avalue;
if avalue and not ftimer.enabled then begin
asyncevent(enabletimertag); //win32 settimer must be in mainthread
sys_mutexunlock(mutex);
end
else begin
sys_mutexunlock(mutex);
ftimer.enabled:= avalue;
end;
end
else begin
ftimer.enabled:= avalue;
end;
end
else begin
fenabled:= avalue;
end;
end;
procedure ttimer.doasyncevent(var atag: integer);
begin
if fenabled and (atag = enabletimertag) then begin
ftimer.enabled:= true;
end;
end;
function ttimer.getinterval: integer;
begin
result:= ftimer.interval;
end;
procedure ttimer.setinterval(const avalue: integer);
begin
if not application.ismainthread and ftimer.enabled then begin
enabled:= false;
ftimer.interval:= avalue; //win32 settimer must be in main thread
enabled:= true;
end
else begin
ftimer.interval:= avalue;
end;
end;
function ttimer.getontimer: notifyeventty;
begin
result:= ftimer.ontimer;
end;
procedure ttimer.setontimer(const Value: notifyeventty);
begin
ftimer.ontimer:= value;
end;
end.
const mm = 30;
var a: array[0..mm] of TDateTime;
procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
begin
Memo1.Lines.Clear;
for i:=0 to mm do begin
Sleep(i);
a[i]:= Now();
end;
For i:=1 to mm do Memo1.Lines.Add(FormatDateTime('ss.zzz', (a[i] - a[i-1])*1000.0));
end;
procedure Sleep(milliseconds: Cardinal);
Var
timeout,timeoutresult : TTimespec;
begin
timeout.tv_sec:=milliseconds div 1000;
timeout.tv_nsec:=1000*1000*(milliseconds mod 1000);
fpnanosleep(@timeout,@timeoutresult);
end;
function Now: TDateTime;
var
SystemTime: TSystemTime;
begin
GetLocalTime(SystemTime);
result := systemTimeToDateTime(SystemTime);
end;
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14