IDE: Read all compiler options in a thread.

git-svn-id: trunk@42474 -
This commit is contained in:
juha 2013-08-24 07:24:46 +00:00
parent b73fea1ff5
commit 2e6dcd7875
5 changed files with 170 additions and 112 deletions

View File

@ -40,15 +40,15 @@ object frmAllCompilerOptions: TfrmAllCompilerOptions
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = ButtonPanel1
Left = 0
Height = 419
Height = 397
Top = 25
Width = 616
HorzScrollBar.Increment = 61
HorzScrollBar.Page = 612
HorzScrollBar.Smooth = True
HorzScrollBar.Tracking = True
VertScrollBar.Increment = 41
VertScrollBar.Page = 415
VertScrollBar.Increment = 39
VertScrollBar.Page = 393
VertScrollBar.Smooth = True
VertScrollBar.Tracking = True
Anchors = [akTop, akLeft, akRight, akBottom]
@ -59,7 +59,7 @@ object frmAllCompilerOptions: TfrmAllCompilerOptions
object ButtonPanel1: TButtonPanel
Left = 6
Height = 41
Top = 450
Top = 428
Width = 610
OKButton.Name = 'OKButton'
OKButton.DefaultCaption = True
@ -98,4 +98,11 @@ object frmAllCompilerOptions: TfrmAllCompilerOptions
Caption = 'Use comments in custom options'
TabOrder = 4
end
object StatusBar1: TStatusBar
Left = 0
Height = 22
Top = 475
Width = 622
Panels = <>
end
end

View File

@ -6,7 +6,7 @@ interface
uses
Classes, SysUtils, Forms, Controls, StdCtrls, Buttons, ButtonPanel, EditBtn,
Dialogs, contnrs, LCLProc, Compiler, LazarusIDEStrConsts;
Dialogs, contnrs, LCLProc, ComCtrls, Compiler, LazarusIDEStrConsts;
type
@ -19,6 +19,7 @@ type
cbUseComments: TCheckBox;
edOptionsFilter: TEdit;
sbAllOptions: TScrollBox;
StatusBar1: TStatusBar;
procedure btnResetOptionsFilterClick(Sender: TObject);
procedure cbShowModifiedClick(Sender: TObject);
procedure edOptionsFilterChange(Sender: TObject);
@ -26,6 +27,7 @@ type
private
FIdleConnected: Boolean;
FOptionsReader: TCompilerOptReader;
FOptionsThread: TCompilerOptThread;
FGeneratedControls: TComponentList;
FEffectiveFilter: string;
FEffectiveShowModified: Boolean;
@ -44,6 +46,7 @@ type
function ToCustomOptions(aStrings: TStrings): TModalResult;
public
property OptionsReader: TCompilerOptReader read FOptionsReader write FOptionsReader;
property OptionsThread: TCompilerOptThread read FOptionsThread write FOptionsThread;
end;
var
@ -115,36 +118,38 @@ begin
end;
procedure TfrmAllCompilerOptions.OnIdle(Sender: TObject; var Done: Boolean);
{$IFDEF TimeAllCompilerOptions}
var
StartTime, EndTime: TDateTime;
function FormatTimeWithMs(aTime: TDateTime): string;
var
fs: TFormatSettings;
ms: string;
{$ENDIF}
begin
fs.TimeSeparator := ':';
Result := FormatDateTime('nn:ss', aTime, fs)+'.'+FormatDateTime('zzz', aTime);
end;
var
StartTime: TDateTime;
ReadTimeStr, RenderTimeStr: string;
begin
IdleConnected := False;
Screen.Cursor := crHourGlass;
try
edOptionsFilter.Enabled := False;
{$IFDEF TimeAllCompilerOptions}
FOptionsThread.WaitFor; // Make sure the options are read.
if FOptionsReader.ErrorMsg <> '' then
StatusBar1.SimpleText := FOptionsReader.ErrorMsg
else begin
StartTime := Now;
{$ENDIF}
RenderAndFilterOptions;
{$IFDEF TimeAllCompilerOptions}
EndTime := Now-StartTime;
{$ENDIF}
edOptionsFilter.Enabled := True;
RenderTimeStr := FormatTimeWithMs(Now-StartTime);
ReadTimeStr := FormatTimeWithMs(FOptionsThread.ReadTime);
StatusBar1.SimpleText := Format('Time for reading options: %s, rendering GUI: %s',
[ReadTimeStr, RenderTimeStr]);
end;
finally
Screen.Cursor := crDefault;
end;
{$IFDEF TimeAllCompilerOptions}
if not FRenderedOnce then begin
ms := FormatDateTime('zzz', EndTime);
fs.TimeSeparator := ':';
ShowMessage(Format('Rendering compiler options GUI took: %s.%s',
[FormatDateTime('nn:ss', EndTime, fs), ms]));
end;
{$ENDIF}
FRenderedOnce := True;
end;

