optimized entities-connection performances at startup

This commit is contained in:
Basile Burg 2014-12-09 04:54:51 +01:00
parent dce827ef65
commit 4e15bdcd15
12 changed files with 49 additions and 27 deletions

View File

@ -296,7 +296,7 @@
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<UnitName Value="ce_staticexplorer"/> <UnitName Value="ce_staticexplorer"/>
</Unit23> </Unit23>
<Unit24> <Unit24>
<Filename Value="..\src\ce_staticmacro.pas"/> <Filename Value="..\src\ce_staticmacro.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="ce_staticmacro"/> <UnitName Value="ce_staticmacro"/>

View File

@ -6,8 +6,8 @@ uses
{$IFDEF UNIX}{$IFDEF UseCThreads} {$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads, cthreads,
{$ENDIF}{$ENDIF} {$ENDIF}{$ENDIF}
Interfaces, Forms, lazcontrols, runtimetypeinfocontrols, ce_libman, ce_tools, Interfaces, Forms, lazcontrols, runtimetypeinfocontrols, ce_observer, ce_libman,
ce_dcd, ce_observer, ce_main, ce_writableComponent, ce_options, ce_symstring, ce_tools, ce_dcd, ce_main, ce_writableComponent, ce_options, ce_symstring,
ce_staticmacro; ce_staticmacro;
{$R *.res} {$R *.res}

View File

@ -55,10 +55,7 @@ begin
inherited; inherited;
Enabled := exeInSysPath('cdb'); Enabled := exeInSysPath('cdb');
if Enabled then if Enabled then
begin
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
EntitiesConnector.endUpdate;
end;
end; end;
destructor TCECdbWidget.destroy; destructor TCECdbWidget.destroy;

View File

@ -90,7 +90,6 @@ begin
end; end;
// //
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
EntitiesConnector.endUpdate;
end; end;
destructor TCEEditorWidget.destroy; destructor TCEEditorWidget.destroy;

View File

@ -152,7 +152,6 @@ begin
btnClearCat.OnClick := @actClearCurCatExecute; btnClearCat.OnClick := @actClearCurCatExecute;
// //
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
EntitiesConnector.endUpdate;
end; end;
destructor TCEMessagesWidget.destroy; destructor TCEMessagesWidget.destroy;

View File

@ -16,18 +16,26 @@ type
private private
fObservers: TObjectList; fObservers: TObjectList;
fSubjects: TObjectList; fSubjects: TObjectList;
fUpdating: boolean; fUpdatesCount: Integer;
procedure tryUpdate;
procedure updateEntities; procedure updateEntities;
function getIsUpdating: boolean;
public public
constructor create; constructor create;
destructor destroy; override; destructor destroy; override;
// // forces the update, fixes begin/add pair error or if immediate update is needed.
procedure forceUpdate;
// entities will be added in bulk, must be followed by an enUpdate().
procedure beginUpdate; procedure beginUpdate;
// entities has ben added in bulk
procedure endUpdate; procedure endUpdate;
// add/remove entities, update is automatic
procedure addObserver(anObserver: TObject); procedure addObserver(anObserver: TObject);
procedure addSubject(aSubject: TObject); procedure addSubject(aSubject: TObject);
procedure removeObserver(anObserver: TObject); procedure removeObserver(anObserver: TObject);
procedure removeSubject(aSubject: TObject); procedure removeSubject(aSubject: TObject);
// should be tested before forceUpdate()
property isUpdating: boolean read getIsUpdating;
end; end;
(** (**
@ -71,6 +79,9 @@ var
implementation implementation
uses
LCLProc;
{$REGION TCEEntitiesConnector --------------------------------------------------} {$REGION TCEEntitiesConnector --------------------------------------------------}
constructor TCEEntitiesConnector.create; constructor TCEEntitiesConnector.create;
begin begin
@ -85,11 +96,33 @@ begin
inherited; inherited;
end; end;
function TCEEntitiesConnector.getIsUpdating: boolean;
begin
exit(fUpdatesCount > 0);
end;
procedure TCEEntitiesConnector.tryUpdate;
begin
{$IFDEF DEBUG}
if fUpdatesCount > 0 then
DebugLn('saved uselless update in TCEEntitiesConnector')
else
DebugLn('efficient update in TCEEntitiesConnector');
{$ENDIF}
if fUpdatesCount <= 0 then
updateEntities;
end;
procedure TCEEntitiesConnector.forceUpdate;
begin
updateEntities;
end;
procedure TCEEntitiesConnector.updateEntities; procedure TCEEntitiesConnector.updateEntities;
var var
i,j: Integer; i,j: Integer;
begin begin
fUpdating := false; fUpdatesCount := 0;
for i := 0 to fSubjects.Count-1 do for i := 0 to fSubjects.Count-1 do
begin begin
if not (fSubjects[i] is ICESubject) then if not (fSubjects[i] is ICESubject) then
@ -104,20 +137,21 @@ end;
procedure TCEEntitiesConnector.beginUpdate; procedure TCEEntitiesConnector.beginUpdate;
begin begin
fUpdating := true; fUpdatesCount += 1;
end; end;
procedure TCEEntitiesConnector.endUpdate; procedure TCEEntitiesConnector.endUpdate;
begin begin
updateEntities; fUpdatesCount -= 1;
tryUpdate;
end; end;
procedure TCEEntitiesConnector.addObserver(anObserver: TObject); procedure TCEEntitiesConnector.addObserver(anObserver: TObject);
begin begin
if fObservers.IndexOf(anObserver) <> -1 then if fObservers.IndexOf(anObserver) <> -1 then
exit; exit;
fUpdating := true;
fObservers.Add(anObserver); fObservers.Add(anObserver);
tryUpdate;
end; end;
procedure TCEEntitiesConnector.addSubject(aSubject: TObject); procedure TCEEntitiesConnector.addSubject(aSubject: TObject);
@ -126,25 +160,25 @@ begin
exit; exit;
if fSubjects.IndexOf(aSubject) <> -1 then if fSubjects.IndexOf(aSubject) <> -1 then
exit; exit;
fUpdating := true;
fSubjects.Add(aSubject); fSubjects.Add(aSubject);
tryUpdate;
end; end;
procedure TCEEntitiesConnector.removeObserver(anObserver: TObject); procedure TCEEntitiesConnector.removeObserver(anObserver: TObject);
var var
i: Integer; i: Integer;
begin begin
fUpdating := true;
fObservers.Remove(anObserver); fObservers.Remove(anObserver);
for i := 0 to fSubjects.Count-1 do for i := 0 to fSubjects.Count-1 do
if fSubjects[i] <> nil then if fSubjects[i] <> nil then
(fSubjects[i] as ICESubject).removeObserver(anObserver); (fSubjects[i] as ICESubject).removeObserver(anObserver);
tryUpdate;
end; end;
procedure TCEEntitiesConnector.removeSubject(aSubject: TObject); procedure TCEEntitiesConnector.removeSubject(aSubject: TObject);
begin begin
fUpdating := true;
fSubjects.Remove(aSubject); fSubjects.Remove(aSubject);
tryUpdate;
end; end;
{$ENDREGION} {$ENDREGION}
@ -153,13 +187,11 @@ constructor TCECustomSubject.create;
begin begin
fObservers := TObjectList.create(false); fObservers := TObjectList.create(false);
EntitiesConnector.addSubject(Self); EntitiesConnector.addSubject(Self);
EntitiesConnector.endUpdate;
end; end;
destructor TCECustomSubject.destroy; destructor TCECustomSubject.destroy;
begin begin
EntitiesConnector.removeSubject(Self); EntitiesConnector.removeSubject(Self);
EntitiesConnector.endUpdate;
fObservers.Free; fObservers.Free;
Inherited; Inherited;
end; end;
@ -200,6 +232,7 @@ end;
initialization initialization
EntitiesConnector := TCEEntitiesConnector.create; EntitiesConnector := TCEEntitiesConnector.create;
EntitiesConnector.beginUpdate;
finalization finalization
EntitiesConnector.Free; EntitiesConnector.Free;
EntitiesConnector := nil; EntitiesConnector := nil;

View File

@ -53,7 +53,6 @@ begin
Grid.OnEditorFilter := @GridFilter; Grid.OnEditorFilter := @GridFilter;
// //
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
EntitiesConnector.endUpdate;
end; end;
destructor TCEProjectConfigurationWidget.destroy; destructor TCEProjectConfigurationWidget.destroy;

View File

@ -83,7 +83,6 @@ begin
Tree.PopupMenu := contextMenu; Tree.PopupMenu := contextMenu;
// //
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
EntitiesConnector.endUpdate;
end; end;
destructor TCEProjectInspectWidget.destroy; destructor TCEProjectInspectWidget.destroy;

View File

@ -92,7 +92,6 @@ begin
fReplaceMru:= TMruList.Create; fReplaceMru:= TMruList.Create;
// //
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
EntitiesConnector.endUpdate;
end; end;
destructor TCESearchWidget.Destroy; destructor TCESearchWidget.Destroy;

View File

@ -86,7 +86,7 @@ type
implementation implementation
{$R *.lfm} {$R *.lfm}
uses ce_libman, ce_symstring; uses LCLProc, ce_libman, ce_symstring;
{$REGION Standard Comp/Obj------------------------------------------------------} {$REGION Standard Comp/Obj------------------------------------------------------}
constructor TCEStaticExplorerWidget.create(aOwner: TComponent); constructor TCEStaticExplorerWidget.create(aOwner: TComponent);
@ -138,7 +138,6 @@ begin
Tree.PopupMenu := contextMenu; Tree.PopupMenu := contextMenu;
// //
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
EntitiesConnector.endUpdate;
end; end;
destructor TCEStaticExplorerWidget.destroy; destructor TCEStaticExplorerWidget.destroy;
@ -513,7 +512,7 @@ begin
if ndCat = nil then if ndCat = nil then
begin begin
{$IFDEF DEBUG} {$IFDEF DEBUG}
writeln(memb.Items[i].GetPath('kind').AsString); DebugLn(memb.Items[i].GetPath('kind').AsString);
{$ENDIF} {$ENDIF}
continue; continue;
end; end;

View File

@ -89,7 +89,6 @@ begin
updateCompletor; updateCompletor;
// //
EntitiesConnector.addObserver(Self); EntitiesConnector.addObserver(Self);
EntitiesConnector.endUpdate;
end; end;
destructor TCEStaticEditorMacro.destroy; destructor TCEStaticEditorMacro.destroy;

View File

@ -128,7 +128,6 @@ begin
PopupMenu := contextMenu; PopupMenu := contextMenu;
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
EntitiesConnector.endUpdate;
end; end;
destructor TCEWidget.destroy; destructor TCEWidget.destroy;