-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathLightCore.LogLinesS.pas
More file actions
154 lines (116 loc) · 4.93 KB
/
Copy pathLightCore.LogLinesS.pas
File metadata and controls
154 lines (116 loc) · 4.93 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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
UNIT LightCore.LogLinesS;
{=============================================================================================================
2026.05.07
www.GabrielMoraru.com
Github.com/GabrielOnDelphi/Delphi-LightSaber/blob/main/System/Copyright.txt
--------------------------------------------------------------------------------------------------------------
Single-Threaded Version of LogLines
This is the non-thread-safe implementation of TAbstractLogLines.
Use this when all log operations occur on a single thread (typically the main thread).
For multi-threaded scenarios, use TLogLinesMultiThreaded from LightCore.LogLinesM.pas.
The class stores log entries as PLogLine pointers in a TList.
Memory for each log line is allocated with New() and freed with Dispose() on Clear/Destroy.
Inherits ReadFromStream/WriteToStream from TAbstractLogLines (no override needed).
Tester:
LightSaber\Demo\LightLog\
=============================================================================================================}
INTERFACE
USES
System.SysUtils, System.Classes,
LightCore.LogTypes, LightCore.LogLinesAbstract;
TYPE
{ Single-threaded log lines store. Inherits CountFiltered, Row2FilteredRow, and
GetFilteredSlice from the abstract base — the lock hooks (acquireReadLock / releaseReadLock) stay as no-ops, so iteration runs lock-free. }
TLogLinesSingleThreaded = class(TAbstractLogLines)
protected
function getItem(Index: Integer): PLogLine; override;
public
constructor Create;
destructor Destroy; override;
procedure Clear; override;
function Count: Integer; override;
function AddNewLine(CONST Msg: string; Level: TLogVerbLvl; Bold: Boolean = FALSE; Indent: Integer = 0): PLogLine; override;
function Add (Value: PLogLine): Integer; override;
function SnapshotAndClear: TAbstractLogLines; override;
end;
IMPLEMENTATION
{-------------------------------------------------------------------------------------------------------------
CONSTRUCTOR / DESTRUCTOR
-------------------------------------------------------------------------------------------------------------}
constructor TLogLinesSingleThreaded.Create;
begin
inherited Create;
FList:= TList.Create;
end;
destructor TLogLinesSingleThreaded.Destroy;
begin
if FList <> NIL { NIL when the constructor raised before TList.Create finished (partially-constructed object) }
then Clear; { Free the allocated memory for lines }
FreeAndNil(FList);
inherited;
end;
function TLogLinesSingleThreaded.getItem(Index: Integer): PLogLine;
begin
Result:= PLogLine(FList[Index]);
end;
{ Disposes all log line records and clears the list. }
procedure TLogLinesSingleThreaded.Clear;
var
i: Integer;
begin
for i:= 0 to FList.Count - 1 do
Dispose(PLogLine(FList[i]));
FList.Clear;
end;
function TLogLinesSingleThreaded.Count: Integer;
begin
Result:= FList.Count;
end;
{-------------------------------------------------------------------------------------------------------------
ADD
-------------------------------------------------------------------------------------------------------------}
{ Adds an externally-created log line pointer to the list.
The caller is responsible for allocating the PLogLine with New().
The list takes ownership and will Dispose() it on Clear/Destroy. }
function TLogLinesSingleThreaded.Add(Value: PLogLine): Integer;
begin
Assert(Value <> NIL, 'TLogLinesSingleThreaded.Add: Value cannot be nil');
Result:= FList.Add(Value);
end;
{ Creates a new log line record, populates it, and adds it to the list.
Returns the pointer to the newly created line. }
function TLogLinesSingleThreaded.AddNewLine(CONST Msg: string; Level: TLogVerbLvl; Bold: Boolean = FALSE; Indent: Integer = 0): PLogLine;
begin
New(Result);
Result.Msg := Msg;
Result.Level := Level;
Result.Bold := Bold;
Result.Time := Now;
Result.Indent:= Indent;
Add(Result);
end;
{-------------------------------------------------------------------------------------------------------------
ACCESS
Row2FilteredRow / GetFilteredSlice / CountFiltered now live in TAbstractLogLines.
The single-threaded path leaves the lock hooks as no-ops, so iteration is lock-free.
-------------------------------------------------------------------------------------------------------------}
{ Atomic snapshot+clear: transfers all PLogLine pointers into a new instance and
leaves Self empty without disposing them. Caller owns the returned snapshot. }
function TLogLinesSingleThreaded.SnapshotAndClear: TAbstractLogLines;
VAR
Snapshot: TLogLinesSingleThreaded;
i: Integer;
begin
Snapshot:= TLogLinesSingleThreaded.Create;
TRY
Snapshot.FList.Capacity:= FList.Count;
for i:= 0 to FList.Count - 1 do
Snapshot.FList.Add(FList[i]);
FList.Clear; { Pointers transferred — do NOT Dispose; the snapshot owns them now. }
EXCEPT
FreeAndNil(Snapshot);
RAISE;
END;
Result:= Snapshot;
end;
end.