View File

@ -45,7 +45,7 @@ uses
OutputFilter,
{$ENDIF}
UTF8Process, InfoBuild, IDEMsgIntf, CompOptsIntf, IDEExternToolIntf,
DefineTemplates, TransferMacros, LazFileUtils;
DefineTemplates, TransferMacros, EnvironmentOpts, LazFileUtils;
type
TOnCmdLineCreate = procedure(var CmdLine: string; var Abort:boolean) of object;
@ -194,7 +194,24 @@ type
property SupportedCategories: TStringList read fSupportedCategories;
property RootOptGroup: TCompilerOptGroup read fRootOptGroup;
property CompilerExecutable: string read fCompilerExecutable write fCompilerExecutable;
property ErrorMsg: String read fErrorMsg;
property ErrorMsg: String read fErrorMsg write fErrorMsg;
end;
{ TCompilerOptThread }
TCompilerOptThread = class(TThread)
private
fReader: TCompilerOptReader;
fReadTime: TDateTime;
function GetErrorMsg: string;
protected
procedure Execute; override;
public
constructor Create(aReader: TCompilerOptReader);
destructor Destroy; override;
public
property ReadTime: TDateTime read fReadTime;
property ErrorMsg: string read GetErrorMsg;
end;
@ -1000,6 +1017,7 @@ var
ParsedTarget: String;
begin
OptionIdCounter := 0;
fErrorMsg := '';
if fCompilerExecutable = '' then
fCompilerExecutable := 'fpc'; // Let's hope "fpc" is found in PATH.
ParsedTarget := '-T$(TargetOS) -P$(TargetCPU)';
@ -1073,7 +1091,6 @@ begin
begin
s := Trim(aStrings[i]);
if s = '' then Continue;
sl.Clear;
SplitCmdLineParams(s, sl);
for j := 0 to sl.Count-1 do
@ -1154,5 +1171,40 @@ begin
aStrings.AddStrings(fDefines);
end;
{ TCompilerOptThread }
constructor TCompilerOptThread.Create(aReader: TCompilerOptReader);
begin
inherited Create(True);
//FreeOnTerminate:=True;
fReader:=aReader;
end;
destructor TCompilerOptThread.Destroy;
begin
inherited Destroy;
end;
function TCompilerOptThread.GetErrorMsg: string;
begin
Result := fReader.ErrorMsg;
end;
procedure TCompilerOptThread.Execute;
var
StartTime: TDateTime;
begin
StartTime := Now;
try
fReader.CompilerExecutable := EnvironmentOptions.GetParsedCompilerFilename;
fReader.ReadAndParseOptions;
except
on E: Exception do
fReader.ErrorMsg := 'Error parsing options: '+E.Message;
end;
fReadTime := Now-StartTime;
end;
end.

View File

