-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathSingletons.pas
More file actions
87 lines (73 loc) · 2.1 KB
/
Singletons.pas
File metadata and controls
87 lines (73 loc) · 2.1 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
(*
Singletons unit
(C) 2006 Mirage
Created May 25, 2006
The unit contains base singleton class. Any descendant class will have a singleton-like behaviour
*)
{$Include GDefines}
unit Singletons;
interface
type
TSingleton = class
procedure Init; virtual;
class function NewInstance: TObject; override;
procedure FreeInstance; override;
end;
implementation
type
TSingletonEntry = record
Instance: TObject;
end;
var
SingletonEntries: array of TSingletonEntry;
function FindSingletonEntry(AClassType: TClass): Integer;
begin
for Result := 0 to High(SingletonEntries) do if SingletonEntries[Result].Instance.ClassType = AClassType then Exit;
Result := -1;
end;
procedure NewSingletonEntry(AInstance: TObject);
begin
SetLength(SingletonEntries, Length(SingletonEntries)+1);
SingletonEntries[High(SingletonEntries)].Instance := AInstance;
end;
procedure DeleteSingletonEntry(AInstance: TObject);
var i: Integer; Found: Boolean;
begin
Found := False;
for i := 0 to High(SingletonEntries) do begin
if not Found and (SingletonEntries[i].Instance = AInstance) then Found := True;
if Found and (i < High(SingletonEntries)) then SingletonEntries[i] := SingletonEntries[i+1];
end;
SetLength(SingletonEntries, Length(SingletonEntries)-1);
end;
procedure DestroyAllSingletons;
var i: Integer;
begin
for i := 0 to High(SingletonEntries) do if Assigned(SingletonEntries[i].Instance) then begin
SingletonEntries[i].Instance.Free;
SingletonEntries[i].Instance := nil;
end;
end;
{ TSingleton }
procedure TSingleton.Init;
begin
end;
class function TSingleton.NewInstance: TObject;
var Index: Integer;
begin
Index := FindSingletonEntry(Self);
if Index = -1 then begin
Result := inherited NewInstance;
NewSingletonEntry(Result); // ToDo: Don't add if an exception in the constructor occured (use AfterConstruction)
(Result as TSingleton).Init;
end else Result := SingletonEntries[Index].Instance;
end;
procedure TSingleton.FreeInstance;
begin
DeleteSingletonEntry(Self);
inherited;
end;
initialization
finalization
DestroyAllSingletons;
end.