source: PinConnection/UCommDelay.pas@ 299

Last change on this file since 299 was 296, checked in by george, 14 years ago
  • Added: New TCommDelay interconnection block for creating time delay in route.
  • Fixed: In TCommThread do not obtain lock during sending data in thread.
  • Modified: TCommFrame have ability to change special control symbols.
File size: 4.4 KB
Line 
1unit UCommDelay;
2
3{$mode Delphi}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils, UCommPin, UThreading, SyncObjs, SpecializedList, UStreamHelper;
9
10type
11 TCommDelay = class;
12
13 { TDelayedPacket }
14
15 TDelayedPacket = class
16 ReceiveTime: TDateTime;
17 Data: TStreamHelper;
18 constructor Create;
19 destructor Destroy; override;
20 end;
21
22 { TCommDelayThread }
23
24 TCommDelayThread = class(TTermThread)
25 Parent: TCommDelay;
26 procedure Execute; override;
27 end;
28
29 { TCommDelay }
30
31 TCommDelay = class
32 private
33 FActive: Boolean;
34 FDelay: TDateTime;
35 PacketQueue1: TListObject; // TListObject<TDelayedPacket>
36 PacketQueue2: TListObject; // TListObject<TDelayedPacket>
37 Thread: TCommDelayThread;
38 procedure ReceiveData1(Sender: TCommPin; AStream: TStream);
39 procedure ReceiveData2(Sender: TCommPin; AStream: TStream);
40 procedure SetActive(AValue: Boolean);
41 public
42 Lock: TCriticalSection;
43 Pin1: TCommPin;
44 Pin2: TCommPin;
45 constructor Create;
46 destructor Destroy; override;
47 property Delay: TDateTime read FDelay write FDelay;
48 property Active: Boolean read FActive write SetActive;
49 end;
50
51implementation
52
53{ TCommDelayThread }
54
55procedure TCommDelayThread.Execute;
56var
57 I: Integer;
58 CurrentTime: TDateTime;
59 SendData: TStreamHelper;
60begin
61 try
62 SendData := TStreamHelper.Create;
63 repeat
64 with Parent do begin
65 try
66 Lock.Acquire;
67 CurrentTime := Now;
68 for I := PacketQueue1.Count - 1 downto 0 do
69 if TDelayedPacket(PacketQueue1[I]).ReceiveTime < (CurrentTime - Delay) then begin
70 SendData.Clear;
71 SendData.WriteStream(TDelayedPacket(PacketQueue1[I]).Data, TDelayedPacket(PacketQueue1[I]).Data.Size);
72 PacketQueue1.Delete(I);
73 try
74 Lock.Release;
75 Pin1.Send(SendData.Stream);
76 finally
77 Lock.Acquire;
78 end;
79 end;
80
81 for I := PacketQueue2.Count - 1 downto 0 do
82 if TDelayedPacket(PacketQueue2[I]).ReceiveTime < (CurrentTime - Delay) then begin
83 SendData.Clear;
84 SendData.WriteStream(TDelayedPacket(PacketQueue2[I]).Data, TDelayedPacket(PacketQueue2[I]).Data.Size);
85 PacketQueue2.Delete(I);
86 try
87 Lock.Release;
88 Pin2.Send(SendData.Stream);
89 finally
90 Lock.Acquire;
91 end;
92 end;
93 finally
94 Lock.Release;
95 end;
96 end;
97 if not Terminated then Sleep(1);
98 until Terminated;
99 finally
100 SendData.Free;
101 end;
102end;
103
104{ TDelayedPacket }
105
106constructor TDelayedPacket.Create;
107begin
108 Data := TStreamHelper.Create;
109end;
110
111destructor TDelayedPacket.Destroy;
112begin
113 Data.Free;
114 inherited Destroy;
115end;
116
117{ TCommDelay }
118
119procedure TCommDelay.ReceiveData1(Sender: TCommPin; AStream: TStream);
120begin
121 try
122 Lock.Acquire;
123 if Delay = 0 then Pin2.Send(AStream)
124 else
125 with TDelayedPacket(PacketQueue2.AddNew(TDelayedPacket.Create)) do begin
126 ReceiveTime := Now;
127 Data.WriteStream(AStream, AStream.Size);
128 end;
129 finally
130 Lock.Release;
131 end;
132end;
133
134procedure TCommDelay.ReceiveData2(Sender: TCommPin; AStream: TStream);
135begin
136 try
137 Lock.Acquire;
138 if Delay = 0 then Pin1.Send(AStream)
139 else
140 with TDelayedPacket(PacketQueue1.AddNew(TDelayedPacket.Create)) do begin
141 ReceiveTime := Now;
142 Data.WriteStream(AStream, AStream.Size);
143 end;
144 finally
145 Lock.Release;
146 end;
147end;
148
149procedure TCommDelay.SetActive(AValue: Boolean);
150begin
151 if FActive = AValue then Exit;
152 FActive := AValue;
153 if AValue then begin
154 Thread := TCommDelayThread.Create(True);
155 Thread.FreeOnTerminate := False;
156 Thread.Parent := Self;
157 Thread.Name := 'CommDelay';
158 Thread.Start;
159 end else begin
160 FreeAndNil(Thread);
161 end;
162end;
163
164constructor TCommDelay.Create;
165begin
166 Lock := TCriticalSection.Create;
167 PacketQueue1 := TListObject.Create;
168 PacketQueue2 := TListObject.Create;
169 Pin1 := TCommPin.Create;
170 Pin1.OnReceive := ReceiveData1;
171 Pin2 := TCommPin.Create;
172 Pin2.OnReceive := ReceiveData2;
173end;
174
175destructor TCommDelay.Destroy;
176begin
177 Active := False;
178 Pin2.Free;
179 Pin1.Free;
180 PacketQueue1.Free;
181 PacketQueue2.Free;
182 Lock.Free;
183 inherited Destroy;
184end;
185
186end.
187
Note: See TracBrowser for help on using the repository browser.