@ -50,13 +50,22 @@ type
procedure RemoveBtnClick(Sender: TObject);
procedure DefinesCheckListKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private
FIdleConnected: Boolean;
FOptionsReader: TCompilerOptReader;
FOptionsThread: TCompilerOptThread;
FCustomOptions: TStrings;
procedure SetIdleConnected(AValue: Boolean);
procedure OnIdle(Sender: TObject; var Done: Boolean);
procedure DeleteSelected;
procedure UpdateButtons;
private
property IdleConnected: Boolean read FIdleConnected write SetIdleConnected;
public
function FromCustomOptions(aStrings: TStrings): TModalResult;
function ToCustomOptions(aStrings: TStrings): TModalResult;
public
property OptionsReader: TCompilerOptReader read FOptionsReader write FOptionsReader;
property OptionsThread: TCompilerOptThread read FOptionsThread write FOptionsThread;
property CustomOptions: TStrings read FCustomOptions write FCustomOptions;
end;
@ -80,6 +89,7 @@ procedure TCustomDefinesForm.FormShow(Sender: TObject);
begin
DefinesCheckListClick(Nil);
ActiveControl := DefinesCheckList;
IdleConnected := True;
end;
procedure TCustomDefinesForm.FormDestroy(Sender: TObject);
@ -106,10 +116,9 @@ end;
procedure TCustomDefinesForm.DefinesCheckListClick(Sender: TObject);
begin
with DefinesCheckList do begin
with DefinesCheckList do
if ItemIndex > -1 then
edDefine.Text := Items[ItemIndex];
end;
UpdateButtons;
end;
@ -125,38 +134,34 @@ end;
procedure TCustomDefinesForm.DefinesCheckListKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_DELETE then begin
if Key = VK_DELETE then
begin
DeleteSelected;
Key := 0;
end;
end;
procedure TCustomDefinesForm.DeleteSelected;
var
i: Integer;
procedure TCustomDefinesForm.SetIdleConnected(AValue: Boolean);
begin
with DefinesCheckList.Items do
for i := Count-1 downto 0 do
if DefinesCheckList.Selected[i] then begin
Delete(i);
UpdateButtons;
end;
if FIdleConnected = AValue then exit;
FIdleConnected := AValue;
if FIdleConnected then
Application.AddOnIdleHandler(@OnIdle)
else
Application.RemoveOnIdleHandler(@OnIdle);
end;
procedure TCustomDefinesForm.UpdateButtons;
begin
AddBtn.Enabled := (edDefine.Text <> '')
and (DefinesCheckList.Items.IndexOf(edDefine.Text) = -1);
RemoveBtn.Enabled := DefinesCheckList.SelCount > 0;
end;
function TCustomDefinesForm.FromCustomOptions(aStrings: TStrings): TModalResult;
procedure TCustomDefinesForm.OnIdle(Sender: TObject; var Done: Boolean);
var
s: String;
i, ListInd: Integer;
begin
IdleConnected := False;
Screen.Cursor := crHourGlass;
try
FOptionsThread.WaitFor; // Make sure the options are read.
// Parse and separate defines from other options.
FOptionsReader.FromCustomOptions(aStrings);
FOptionsReader.FromCustomOptions(FCustomOptions);
// Check the found defines in the GUI.
for i := 0 to FOptionsReader.Defines.Count-1 do
begin
@ -169,7 +174,29 @@ begin
end;
DefinesCheckList.Checked[ListInd] := True;
end;
Result:=mrOK;
finally
Screen.Cursor := crDefault;
end;
end;
procedure TCustomDefinesForm.DeleteSelected;
var
i: Integer;
begin
with DefinesCheckList.Items do
for i := Count-1 downto 0 do
if DefinesCheckList.Selected[i] then
begin
Delete(i);
UpdateButtons;
end;
end;
procedure TCustomDefinesForm.UpdateButtons;
begin
AddBtn.Enabled := (edDefine.Text <> '')
and (DefinesCheckList.Items.IndexOf(edDefine.Text) = -1);
RemoveBtn.Enabled := DefinesCheckList.SelCount > 0;
end;
function TCustomDefinesForm.ToCustomOptions(aStrings: TStrings): TModalResult;

View File

