fix #112, autoDemangle in messages caused a sync issue

This commit is contained in:
Basile Burg 2017-01-22 08:48:00 +01:00
parent cd1a929936
commit 76df25458c
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
2 changed files with 23 additions and 29 deletions

View File

@ -11,13 +11,11 @@ uses
type type
TCEDDemangler = class TCEDDemangler = class
private strict private
fActive: boolean; fActive: boolean;
fDone: boolean;
fProc: TCEProcess; fProc: TCEProcess;
fList, fOut: TStringList; fList, fOut: TStringList;
procedure procOutput(sender: TObject); procedure procTerminate(sender: TObject);
procedure init;
public public
constructor create; constructor create;
destructor destroy; override; destructor destroy; override;
@ -38,9 +36,15 @@ var
constructor TCEDDemangler.create; constructor TCEDDemangler.create;
begin begin
init;
fList := TStringList.Create; fList := TStringList.Create;
fOut := TStringList.Create; fOut := TStringList.Create;
fProc := TCEProcess.create(nil);
fProc.Executable:= exeFullName('ddemangle' + exeExt);
fProc.Options:= [poUsePipes];
fProc.OnTerminate:=@procTerminate;
fProc.ShowWindow:= swoHIDE;
fProc.execute;
fActive := true;
end; end;
destructor TCEDDemangler.destroy; destructor TCEDDemangler.destroy;
@ -52,44 +56,28 @@ begin
inherited; inherited;
end; end;
procedure TCEDDemangler.init; procedure TCEDDemangler.procTerminate(sender: TObject);
begin begin
if assigned(fProc) and fProc.Running then fActive := false;
exit;
fProc.free;
fProc := TCEProcess.create(nil);
fProc.Executable:= exeFullName('ddemangle' + exeExt);
fProc.Options:= [poUsePipes];
fProc.OnReadData:=@procOutput;
fProc.ShowWindow:= swoHIDE;
fProc.execute;
fActive := true;
end; end;
procedure TCEDDemangler.demangle(const value: string); procedure TCEDDemangler.demangle(const value: string);
var var
i: integer = 0; nb: integer;
begin begin
init;
fDone := false;
if value.isNotEmpty then if value.isNotEmpty then
fProc.Input.Write(value[1], value.length); fProc.Input.Write(value[1], value.length);
fProc.Input.WriteByte(10); fProc.Input.WriteByte(10);
while not fDone do while true do
begin begin
Application.ProcessMessages; nb := fProc.NumBytesAvailable;
i += 1; if nb <> 0 then
if i = high(integer) then break;
i := 0;
end; end;
end; fProc.fillOutputStack;
procedure TCEDDemangler.procOutput(sender: TObject);
begin
fProc.getFullLines(fOut); fProc.getFullLines(fOut);
if fOut.Count <> 0 then if fOut.Count <> 0 then
fList.Add(fOut[0]); fList.Add(fOut[0]);
fDone := true;
end; end;
function demangle(const value: string): string; function demangle(const value: string): string;

View File

@ -34,6 +34,7 @@ type
fOutputStack: TMemoryStream; fOutputStack: TMemoryStream;
fTerminateChecker: TTimer; fTerminateChecker: TTimer;
fDoneTerminated: boolean; fDoneTerminated: boolean;
fHasRead: boolean;
procedure checkTerminated(sender: TObject); procedure checkTerminated(sender: TObject);
procedure setOnTerminate(value: TNotifyEvent); procedure setOnTerminate(value: TNotifyEvent);
procedure setOnReadData(value: TNotifyEvent); procedure setOnReadData(value: TNotifyEvent);
@ -53,6 +54,8 @@ type
procedure getFullLines(list: TStrings; consume: boolean = true); procedure getFullLines(list: TStrings; consume: boolean = true);
// access to a flexible copy of TProcess.Output // access to a flexible copy of TProcess.Output
property OutputStack: TMemoryStream read fOutputStack; property OutputStack: TMemoryStream read fOutputStack;
// indicates if an output buffer is read
property hasRead: boolean read fHasRead;
end; end;
{ {
@ -111,6 +114,7 @@ end;
procedure TCEProcess.Execute; procedure TCEProcess.Execute;
begin begin
fHasRead := false;
fOutputStack.Clear; fOutputStack.Clear;
fDoneTerminated := false; fDoneTerminated := false;
TAsyncProcess(self).OnReadData := @internalDoOnReadData; TAsyncProcess(self).OnReadData := @internalDoOnReadData;
@ -184,6 +188,7 @@ end;
procedure TCEProcess.internalDoOnReadData(sender: TObject); procedure TCEProcess.internalDoOnReadData(sender: TObject);
begin begin
fHasRead := true;
fillOutputStack; fillOutputStack;
if fRealOnReadData <> nil then if fRealOnReadData <> nil then
fRealOnReadData(self); fRealOnReadData(self);
@ -191,6 +196,7 @@ end;
procedure TCEProcess.internalDoOnTerminate(sender: TObject); procedure TCEProcess.internalDoOnTerminate(sender: TObject);
begin begin
fHasRead := false;
fTerminateChecker.Enabled := false; fTerminateChecker.Enabled := false;
if fDoneTerminated then exit; if fDoneTerminated then exit;
fDoneTerminated := true; fDoneTerminated := true;