-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathclock.pas
More file actions
134 lines (109 loc) · 2.8 KB
/
clock.pas
File metadata and controls
134 lines (109 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
{$MODE OBJFPC} { -*- delphi -*- }
{$INCLUDE settings.inc}
unit clock;
interface
uses
sysutils;
type
TClock = class abstract
function Now(): TDateTime; virtual; abstract;
function AsUnixEpoch(): Int64;
end;
TRootClock = class abstract (TClock)
constructor Create(); virtual; abstract;
end;
TRootClockClass = class of TRootClock;
TSystemClock = class(TRootClock)
constructor Create(); override;
function Now(): TDateTime; override;
end;
TComposedClock = class abstract (TClock)
protected
FParentClock: TClock;
public
constructor Create(AParentClock: TClock); virtual;
property Parent: TClock read FParentClock;
end;
TMonotonicClock = class(TComposedClock)
private
FLast: TDateTime;
public
constructor Create(AParentClock: TClock); override;
function Now(): TDateTime; override;
end;
// A clock that returns the same value every time Now() is called.
// The value is forgotten when Unlatch() is called. The value is taken from the given parent TClock when
// the time is first read after the object is created or after Unlatch() is called.
TStableClock = class(TComposedClock)
private
FNow, FMax: TDateTime;
public
constructor Create(AParentClock: TClock); override;
procedure Unlatch();
procedure UnlatchUntil(Max: TDateTime);
function Now(): TDateTime; override;
end;
implementation
uses math, dateutils;
function TClock.AsUnixEpoch(): Int64;
begin
Result := DateTimeToUnix(Now());
end;
constructor TSystemClock.Create();
begin
end;
function TSystemClock.Now(): TDateTime;
begin
Result := sysutils.Now();
end;
constructor TComposedClock.Create(AParentClock: TClock);
begin
inherited Create();
FParentClock := AParentClock;
end;
constructor TMonotonicClock.Create(AParentClock: TClock);
begin
inherited Create(AParentClock);
FLast := FParentClock.Now;
end;
function TMonotonicClock.Now(): TDateTime;
begin
Result := FParentClock.Now;
if (Result < FLast) then
begin
{$IFOPT C+}
Writeln('MONOTONIC CLOCK DETECTED NEGATIVE TIME (was: ', FLast, '; now: ', Result, ')');
{$ENDIF}
Result := FLast;
end
else
FLast := Result;
end;
constructor TStableClock.Create(AParentClock: TClock);
begin
inherited Create(AParentClock);
FNow := NaN;
FMax := NaN;
end;
procedure TStableClock.Unlatch();
begin
FNow := NaN;
FMax := NaN;
end;
procedure TStableClock.UnlatchUntil(Max: TDateTime);
begin
FNow := NaN;
FMax := Max;
end;
function TStableClock.Now(): TDateTime;
begin
Assert(Assigned(FParentClock));
if (IsNaN(FNow)) then
begin
FNow := FParentClock.Now();
if (not IsNaN(FMax) and (FNow > FMax)) then
FNow := FMax;
end;
Result := FNow;
end;
end.