@ -31,15 +31,12 @@ uses
Classes, SysUtils, math, AVL_Tree, LazLogger, Forms, Controls, Graphics,
Dialogs, StdCtrls, LCLProc, ComCtrls, LCLType, ExtCtrls, Buttons,
CodeToolsCfgScript, KeywordFuncLists, LazarusIDEStrConsts,
IDEOptionsIntf, CompOptsIntf, IDECommands, Project, EnvironmentOpts,
IDEOptionsIntf, CompOptsIntf, IDECommands, Project,
CompilerOptions, AllCompilerOptions, Compiler, EditorOptions, PackageDefs,
SynEdit, SynEditKeyCmds, SynCompletion, SourceSynEditor, CustomDefines;
type
TIdleAction = (iaCompilerOpts, iaMessages);
TIdleActions = set of TIdleAction;
{ TCompilerOtherOptionsFrame }
TCompilerOtherOptionsFrame = class(TAbstractIDEOptionsEditor)
@ -60,7 +57,7 @@ type
procedure CondSynEditStatusChange(Sender: TObject; Changes: TSynStatusChanges);
private
FCompOptions: TBaseCompilerOptions;
FIdleConnected: TIdleActions;
FIdleConnected: Boolean;
FIsPackage: boolean;
FCompletionHistory: TStrings;
FCompletionValues: TStrings;
@ -70,8 +67,9 @@ type
fEngine: TIDECfgScriptEngine;
fSynCompletion: TSynCompletion;
FOptionsReader: TCompilerOptReader;
FOptionsThread: TCompilerOptThread;
FUseComments: boolean;
procedure SetIdleConnected(AValue: TIdleActions);
procedure SetIdleConnected(AValue: Boolean);
procedure SetStatusMessage(const AValue: string);
procedure StartCompletion;
procedure UpdateCompletionValues;
@ -105,7 +103,7 @@ type
property DefaultVariables: TCTCfgScriptVariables read FDefaultVariables;
property CompletionValues: TStrings read FCompletionValues;
property CompletionHistory: TStrings read FCompletionHistory;
property IdleConnected: TIdleActions read FIdleConnected write SetIdleConnected;
property IdleConnected: Boolean read FIdleConnected write SetIdleConnected;
property OptionsReader: TCompilerOptReader read FOptionsReader;
end;
@ -124,6 +122,7 @@ begin
AllOpts := TfrmAllCompilerOptions.Create(Nil);
try
AllOpts.OptionsReader := FOptionsReader;
AllOpts.OptionsThread := FOptionsThread;
AllOpts.cbUseComments.Checked := FUseComments;
if AllOpts.ShowModal = mrOK then
begin
@ -145,12 +144,13 @@ procedure TCompilerOtherOptionsFrame.btnDefinesClick(Sender: TObject);
var
EditForm: TCustomDefinesForm;
begin
EditForm:=TCustomDefinesForm.Create(Nil);
EditForm := TCustomDefinesForm.Create(Nil);
try
EditForm.OptionsReader:=FOptionsReader;
EditForm.OptionsReader := FOptionsReader;
EditForm.OptionsThread := FOptionsThread;
EditForm.CustomOptions := memoCustomOptions.Lines;
EditForm.DefinesCheckList.Items.Assign(Project1.CustomDefines);
EditForm.FromCustomOptions(memoCustomOptions.Lines);
if EditForm.ShowModal=mrOK then
if EditForm.ShowModal = mrOK then
begin
Project1.CustomDefines.Assign(EditForm.DefinesCheckList.Items);
// Synchronize with custom options memo
@ -167,7 +167,7 @@ end;
procedure TCompilerOtherOptionsFrame.CondSynEditChange(Sender: TObject);
begin
UpdateStatusBar;
IdleConnected := IdleConnected + [iaMessages];
IdleConnected := True;
end;
procedure TCompilerOtherOptionsFrame.CondSynEditKeyPress(Sender: TObject; var Key: char);
@ -357,8 +357,12 @@ procedure TCompilerOtherOptionsFrame.SetVisible(Value: Boolean);
begin
inherited SetVisible(Value);
// Read all compiler options when the page is shown for the first time.
if Value then
IdleConnected := IdleConnected + [iaCompilerOpts];
if Value and (FOptionsReader.RootOptGroup.CompilerOpts.Count = 0)
and not Assigned(fOptionsThread) then
begin
fOptionsThread := TCompilerOptThread.Create(FOptionsReader);
fOptionsThread.Start;
end;
end;
procedure TCompilerOtherOptionsFrame.SetStatusMessage(const AValue: string);
@ -368,11 +372,11 @@ begin
CondStatusbar.Panels[2].Text := FStatusMessage;
end;
procedure TCompilerOtherOptionsFrame.SetIdleConnected(AValue: TIdleActions);
procedure TCompilerOtherOptionsFrame.SetIdleConnected(AValue: Boolean);
begin
if FIdleConnected=AValue then exit;
FIdleConnected:=AValue;
if FIdleConnected <> [] then
if FIdleConnected then
Application.AddOnIdleHandler(@OnIdle)
else
Application.RemoveOnIdleHandler(@OnIdle);
@ -620,47 +624,9 @@ begin
end;
procedure TCompilerOtherOptionsFrame.OnIdle(Sender: TObject; var Done: Boolean);
var
OldIdleConnected: TIdleActions;
{$IFDEF TimeAllCompilerOptions}
StartTime, EndTime: TDateTime;
fs: TFormatSettings;
ms: String;
{$ENDIF}
begin
OldIdleConnected := IdleConnected;
IdleConnected := [];
// Messages
if iaMessages in OldIdleConnected then
IdleConnected := False;
UpdateMessages;
// Read all compiler options only once
if (iaCompilerOpts in OldIdleConnected)
and (FOptionsReader.RootOptGroup.CompilerOpts.Count = 0) then
begin
{$IFDEF TimeAllCompilerOptions}
StartTime := Now;
{$ENDIF}
Screen.Cursor := crHourGlass;
try
try
FOptionsReader.CompilerExecutable := EnvironmentOptions.GetParsedCompilerFilename;
if FOptionsReader.ReadAndParseOptions <> mrOK then
ShowMessage(FOptionsReader.ErrorMsg);
except
on E: Exception do
ShowMessage('Error parsing options: '+E.Message);
end;
finally
Screen.Cursor := crDefault;
end;
{$IFDEF TimeAllCompilerOptions}
EndTime := Now-StartTime;
ms := FormatDateTime('zzz', EndTime);
fs.TimeSeparator := ':';
ShowMessage(Format('Reading compiler options took: %s.%s',
[FormatDateTime('nn:ss', EndTime, fs), ms]));
{$ENDIF}
end;
end;
constructor TCompilerOtherOptionsFrame.Create(TheOwner: TComponent);
@ -692,6 +658,7 @@ end;
destructor TCompilerOtherOptionsFrame.Destroy;
begin
FreeAndNil(fOptionsThread);
FreeAndNil(FOptionsReader);
FreeAndNil(FCompletionHistory);
FreeAndNil(FCompletionValues);