Tento zdrojový kód je k dispozici ke stažení zde: cmd_v12_2004_09_27.zip(~1 MB)
1: | unit ChipThr; |
2: | |
3: | interface |
4: | uses Windows,Classes,Chip; |
5: | |
6: | type |
7: | TSendKeyEvent=procedure (Sender:TObject; Key:char) of object; |
8: | TBasicThread=class(TThread) |
9: | protected |
10: | FTag:integer; |
11: | FOnIdle:TNotifyEvent; |
12: | FOnSendKey:TSendKeyEvent; |
13: | FKeyBuf:string; |
14: | FKeyLock:TRTLCriticalSection; |
15: | FCommand:string; |
16: | FBas:TBasic; |
17: | FOut:char; |
18: | FInput,FOutput:TextFile; |
19: | procedure DoTTY; |
20: | public |
21: | function ReadKey:char; |
22: | function KeyPressed:boolean; |
23: | protected |
24: | procedure TTY(c:char); |
25: | function ReadBuf(Buffer: PChar; Count: Cardinal): Cardinal; |
26: | procedure WriteBuf(Buffer: PChar; Count: Cardinal); |
27: | procedure Execute;override; |
28: | procedure Idle; |
29: | procedure InitializeEngine;virtual; |
30: | public |
31: | constructor Create(AFactory:TBasicClass; const ACommand:string); |
32: | destructor Destroy;override; |
33: | procedure PushKey(key:char); |
34: | property OnSendKey:TSendKeyEvent read FOnSendKey write FOnSendKey; |
35: | property OnIdle:TNotifyEvent read FOnIdle write FOnIdle; |
36: | property Tag:integer read FTag write FTag; |
37: | property Script:TBasic read FBas; |
38: | end; |
39: | |
40: | implementation |
41: | uses SysUtils; |
42: | |
43: | procedure TBasicThread.InitializeEngine; |
44: | begin |
45: | end; |
46: | |
47: | procedure TBasicThread.Idle; |
48: | begin |
49: | if Assigned(FOnIdle) then FOnIdle(Self); |
50: | Suspend |
51: | end; |
52: | |
53: | procedure TBasicThread.DoTTY; |
54: | begin |
55: | if Assigned(FOnSendKey) then FOnSendKey(Self,FOut) |
56: | end; |
57: | |
58: | procedure TBasicThread.TTY; |
59: | begin |
60: | FOut:=c; |
61: | Synchronize(DoTTY) |
62: | end; |
63: | |
64: | constructor TBasicThread.Create; |
65: | begin |
66: | inherited Create(true); |
67: | FCommand:=ACommand; |
68: | FBas:=AFactory.Create; |
69: | InitializeCriticalSection(FKeyLock) |
70: | end; |
71: | |
72: | function TBasicThread.KeyPressed; |
73: | begin |
74: | EnterCriticalSection(FKeyLock); |
75: | Result:=FKeyBuf<>''; |
76: | LeaveCriticalSection(FKeyLock) |
77: | end; |
78: | |
79: | function TBasicThread.ReadKey; |
80: | label loop; |
81: | begin |
82: | loop: |
83: | EnterCriticalSection(FKeyLock); |
84: | if FKeyBuf='' then |
85: | Result:=#0 |
86: | else begin |
87: | Result:=FKeyBuf[1]; |
88: | Delete(FKeyBuf,1,1) |
89: | end; |
90: | LeaveCriticalSection(FKeyLock); |
91: | if Result=#0 then begin |
92: | Idle; |
93: | goto loop |
94: | end |
95: | end; |
96: | |
97: | function TBasicThread.ReadBuf; |
98: | var |
99: | Ch: Char; |
100: | I: Cardinal; |
101: | |
102: | procedure WriteChar(c:char); |
103: | begin |
104: | TTY(c) |
105: | end; |
106: | |
107: | begin |
108: | I := 0; |
109: | repeat |
110: | Ch := ReadKey; |
111: | case Ch of |
112: | #8: |
113: | if I > 0 then |
114: | begin |
115: | Dec(I); |
116: | WriteChar(#8); |
117: | end; |
118: | #32..#255: |
119: | if I < Count - 2 then |
120: | begin |
121: | Buffer[I] := Ch; |
122: | Inc(I); |
123: | WriteChar(Ch); |
124: | end; |
125: | end; |
126: | until (Ch in [#0,#13]); |
127: | Buffer[I] := Ch; |
128: | Inc(I); |
129: | if Ch = #13 then |
130: | begin |
131: | Buffer[I] := #10; |
132: | Inc(I); |
133: | WriteBuf(#13#10,2); |
134: | end; |
135: | ReadBuf := I; |
136: | end; |
137: | |
138: | procedure TBasicThread.WriteBuf; |
139: | begin |
140: | while Count>0 do begin |
141: | TTY(Buffer^); |
142: | inc(Buffer); |
143: | dec(Count) |
144: | end |
145: | end; |
146: | |
147: | { Text file device driver output function } |
148: | |
149: | function CrtOutput(var F: TTextRec): Integer; far; |
150: | begin |
151: | if F.BufPos <> 0 then |
152: | with TObject((@F.UserData)^) as TBasicThread do |
153: | begin |
154: | WriteBuf(PChar(F.BufPtr), F.BufPos); |
155: | F.BufPos := 0; |
156: | end; |
157: | CrtOutput := 0; |
158: | end; |
159: | |
160: | { Text file device driver input function } |
161: | |
162: | function CrtInput(var F: TTextRec): Integer; far; |
163: | begin |
164: | with TObject((@F.UserData)^) as TBasicThread do |
165: | F.BufEnd := ReadBuf(PChar(F.BufPtr), F.BufSize); |
166: | F.BufPos := 0; |
167: | CrtInput := 0; |
168: | end; |
169: | |
170: | { Text file device driver close function } |
171: | |
172: | function CrtClose(var F: TTextRec): Integer; far; |
173: | begin |
174: | CrtClose := 0; |
175: | end; |
176: | |
177: | { Text file device driver open function } |
178: | |
179: | function CrtOpen(var F: TTextRec): Integer; far; |
180: | begin |
181: | if F.Mode = fmInput then |
182: | begin |
183: | F.InOutFunc := @CrtInput; |
184: | F.FlushFunc := nil; |
185: | end else |
186: | begin |
187: | F.Mode := fmOutput; |
188: | F.InOutFunc := @CrtOutput; |
189: | F.FlushFunc := @CrtOutput; |
190: | end; |
191: | F.CloseFunc := @CrtClose; |
192: | CrtOpen := 0; |
193: | end; |
194: | |
195: | procedure TBasicThread.Execute; |
196: | |
197: | procedure AssignCrt(var F: Text); |
198: | begin |
199: | with TTextRec(F) do |
200: | begin |
201: | Handle := Cardinal(-1); |
202: | Mode := fmClosed; |
203: | BufSize := SizeOf(Buffer); |
204: | BufPtr := @Buffer; |
205: | OpenFunc := @CrtOpen; |
206: | Move(Self, UserData[1],Sizeof(Pointer)); |
207: | Name[0] := #0; |
208: | end; |
209: | end; |
210: | |
211: | begin |
212: | FBas.Input:=@FInput; |
213: | AssignCrt(FInput); |
214: | Reset(FInput); |
215: | FBas.Output:=@FOutput; |
216: | AssignCrt(FOutput); |
217: | Rewrite(FOutput); |
218: | InitializeEngine; |
219: | FBas.Run(FCommand) |
220: | end; |
221: | |
222: | procedure TBasicThread.PushKey; |
223: | begin |
224: | EnterCriticalSection(FKeyLock); |
225: | if key = #3 then |
226: | FBas.SetBreak |
227: | else |
228: | FKeyBuf:=FKeyBuf+key; |
229: | Resume; |
230: | LeaveCriticalSection(FKeyLock) |
231: | end; |
232: | |
233: | destructor TBasicThread.Destroy; |
234: | begin |
235: | FBas.Free; |
236: | CloseFile(FInput); |
237: | CloseFile(FOutput); |
238: | DeleteCriticalSection(FKeyLock); |
239: | inherited |
240: | end; |
241: | |
242: | end. |