FIX: the FileSource that requires singleton may also be created multiple times (FileSystem/iCloud/Stash)

1. turn GetFileSource() to virtual, and apply it in TFileView.LoadConfiguration()
2. add Address in TVfsModule, and apply it in uFileSourceUtil.ChooseFileSource()
This commit is contained in:
rich2014 2026-06-05 17:02:23 +08:00
commit 8ba4152f6d
16 changed files with 54 additions and 50 deletions

View file

@ -87,7 +87,7 @@ var
begin
Result:= False;
try
TempFileSource:= TTempFileSystemFileSource.GetFileSource;
TempFileSource:= TTempFileSystemFileSource.Create;
if bWithAll then
begin
FileName:= TempFileSource.FileSystemRoot + ExcludeFrontPathDelimiter(aFile.FullPath);

View file

@ -46,6 +46,7 @@ type
public
constructor Create; override;
destructor Destroy; override;
class function GetFileSource: IFileSource; override;
function GetWatcher: TFileSourceWatcher; override;
function GetProcessor: TFileSourceProcessor; override;
@ -75,8 +76,6 @@ type
procedure RetrieveProperties(AFile: TFile; PropertiesToSet: TFilePropertiesTypes; const AVariantProperties: array of String); override;
class function GetFileSource: IFileSystemFileSource;
function GetSupportedFileProperties: TFilePropertiesTypes; override;
function GetRetrievableFileProperties: TFilePropertiesTypes; override;
function GetOperationsTypes: TFileSourceOperationTypes; override;
@ -791,15 +790,11 @@ begin
end;
end;
class function TFileSystemFileSource.GetFileSource: IFileSystemFileSource;
var
aFileSource: IFileSource;
class function TFileSystemFileSource.GetFileSource: IFileSource;
begin
aFileSource := FileSourceManager.Find(TFileSystemFileSource, '');
if not Assigned(aFileSource) then
Result := TFileSystemFileSource.Create
else
Result := aFileSource as IFileSystemFileSource;
Result:= FileSourceManager.Find(TFileSystemFileSource, '');
if not Assigned(Result) then
Result := TFileSystemFileSource.Create;
end;
function TFileSystemFileSource.GetOperationsTypes: TFileSourceOperationTypes;

View file

