60 |
|
{ } |
61 |
|
{************************************************************************} |
62 |
|
unit FBEvents; |
63 |
< |
{$IFDEF MSWINDOWS} |
64 |
< |
{$DEFINE WINDOWS} |
63 |
> |
{$IFDEF MSWINDOWS} |
64 |
> |
{$DEFINE WINDOWS} |
65 |
|
{$ENDIF} |
66 |
|
|
67 |
|
{$IFDEF FPC} |
108 |
|
procedure CancelEvents(Force: boolean = false); virtual; |
109 |
|
procedure EventSignaled; |
110 |
|
function GetIEvents: IEvents; virtual; abstract; |
111 |
< |
procedure ProcessEventCounts; |
111 |
> |
function ProcessEventCounts: boolean; |
112 |
|
public |
113 |
|
const EPB_version1 = 1; |
114 |
|
public |
118 |
|
{IEvents} |
119 |
|
procedure GetEvents(EventNames: TStrings); |
120 |
|
procedure SetEvents(EventNames: TStrings); overload; |
121 |
< |
procedure SetEvents(Event: AnsiString); overload; |
121 |
> |
procedure SetEvents(Event: string); overload; |
122 |
|
procedure Cancel; |
123 |
|
function ExtractEventCounts: TEventCounts; |
124 |
|
function GetAttachment: IAttachment; |
125 |
|
procedure AsyncWaitForEvent(EventHandler: TEventHandler); virtual; abstract; |
126 |
+ |
procedure WaitForEvent; virtual; abstract; |
127 |
|
end; |
128 |
|
|
129 |
|
|
219 |
|
procedure TFBEvents.CreateEventBlock; |
220 |
|
var i: integer; |
221 |
|
P: PByte; |
222 |
+ |
var s: Ansistring; |
223 |
|
begin |
224 |
|
{calculate length of event parameter block, setting initial length to include version |
225 |
|
and counts for each argument} |
226 |
|
|
227 |
+ |
if FEventBuffer <> nil then |
228 |
+ |
begin |
229 |
+ |
FreeMem( FEventBuffer); |
230 |
+ |
FEventBuffer := nil; |
231 |
+ |
end; |
232 |
+ |
if FResultBuffer <> nil then |
233 |
+ |
begin |
234 |
+ |
FreeMem( FResultBuffer); |
235 |
+ |
FResultBuffer := nil; |
236 |
+ |
end; |
237 |
+ |
|
238 |
|
FEventBufferLen := 1; |
239 |
|
for i := 0 to FEvents.Count - 1 do |
240 |
< |
FEventBufferLen := FEventBufferLen + length(FEvents[i]) + 1 + sizeof(Long); |
240 |
> |
begin |
241 |
> |
s := FEvents[i]; |
242 |
> |
FEventBufferLen := FEventBufferLen + length(s) + 1 + sizeof(Long); |
243 |
> |
end; |
244 |
|
|
245 |
|
with FFirebirdClientAPI do |
246 |
|
begin |
247 |
|
IBAlloc(FEventBuffer,0,FEventBufferLen); |
248 |
|
if FEventBuffer = nil then Exit; |
233 |
– |
{$if declared(FillByte)} |
234 |
– |
FillByte(FEventBuffer^,FEventBufferLen,0); |
235 |
– |
{$else} |
249 |
|
FillChar(FEventBuffer^,FEventBufferLen,0); |
237 |
– |
{$ifend} |
250 |
|
IBAlloc(FResultBuffer,0,FEventBufferLen); |
251 |
|
if FResultBuffer = nil then |
252 |
|
begin |
253 |
|
FreeMem(FEventBuffer); |
254 |
+ |
FEventBuffer := nil; |
255 |
|
Exit; |
256 |
|
end; |
257 |
+ |
FillChar(FResultBuffer^,FEventBufferLen,0); |
258 |
|
|
259 |
|
P := FEventBuffer; |
260 |
|
P^ := EPB_version1; |
263 |
|
|
264 |
|
for i := 0 to FEvents.Count - 1 do |
265 |
|
begin |
266 |
< |
P^ := Length(FEvents[i]); |
266 |
> |
s := FEvents[i]; |
267 |
> |
P^ := Length(s); |
268 |
|
Inc(P); |
269 |
< |
Move(FEvents[i][1],P^,Length(FEvents[i])); |
270 |
< |
Inc(P,Length(FEvents[i])+sizeof(Long)); |
271 |
< |
FEventCounts[i].EventName := FEvents[i]; |
269 |
> |
Move(s[1],P^,Length(s)); |
270 |
> |
Inc(P,Length(s)+sizeof(Long)); |
271 |
> |
FEventCounts[i].EventName := s; |
272 |
|
end; |
273 |
|
end; |
274 |
|
|
275 |
|
{ for i := 0 to FEventBufferLen - 1 do |
276 |
|
write(Format('%x ', [FEventBuffer[i]])); |
277 |
< |
writeln;} |
277 |
> |
writeln; } |
278 |
|
end; |
279 |
|
|
280 |
|
procedure TFBEvents.CancelEvents(Force: boolean); |
289 |
|
FCriticalSection.Enter; |
290 |
|
try |
291 |
|
if not FInWaitState then Exit; |
292 |
< |
FInWaitState := false; |
278 |
< |
ProcessEventCounts; |
279 |
< |
if assigned(FEventHandler) then |
292 |
> |
if ProcessEventCounts and assigned(FEventHandler) then |
293 |
|
begin |
294 |
|
Handler := FEventHandler; |
295 |
|
FEventHandler := nil; |
296 |
+ |
FInWaitState := false; |
297 |
|
end; |
298 |
|
finally |
299 |
|
FCriticalSection.Leave; |
358 |
|
|
359 |
|
{ProcessEventCounts effectively replaces isc_event_counts} |
360 |
|
|
361 |
< |
procedure TFBEvents.ProcessEventCounts; |
361 |
> |
function TFBEvents.ProcessEventCounts: boolean; |
362 |
|
|
363 |
|
var i: integer; |
364 |
|
P, Q: PByte; |
366 |
|
new_count: Long; |
367 |
|
len: byte; |
368 |
|
begin |
369 |
+ |
Result := false; |
370 |
|
P := FEventBuffer; |
371 |
|
Q := FResultBuffer; |
372 |
|
Inc(P); {skip past version byte} |
383 |
|
new_count := DecodeInteger(Q,sizeof(Long)); |
384 |
|
Inc(Q,sizeof(Long)); |
385 |
|
FEventCounts[i].Count := new_count - initial_count; |
386 |
+ |
if FEventCounts[i].Count > 0 then |
387 |
+ |
Result := true; |
388 |
+ |
// writeln('Event Count[',i,'] = ',FEventCounts[i].Count); |
389 |
|
end; |
390 |
|
Move(FResultBuffer^,FEventBuffer^,FEventBufferLen); |
391 |
|
end; |
440 |
|
end; |
441 |
|
end; |
442 |
|
|
443 |
< |
procedure TFBEvents.SetEvents(Event: AnsiString); |
443 |
> |
procedure TFBEvents.SetEvents(Event: string); |
444 |
|
var S: TStringList; |
445 |
|
begin |
446 |
|
S := TStringList.Create; |