-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathuCefUtilCallbackList.pas
132 lines (114 loc) · 2.67 KB
/
uCefUtilCallbackList.pas
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
unit uCefUtilCallbackList;
interface
uses
SysUtils, Classes, System.Generics.Collections, ioutils, System.SyncObjs,
//
uCEFTypes, uCEFInterfaces, uCEFv8Value, uCEFProcessMessage, uCEFv8Handler,
uCEFMiscFunctions,
uCEFv8Context;
type
TCefCallbackItem = record
Id: Integer;
Func: ICefv8Value;
Ctx: ICefv8Context;
constructor Create(const AFunc: ICefv8Value);
end;
TCefCallbackContainer = class
private
FLock: TCriticalSection;
FList: TList<TCefCallbackItem>;
public
constructor Create;
destructor Destroy; override;
//
function Add(const AFunc: ICefv8Value): Integer;
procedure ContextRelease(const ACtx: ICefv8Context);
function Execute(const AId: Integer): Boolean;
end;
var
gCallbackList: TCefCallbackContainer;
implementation
{ TCefCallbackContainer }
function TCefCallbackContainer.Add(const AFunc: ICefv8Value): Integer;
var item: TCefCallbackItem;
begin
Result := 0;
if (not Assigned(AFunc)) or (not AFunc.IsFunction) then
Exit;
//
FLock.Enter;
try
// CefDebugLog('cb/Add');
item := TCefCallbackItem.Create(afunc);
FList.Add(item);
Result := item.Id;
finally
FLock.Leave
end;
end;
procedure TCefCallbackContainer.ContextRelease(const ACtx: ICefv8Context);
var
item: TCefCallbackItem;
j: Integer;
begin
FLock.Enter;
try
// CefDebugLog('cb/ContextRelease');
for j := FList.Count - 1 downto 0 do
begin
item := FList[j];
if item.Ctx.IsSame(ACtx) then
FList.Delete(j)
end;
finally
FLock.Leave
end;
end;
constructor TCefCallbackContainer.Create;
begin
FLock := TCriticalSection.Create;
FList := TList<TCefCallbackItem>.Create;
end;
destructor TCefCallbackContainer.Destroy;
begin
FLock.Free;
FList.Free;
inherited;
end;
function TCefCallbackContainer.Execute(const AId: Integer): Boolean;
var
item: TCefCallbackItem;
j: Integer;
begin
FLock.Enter;
try
// CefDebugLog('cb/exec');
for j := 0 to FList.Count - 1 do
begin
item := FList[j];
if item.Id = AId then
begin
item.Func.ExecuteFunctionWithContext(item.Ctx, nil, nil);
FList.Delete(j);
Exit(True)
end;
end;
finally
FLock.Leave
end;
Result := False
end;
var
ID_COUNTER: Integer = 0;
{ TCefCallbackItem }
constructor TCefCallbackItem.Create(const AFunc: ICefv8Value);
begin
Id := TInterlocked.Increment(ID_COUNTER);
Func := AFunc;
Ctx := TCefv8ContextRef.Current();
end;
initialization
gCallbackList := TCefCallbackContainer.Create;
finalization
gCallbackList.Free;
end.