@ -21,10 +21,8 @@ type
procedure AddList(var aFileList: TFileTree; aFileSource: IFileSource);
function GetFileList: TFileTree;
function GetFileSource: IFileSource;
property FileList: TFileTree read GetFileList;
property FileSource: IFileSource read GetFileSource;
end;
{en
@ -62,7 +60,6 @@ type
protected
function GetFileList: TFileTree;
function GetFileSource: IFileSource;
procedure DoReload(const PathsToReload: TPathsArray); override;
public
@ -214,11 +211,6 @@ begin
Result := FFileList;
end;
function TMultiListFileSource.GetFileSource: IFileSource;
begin
Result := FFileSource;
end;
procedure TMultiListFileSource.DoReload(const PathsToReload: TPathsArray);
procedure ReloadNode(aNode: TFileTreeNode);

View file

@ -74,12 +74,12 @@ var
procedure TSearchResultFileSourceProcessor.consultMoveOperation( var params: TFileSourceConsultParams);
var
searchResultFS: ISearchResultFileSource;
searchResultFS: TSearchResultFileSource;
begin
if params.phase<>TFileSourceConsultPhase.source then
Exit;
searchResultFS:= params.currentFS as ISearchResultFileSource;
searchResultFS:= params.currentFS as TSearchResultFileSource;
params.sourceFS:= searchResultFS.FileSource;
end;

View file

@ -38,6 +38,8 @@ type
public
constructor Create; override; overload;
destructor Destroy; override;
class function GetFileSource: IFileSource; override;
function GetLocalName(var aFile: TFile): Boolean; override;
class function GetMainIcon(out Path: String): Boolean; override;
function needReload(const PathToReload: String; const PathToCheck: String): Boolean; override;
@ -63,6 +65,9 @@ implementation
uses
uStashFileSourceOperation;
const
STASH_SCHEME = 'stash://';
var
stashFileSourceProcessor: TFileSourceProcessor;
@ -179,6 +184,7 @@ end;
constructor TStashFileSource.Create;
begin
Inherited Create;
FCurrentAddress:= STASH_SCHEME;
_fileSystemFS:= IFileSystemFileSource(FileSourceManager.Find(TFileSystemFileSource,EmptyStr));
_fileSystemFS.AddEventListener( @self.onFileSystemEvent );
end;
@ -189,6 +195,13 @@ begin
inherited Destroy;
end;
class function TStashFileSource.GetFileSource: IFileSource;
begin
Result:= FileSourceManager.Find( TStashFileSource, STASH_SCHEME );
if not Assigned(Result) then
Result:= TStashFileSource.Create;
end;
function TStashFileSource.GetLocalName(var aFile: TFile): Boolean;
begin
Result:= True;
@ -364,7 +377,7 @@ end;
initialization
stashFileSourceProcessor:= TStashFileSourceProcessor.Create;
RegisterVirtualFileSource( 'Stash', TStashFileSource, True );
RegisterVirtualFileSource( 'Stash', STASH_SCHEME, TStashFileSource, True );
finalization
FreeAndNil( stashFileSourceProcessor );

View file

@ -45,8 +45,6 @@ type
constructor Create(const aPath: String); virtual; overload;
destructor Destroy; override;
class function GetFileSource: ITempFileSystemFileSource;
function IsPathAtRoot(Path: String): Boolean; override;
function GetParentDir(sPath: String): String; override;
function GetRootDir(sPath: String): String; override; overload;
@ -115,11 +113,6 @@ begin
FDeleteOnDestroy := NewDeleteOnDestroy;
end;
class function TTempFileSystemFileSource.GetFileSource: ITempFileSystemFileSource;
begin
Result := TTempFileSystemFileSource.Create;
end;
function TTempFileSystemFileSource.GetFreeSpace(Path: String; out FreeSize, TotalSize : Int64) : Boolean;
begin
Result := GetDiskFreeSpace(FTempRootDir, FreeSize, TotalSize);

View file

@ -367,7 +367,7 @@ begin
begin
SourceFiles:= TFiles.Create(PathDelim);
SourceFiles.Add(AFiles[Index].Clone);
Temp:= TTempFileSystemFileSource.GetFileSource;
Temp:= TTempFileSystemFileSource.Create;
Operation:= FileSource.CreateCopyOutOperation(Temp, SourceFiles, Temp.GetRootDir) as TArchiveCopyOutOperation;
try

View file

@ -312,6 +312,8 @@ type
constructor Create(const URI: TURI); virtual; overload;
destructor Destroy; override;
class function GetFileSource: IFileSource; virtual;
function GetWatcher: TFileSourceWatcher; virtual;
function GetProcessor: TFileSourceProcessor; virtual;
function GetUIHandler: TFileSourceUIHandler; virtual;
@ -582,6 +584,11 @@ begin
inherited Destroy;
end;
class function TFileSource.GetFileSource: IFileSource;
begin
Result:= Create;
end;
function TFileSource.GetWatcher: TFileSourceWatcher;
begin
Result:= defaultFileSourceWatcher;

View file

@ -197,7 +197,7 @@ begin
VfsModule:= gVfsModuleList.VfsModule[aFile.Name];
if Assigned(VfsModule) then
begin
FileSource := FileSourceManager.Find(VfsModule.FileSourceClass, aFile.Name);
FileSource := FileSourceManager.Find(VfsModule.FileSourceClass, VfsModule.Address);
if not Assigned(FileSource) then
FileSource := VfsModule.FileSourceClass.Create;
end;

View file

@ -1225,7 +1225,7 @@ initialization
WfxConnectionsLock := TCriticalSection.Create;
WfxOperationsQueue := TObjectList.Create(False); // False = don't destroy operations (only store references)
WfxOperationsQueueLock := TCriticalSection.Create;
RegisterVirtualFileSource('WfxPlugin', TWfxPluginFileSource, False);
RegisterVirtualFileSource('WfxPlugin', '', TWfxPluginFileSource, False);
finalization
FreeAndNil(WfxOperationList);

View file

@ -2636,7 +2636,7 @@ begin
aFileSource := TFileSystemFileSource.GetFileSource
else begin
FileSourceClass := gVfsModuleList.FindFileSource(sFSType);
if Assigned(FileSourceClass) then aFileSource := FileSourceClass.Create;
if Assigned(FileSourceClass) then aFileSource := FileSourceClass.GetFileSource;
end;
if Assigned(aFileSource) then

View file

@ -8,7 +8,7 @@ interface
uses
Classes, SysUtils, Forms, Controls, ComCtrls, Graphics,
fOptionsFrame,
fMain, uFileSystemFileSource, uFileViewNotebook,
fMain, uFileSource, uFileSystemFileSource, uFileViewNotebook,
uiCloudDrive, uiCloudDriveConfig, uiCloudDriveUtil,
uDarwinImage,
CocoaAll;
@ -41,7 +41,7 @@ implementation
procedure TfrmOptionsiCloud.appsListViewDblClick(Sender: TObject);
var
fs: IFileSystemFileSource;
fs: IFileSource;
path: String;
notebook: TFileViewNotebook;
newPage: TFileViewPage;

View file

@ -273,7 +273,7 @@ class procedure TDarwinFileViewUtil.addiCloudDrivePage;
var
iCloudFS: TiCloudDriveFileSource;
begin
iCloudFS := TiCloudDriveFileSource.GetFileSource;
iCloudFS := TiCloudDriveFileSource.GetFileSource as TiCloudDriveFileSource;
_activeFrameFunc().AddFileSource(iCloudFS, iCloudFS.GetRootDir);
_activeFrameFunc().SetFocus;
end;

View file

@ -30,6 +30,7 @@ type
public
constructor Create; override;
destructor Destroy; override;
class function GetFileSource: IFileSource; override;
class function IsSupportedPath(const Path: String): Boolean; override;
@ -37,8 +38,6 @@ type
function getAppIconByPath( const path: String ): NSImage;
function getDefaultPointForPath( const path: String ): String; override;
public
class function GetFileSource: TiCloudDriveFileSource;
function GetWatcher: TFileSourceWatcher; override;
function GetProcessor: TFileSourceProcessor; override;
function GetUIHandler: TFileSourceUIHandler; override;
@ -229,12 +228,15 @@ end;
function TiCloudDriveWatcher.toFileSourceEvent(event: TDarwinFSWatchEvent;
var fileSourceEvent: TFSWatcherEventData ): Boolean;
var
fs: TiCloudDriveFileSource;
begin
Result:= TDarwinFSWatcherUtil.convertToFileSourceEvent( event, fileSourceEvent );
if Result = false then
Exit;
if TiCloudDriveFileSource.GetFileSource.getMountPointFromPath(event.fullPath)<>nil then begin
fs:= TiCloudDriveFileSource.GetFileSource as TiCloudDriveFileSource;
if fs.getMountPointFromPath(event.fullPath)<>nil then begin
fileSourceEvent.Path:= event.fullPath;
fileSourceEvent.FileName:= '';
end else begin
@ -253,8 +255,10 @@ var
virtualPath: String;
item: TWatcherItem;
fileSourceEvent: TFSWatcherEventData;
fs: TiCloudDriveFileSource;
begin
virtualPath:= TiCloudDriveFileSource.GetFileSource.GetVirtualPath( event.fullPath );
fs:= TiCloudDriveFileSource.GetFileSource as TiCloudDriveFileSource;
virtualPath:= fs.GetVirtualPath( event.fullPath );
virtualPath:= ExtractFilePath( ExcludeTrailingPathDelimiter(virtualPath) );
ok:= Self.toFileSourceEvent( event, fileSourceEvent );
if NOT ok then
@ -711,15 +715,11 @@ begin
Result:= TDarwinFileUtil.getDisplayName( path );
end;
class function TiCloudDriveFileSource.GetFileSource: TiCloudDriveFileSource;
var
aFileSource: IFileSource;
class function TiCloudDriveFileSource.GetFileSource: IFileSource;
begin
aFileSource := FileSourceManager.Find(TiCloudDriveFileSource, iCloudDriveConfig.scheme );
if not Assigned(aFileSource) then
Result:= TiCloudDriveFileSource.Create
else
Result:= aFileSource as TiCloudDriveFileSource;
Result:= FileSourceManager.Find( TiCloudDriveFileSource, iCloudDriveConfig.scheme );
if not Assigned(Result) then
Result:= TiCloudDriveFileSource.Create;
end;
function TiCloudDriveFileSource.GetWatcher: TFileSourceWatcher;
@ -815,7 +815,7 @@ initialization
iCloudDriveWatcher:= TiCloudDriveWatcher.Create;
iCloudDriveProcessor:= TiCloudDriveProcessor.Create;
iCloudDriveUIProcessor:= TiCloudDriveUIHandler.Create;
RegisterVirtualFileSource( 'iCloud', TiCloudDriveFileSource, True );
RegisterVirtualFileSource( 'iCloud', 'iCloud://', TiCloudDriveFileSource, True );
finalization
FreeAndNil( iCloudDriveWatcher );

View file

@ -265,7 +265,7 @@ begin
if FFileSource.IsClass(TTempFileSystemFileSource) then
TempFileSource := (FFileSource as ITempFileSystemFileSource)
else
TempFileSource := TTempFileSystemFileSource.GetFileSource;
TempFileSource := TTempFileSystemFileSource.Create;
Operation := Sender.FileSource.CreateCopyOutOperation(
TempFileSource,

View file

@ -17,6 +17,7 @@ type
TVfsModule = class
Visible: Boolean;
Address: String;
FileSourceClass: TFileSourceClass;
end;
@ -33,6 +34,7 @@ type
end;
procedure RegisterVirtualFileSource(AName: String;
AAddress: String;
AFileSourceClass: TFileSourceClass;
Visible: Boolean = True);
@ -45,6 +47,7 @@ var
implementation
procedure RegisterVirtualFileSource(AName: String;
AAddress: String;
AFileSourceClass: TFileSourceClass;
Visible: Boolean = True);
var
@ -52,6 +55,7 @@ var
begin
VfsModule:= TVfsModule.Create;
VfsModule.Visible:= Visible;
VfsModule.Address:= AAddress;
VfsModule.FileSourceClass:= AFileSourceClass;
gVfsModuleList.AddObject(AName, VfsModule);
end;