mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-17 04:29:25 +02:00
implemented sorting installed packages topologically
git-svn-id: trunk@6296 -
This commit is contained in:
parent
7bdefae9f7
commit
488aa4bca8
@ -34,7 +34,7 @@ unit CGILazIDEIntf;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, cgiApp, cgiModules, LazIDEIntf, ProjectIntf, NewItemIntf;
|
||||
Classes, SysUtils, cgiApp, cgiModules, LazIDEIntf, ProjectIntf;
|
||||
|
||||
type
|
||||
{ TCGIApplicationDescriptor }
|
||||
|
@ -325,8 +325,6 @@ begin
|
||||
end;
|
||||
|
||||
procedure TCustomGTKGLAreaControl.UpdateFrameTimeDiff;
|
||||
var
|
||||
hour, minutes, secs, msecs, usecs: word;
|
||||
begin
|
||||
FCurrentFrameTime:=GetTickCount;
|
||||
if FLastFrameTime=0 then
|
||||
|
@ -2012,7 +2012,7 @@ var
|
||||
ASrcEdit: TSourceEditor;
|
||||
AnUnitInfo: TUnitInfo;
|
||||
begin
|
||||
debugln('TDebugManager.OnProcessIDECommand ',dbgs(Command));
|
||||
//debugln('TMainIDE.OnProcessIDECommand ',dbgs(Command));
|
||||
|
||||
Handled:=true;
|
||||
|
||||
@ -10965,6 +10965,9 @@ end.
|
||||
|
||||
{ =============================================================================
|
||||
$Log$
|
||||
Revision 1.799 2004/11/25 22:05:00 mattias
|
||||
implemented sorting installed packages topologically
|
||||
|
||||
Revision 1.798 2004/11/24 08:18:13 mattias
|
||||
TTextStrings improvements (Exchange, Put), clean ups
|
||||
|
||||
|
@ -216,6 +216,12 @@ type
|
||||
);
|
||||
TPkgDependencyFlags = set of TPkgDependencyFlag;
|
||||
|
||||
TPkgMarkerFlag = (
|
||||
pmfVisited,
|
||||
pmfMarked
|
||||
);
|
||||
TPkgMarkerFlags = set of TPkgMarkerFlag;
|
||||
|
||||
TLoadPackageResult = (
|
||||
lprUndefined,
|
||||
lprSuccess,
|
||||
@ -233,6 +239,7 @@ type
|
||||
FFlags: TPkgDependencyFlags;
|
||||
FHoldPackage: boolean;
|
||||
FLoadPackageResult: TLoadPackageResult;
|
||||
FMarkerFlags: TPKgMarkerFlags;
|
||||
FOwner: TObject;
|
||||
FMaxVersion: TPkgVersion;
|
||||
FMinVersion: TPkgVersion;
|
||||
@ -287,6 +294,7 @@ type
|
||||
property RequiredPackage: TLazPackage read FRequiredPackage write SetRequiredPackage;
|
||||
property LoadPackageResult: TLoadPackageResult read FLoadPackageResult write SetLoadPackageResult;
|
||||
property HoldPackage: boolean read FHoldPackage write SetHoldPackage;
|
||||
property MarkerFlags: TPKgMarkerFlags read FMarkerFlags write FMarkerFlags;
|
||||
end;
|
||||
PPkgDependency = ^TPkgDependency;
|
||||
|
||||
@ -550,6 +558,7 @@ type
|
||||
FRegistered: boolean;
|
||||
FSourceDirectories: TFileReferenceList;
|
||||
FStateFileDate: longint;
|
||||
FTopologicalLevel: integer;
|
||||
FUpdateLock: integer;
|
||||
FUsageOptions: TPkgAdditionalCompilerOptions;
|
||||
FUserReadOnly: boolean;
|
||||
@ -721,6 +730,7 @@ type
|
||||
property RemovedFiles[Index: integer]: TPkgFile read GetRemovedFiles;
|
||||
property SourceDirectories: TFileReferenceList read FSourceDirectories;
|
||||
property StateFileDate: longint read FStateFileDate write FStateFileDate;
|
||||
property TopologicalLevel: integer read FTopologicalLevel write FTopologicalLevel;
|
||||
property UsageOptions: TPkgAdditionalCompilerOptions read FUsageOptions;
|
||||
property UserReadOnly: boolean read FUserReadOnly write SetUserReadOnly;
|
||||
end;
|
||||
|
@ -179,6 +179,9 @@ type
|
||||
Policies: TPackageUpdatePolicies): TList;
|
||||
function GetBrokenDependenciesWhenChangingPkgID(APackage: TLazPackage;
|
||||
const NewName: string; NewVersion: TPkgVersion): TList;
|
||||
procedure CalculateTopologicalLevels;
|
||||
procedure SortDependencyListTopologically(
|
||||
var FirstDependency: TPkgDependency; TopLevelFirst: boolean);
|
||||
procedure IterateAllComponentClasses(Event: TIterateComponentClassesEvent);
|
||||
procedure IterateComponentClasses(APackage: TLazPackage;
|
||||
Event: TIterateComponentClassesEvent;
|
||||
@ -188,6 +191,8 @@ type
|
||||
procedure IteratePackagesSorted(Flags: TFindPackageFlags;
|
||||
Event: TIteratePackagesEvent);
|
||||
procedure MarkAllPackagesAsNotVisited;
|
||||
procedure MarkAllDependencies(MarkPackages: boolean;
|
||||
AddMarkerFlags, RemoveMarkerFlags: TPkgMarkerFlags);
|
||||
procedure MarkAllRequiredPackages(FirstDependency: TPkgDependency);
|
||||
procedure MarkNeededPackages;
|
||||
procedure ConsistencyCheck;
|
||||
@ -1020,7 +1025,7 @@ begin
|
||||
Filename:=SetDirSeparators('$(LazarusDir)/ideintf/');
|
||||
Version.SetValues(1,0,0,0);
|
||||
Author:='Lazarus';
|
||||
License:='GPL-2';
|
||||
License:='LGPL-2';
|
||||
AutoInstall:=pitStatic;
|
||||
AutoUpdate:=pupManually;
|
||||
Description:='IDEIntf - the interface units for the IDE';
|
||||
@ -1042,6 +1047,7 @@ begin
|
||||
AddFile('idecommands.pas','IDECommands',pftUnit,[],cpBase);
|
||||
AddFile('imagelisteditor.pp','ImageListEditor',pftUnit,[],cpBase);
|
||||
AddFile('listviewpropedit.pp','ListViewPropEdit',pftUnit,[],cpBase);
|
||||
AddFile('newitemintf.pas','NewItemIntf',pftUnit,[],cpBase);
|
||||
AddFile('objectinspector.pp','ObjectInspector',pftUnit,[],cpBase);
|
||||
AddFile('objinspstrconsts.pas','ObjInspStrConsts',pftUnit,[],cpBase);
|
||||
AddFile('packageintf.pas','PackageIntf',pftUnit,[],cpBase);
|
||||
@ -1753,6 +1759,27 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazPackageGraph.MarkAllDependencies(
|
||||
MarkPackages: boolean; AddMarkerFlags, RemoveMarkerFlags: TPkgMarkerFlags);
|
||||
var
|
||||
i: Integer;
|
||||
Pkg: TLazPackage;
|
||||
Dependency: TPkgDependency;
|
||||
begin
|
||||
// mark all dependencies of all packages as not visited
|
||||
for i:=FItems.Count-1 downto 0 do begin
|
||||
Pkg:=TLazPackage(FItems[i]);
|
||||
if MarkPackages then
|
||||
Pkg.Flags:=Pkg.Flags-[lpfVisited];
|
||||
Dependency:=Pkg.FirstRequiredDependency;
|
||||
while Dependency<>nil do begin
|
||||
Dependency.MarkerFlags:=
|
||||
Dependency.MarkerFlags+AddMarkerFlags-RemoveMarkerFlags;
|
||||
Dependency:=Dependency.NextRequiresDependency;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazPackageGraph.MarkAllRequiredPackages(
|
||||
FirstDependency: TPkgDependency);
|
||||
var
|
||||
@ -1850,11 +1877,153 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazPackageGraph.CalculateTopologicalLevels;
|
||||
|
||||
procedure GetTopologicalOrder(CurDependency: TPkgDependency;
|
||||
var MaxChildLevel: integer);
|
||||
var
|
||||
RequiredPackage: TLazPackage;
|
||||
CurMaxChildLevel: integer;
|
||||
begin
|
||||
MaxChildLevel:=0;
|
||||
while CurDependency<>nil do begin
|
||||
if CurDependency.LoadPackageResult=lprSuccess then begin
|
||||
RequiredPackage:=CurDependency.RequiredPackage;
|
||||
if (not (lpfVisited in RequiredPackage.Flags)) then begin
|
||||
RequiredPackage.Flags:=RequiredPackage.Flags+[lpfVisited];
|
||||
GetTopologicalOrder(RequiredPackage.FirstRequiredDependency,
|
||||
CurMaxChildLevel);
|
||||
RequiredPackage.TopologicalLevel:=CurMaxChildLevel+1;
|
||||
end;
|
||||
if RequiredPackage.TopologicalLevel>MaxChildLevel then
|
||||
MaxChildLevel:=RequiredPackage.TopologicalLevel;
|
||||
end;
|
||||
CurDependency:=CurDependency.NextRequiresDependency;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
i: Integer;
|
||||
Pkg: TLazPackage;
|
||||
CurMaxChildLevel: integer;
|
||||
begin
|
||||
for i:=FItems.Count-1 downto 0 do begin
|
||||
Pkg:=TLazPackage(FItems[i]);
|
||||
Pkg.Flags:=Pkg.Flags-[lpfVisited];
|
||||
Pkg.TopologicalLevel:=0;
|
||||
end;
|
||||
for i:=FItems.Count-1 downto 0 do begin
|
||||
Pkg:=TLazPackage(FItems[i]);
|
||||
GetTopologicalOrder(Pkg.FirstRequiredDependency,CurMaxChildLevel);
|
||||
Pkg.TopologicalLevel:=CurMaxChildLevel+1;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazPackageGraph.SortDependencyListTopologically(
|
||||
var FirstDependency: TPkgDependency; TopLevelFirst: boolean);
|
||||
// Sort dependency list topologically.
|
||||
// If TopLevelFirst is true then packages that needs others come first
|
||||
var
|
||||
Dependency: TPkgDependency;
|
||||
BucketStarts: PInteger;
|
||||
MaxLvl: Integer;
|
||||
BucketCount: Integer;
|
||||
DependencyCount: Integer;
|
||||
Dependencies: PPkgDependency;
|
||||
i: Integer;
|
||||
j: Integer;
|
||||
CurLvl: LongInt;
|
||||
begin
|
||||
CalculateTopologicalLevels;
|
||||
|
||||
// Bucket sort dependencies
|
||||
MaxLvl:=0;
|
||||
Dependency:=FirstDependency;
|
||||
DependencyCount:=0;
|
||||
while Dependency<>nil do begin
|
||||
if Dependency.RequiredPackage<>nil then begin
|
||||
if MaxLvl<Dependency.RequiredPackage.TopologicalLevel then
|
||||
MaxLvl:=Dependency.RequiredPackage.TopologicalLevel;
|
||||
end;
|
||||
Dependency:=Dependency.NextRequiresDependency;
|
||||
inc(DependencyCount);
|
||||
end;
|
||||
if (MaxLvl=0) or (DependencyCount<=1) then exit;
|
||||
|
||||
//debugln('TLazPackageGraph.SortDependencyListTopologically A MaxLvl=',dbgs(MaxLvl),' ',dbgs(DependencyCount));
|
||||
// compute BucketStarts
|
||||
BucketCount:=MaxLvl+1;
|
||||
GetMem(BucketStarts,SizeOf(Integer)*BucketCount);
|
||||
FillChar(BucketStarts^,SizeOf(Integer)*BucketCount,0);
|
||||
Dependency:=FirstDependency;
|
||||
while Dependency<>nil do begin
|
||||
if Dependency.RequiredPackage<>nil then
|
||||
CurLvl:=Dependency.RequiredPackage.TopologicalLevel
|
||||
else
|
||||
CurLvl:=0;
|
||||
if CurLvl+1<BucketCount then
|
||||
inc(BucketStarts[CurLvl+1]);
|
||||
Dependency:=Dependency.NextRequiresDependency;
|
||||
end;
|
||||
for i:=2 to MaxLvl do
|
||||
BucketStarts[i]:=BucketStarts[i]+BucketStarts[i-1];
|
||||
BucketStarts[0]:=0;
|
||||
|
||||
// put Dependencies into buckets
|
||||
GetMem(Dependencies,SizeOf(Pointer)*DependencyCount);
|
||||
FillChar(Dependencies^,SizeOf(Pointer)*DependencyCount,0);
|
||||
Dependency:=FirstDependency;
|
||||
while Dependency<>nil do begin
|
||||
if Dependency.RequiredPackage<>nil then
|
||||
CurLvl:=Dependency.RequiredPackage.TopologicalLevel
|
||||
else
|
||||
CurLvl:=0;
|
||||
//debugln('BBB1 BucketStarts[',dbgs(CurLvl),']=',dbgs(BucketStarts[CurLvl]),' ',Dependency.AsString);
|
||||
if Dependencies[BucketStarts[CurLvl]]<>nil then
|
||||
RaiseException('');
|
||||
Dependencies[BucketStarts[CurLvl]]:=Dependency;
|
||||
inc(BucketStarts[CurLvl]);
|
||||
Dependency:=Dependency.NextRequiresDependency;
|
||||
end;
|
||||
|
||||
// optional: reverse order
|
||||
if TopLevelFirst then begin
|
||||
i:=0;
|
||||
j:=DependencyCount-1;
|
||||
while (i<j) do begin
|
||||
Dependency:=Dependencies[i];
|
||||
Dependencies[i]:=Dependencies[j];
|
||||
Dependencies[j]:=Dependency;
|
||||
inc(i);
|
||||
dec(j);
|
||||
end;
|
||||
end;
|
||||
|
||||
// commit order
|
||||
FirstDependency:=Dependencies[0];
|
||||
for i:=0 to DependencyCount-1 do begin
|
||||
Dependency:=Dependencies[i];
|
||||
//debugln('TLazPackageGraph.SortDependencyListTopologically A ',Dependency.AsString);
|
||||
if i=0 then
|
||||
Dependency.PrevDependency[pdlRequires]:=nil
|
||||
else
|
||||
Dependency.PrevDependency[pdlRequires]:=Dependencies[i-1];
|
||||
if i=DependencyCount-1 then
|
||||
Dependency.NextDependency[pdlRequires]:=nil
|
||||
else
|
||||
Dependency.NextDependency[pdlRequires]:=Dependencies[i+1];
|
||||
end;
|
||||
|
||||
// clean up
|
||||
FreeMem(BucketStarts);
|
||||
FreeMem(Dependencies);
|
||||
end;
|
||||
|
||||
function TLazPackageGraph.CheckIfPackageCanBeClosed(APackage: TLazPackage
|
||||
): boolean;
|
||||
begin
|
||||
MarkNeededPackages;
|
||||
Result:=lpfNeeded in APackage.FLags;
|
||||
Result:=lpfNeeded in APackage.Flags;
|
||||
end;
|
||||
|
||||
function TLazPackageGraph.PackageIsNeeded(APackage: TLazPackage): boolean;
|
||||
|
@ -162,6 +162,7 @@ type
|
||||
procedure LoadStaticCustomPackages;
|
||||
function LoadInstalledPackage(const PackageName: string): TLazPackage;
|
||||
procedure LoadAutoInstallPackages;
|
||||
procedure SortAutoInstallDependencies;
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
@ -1434,8 +1435,6 @@ begin
|
||||
MiscellaneousOptions.BuildLazOpts.WithStaticPackages:=true;
|
||||
end;
|
||||
|
||||
// TODO: sort FirstAutoInstallDependency topological
|
||||
|
||||
sl:=TStringList.Create;
|
||||
Dependency:=FirstAutoInstallDependency;
|
||||
while Dependency<>nil do begin
|
||||
@ -1469,7 +1468,7 @@ begin
|
||||
PackageGraph.OpenDependency(Dependency);
|
||||
Dependency.AddToList(FirstAutoInstallDependency,pdlRequires);
|
||||
end;
|
||||
// TODO: sort FirstAutoInstallDependency topological
|
||||
SortAutoInstallDependencies;
|
||||
|
||||
// register them
|
||||
PackageGraph.RegisterStaticBasePackages;
|
||||
@ -1551,6 +1550,14 @@ begin
|
||||
end;
|
||||
Dependency.RequiredPackage.AutoInstall:=pitStatic;
|
||||
end;
|
||||
SortAutoInstallDependencies;
|
||||
end;
|
||||
|
||||
procedure TPkgManager.SortAutoInstallDependencies;
|
||||
begin
|
||||
// sort install dependencies, so that lower packages come first
|
||||
PackageGraph.SortDependencyListTopologically(FirstAutoInstallDependency,
|
||||
false);
|
||||
end;
|
||||
|
||||
constructor TPkgManager.Create(TheOwner: TComponent);
|
||||
@ -3087,9 +3094,10 @@ begin
|
||||
NeedSaving:=true;
|
||||
end;
|
||||
end;
|
||||
// TODO: sort FirstAutoInstallDependency topological
|
||||
if NeedSaving then
|
||||
if NeedSaving then begin
|
||||
SortAutoInstallDependencies;
|
||||
SaveAutoInstallDependencies(true);
|
||||
end;
|
||||
|
||||
// save IDE build configs, so user can build IDE on command line
|
||||
BuildIDEFlags:=[blfWithStaticPackages,blfQuick,blfOnlyIDE];
|
||||
@ -3160,6 +3168,7 @@ begin
|
||||
if Dependency<>nil then begin
|
||||
Dependency.RemoveFromList(FirstAutoInstallDependency,pdlRequires);
|
||||
Dependency.Free;
|
||||
SortAutoInstallDependencies;
|
||||
end;
|
||||
SaveAutoInstallDependencies(true);
|
||||
end;
|
||||
@ -3215,6 +3224,7 @@ begin
|
||||
if Result<>mrYes then exit;
|
||||
OldDependency.RemoveFromList(FirstAutoInstallDependency,pdlRequires);
|
||||
OldDependency.Free;
|
||||
SaveAutoInstallDependencies(true);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user