UPD: refactoring common watcher related from uiCloudDrive to uDarwinDC

(cherry picked from commit f3254ee10b)
This commit is contained in:
rich2014 2025-12-20 18:27:06 +08:00 committed by Alexander Koblov
commit 4304e2ca9f
3 changed files with 86 additions and 55 deletions

View file

@ -332,7 +332,7 @@ end;"/>
<PackageName Value="Image32"/>
</Item13>
</RequiredPackages>
<Units Count="296">
<Units Count="297">
<Unit0>
<Filename Value="doublecmd.lpr"/>
<IsPartOfProject Value="True"/>
@ -2144,6 +2144,11 @@ end;"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uDarwinPanel"/>
</Unit295>
<Unit296>
<Filename Value="platform\unix\darwin\udarwindc.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uDarwinDC"/>
</Unit296>
</Units>
</ProjectOptions>
<CompilerOptions>

View file

@ -0,0 +1,78 @@
unit uDarwinDC;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils,
uGlobs,
uFileSourceWatcher,
uDarwinFSWatch;
type
{ TDarwinFSWatcherUtil }
TDarwinFSWatcherUtil = class
class function convertToFileSourceEvent(
const event: TDarwinFSWatchEvent;
var fileSourceEvent: TFSWatcherEventData ): Boolean;
end;
implementation
{ TDarwinFSWatcherUtil }
class function TDarwinFSWatcherUtil.convertToFileSourceEvent(
const event: TDarwinFSWatchEvent;
var fileSourceEvent: TFSWatcherEventData ): Boolean;
begin
Result:= False;
if [watch_file_name_change, watch_attributes_change] * gWatchDirs = [] then exit;
if event.isDropabled then exit;
/// if (ecChildChanged in event.categories) and (not isWatchSubdir(event.watchPath) ) then exit;
fileSourceEvent.Path := event.watchPath;
fileSourceEvent.FileName := EmptyStr;
fileSourceEvent.NewFileName := EmptyStr;
fileSourceEvent.OriginalEvent := event;
fileSourceEvent.EventType := fswUnknownChange;
if TDarwinFSWatchEventCategory.ecRootChanged in event.categories then begin
fileSourceEvent.EventType := fswSelfDeleted;
end else if event.fullPath.Length >= event.watchPath.Length+2 then begin
// 1. file-level update only valid if there is a FileName,
// otherwise keep directory-level update
// 2. the order of the following judgment conditions must be preserved
if (not (watch_file_name_change in gWatchDirs)) and
([ecStructChanged, ecAttribChanged] * event.categories = [ecStructChanged])
then exit;
if (not (watch_attributes_change in gWatchDirs)) and
([ecStructChanged, ecAttribChanged] * event.categories = [ecAttribChanged])
then exit;
fileSourceEvent.FileName := ExtractFileName( event.fullPath );
if TDarwinFSWatchEventCategory.ecRemoved in event.categories then
fileSourceEvent.EventType := fswFileDeleted
else if TDarwinFSWatchEventCategory.ecRenamed in event.categories then begin
if ExtractFilePath(event.fullPath)=ExtractFilePath(event.renamedPath) then begin
// fswFileRenamed only when FileName and NewFileName in the same dir
// otherwise keep fswUnknownChange
fileSourceEvent.EventType := fswFileRenamed;
fileSourceEvent.NewFileName := ExtractFileName( event.renamedPath );
end;
end else if TDarwinFSWatchEventCategory.ecCreated in event.categories then
fileSourceEvent.EventType := fswFileCreated
else if TDarwinFSWatchEventCategory.ecAttribChanged in event.categories then
fileSourceEvent.EventType := fswFileChanged
else
exit;
end;
Result:= True;
end;
end.

View file

@ -13,7 +13,7 @@ uses
uFileSource, uFileSourceOperationTypes, uFileSourceManager,
uFileSourceWatcher, uMountedFileSource, uVfsModule,
uDCUtils, uLng, uGlobs,
uDarwinFSWatch, uDarwinSimpleFSWatch,
uDarwinFSWatch, uDarwinSimpleFSWatch, uDarwinDC,
uDarwinFile, uDarwinImage,
CocoaAll, CocoaUtils, CocoaThemes;
@ -80,8 +80,6 @@ type
procedure destroyWatcher;
function findWatch(const path: String; const event: TFSWatcherEvent): Integer;
private
function toFileSourceEventCommon( event: TDarwinFSWatchEvent;
var fileSourceEvent: TFSWatcherEventData ): Boolean;
function toFileSourceEvent( event: TDarwinFSWatchEvent;
var fileSourceEvent: TFSWatcherEventData ): Boolean;
procedure handleEventInMainThread;
@ -222,60 +220,10 @@ begin
end;
end;
// todo: refactor with TFileSystemWatcherImpl.handleFSEvent(event:TDarwinFSWatchEvent);
function TiCloudDriveWatcher.toFileSourceEventCommon(event: TDarwinFSWatchEvent;
var fileSourceEvent: TFSWatcherEventData ): Boolean;
begin
Result:= False;
if [watch_file_name_change, watch_attributes_change] * gWatchDirs = [] then exit;
if event.isDropabled then exit;
/// if (ecChildChanged in event.categories) and (not isWatchSubdir(event.watchPath) ) then exit;
fileSourceEvent.Path := event.watchPath;
fileSourceEvent.FileName := EmptyStr;
fileSourceEvent.NewFileName := EmptyStr;
fileSourceEvent.OriginalEvent := event;
fileSourceEvent.EventType := fswUnknownChange;
if TDarwinFSWatchEventCategory.ecRootChanged in event.categories then begin
fileSourceEvent.EventType := fswSelfDeleted;
end else if event.fullPath.Length >= event.watchPath.Length+2 then begin
// 1. file-level update only valid if there is a FileName,
// otherwise keep directory-level update
// 2. the order of the following judgment conditions must be preserved
if (not (watch_file_name_change in gWatchDirs)) and
([ecStructChanged, ecAttribChanged] * event.categories = [ecStructChanged])
then exit;
if (not (watch_attributes_change in gWatchDirs)) and
([ecStructChanged, ecAttribChanged] * event.categories = [ecAttribChanged])
then exit;
fileSourceEvent.FileName := ExtractFileName( event.fullPath );
if TDarwinFSWatchEventCategory.ecRemoved in event.categories then
fileSourceEvent.EventType := fswFileDeleted
else if TDarwinFSWatchEventCategory.ecRenamed in event.categories then begin
if ExtractFilePath(event.fullPath)=ExtractFilePath(event.renamedPath) then begin
// fswFileRenamed only when FileName and NewFileName in the same dir
// otherwise keep fswUnknownChange
fileSourceEvent.EventType := fswFileRenamed;
fileSourceEvent.NewFileName := ExtractFileName( event.renamedPath );
end;
end else if TDarwinFSWatchEventCategory.ecCreated in event.categories then
fileSourceEvent.EventType := fswFileCreated
else if TDarwinFSWatchEventCategory.ecAttribChanged in event.categories then
fileSourceEvent.EventType := fswFileChanged
else
exit;
end;
Result:= True;
end;
function TiCloudDriveWatcher.toFileSourceEvent(event: TDarwinFSWatchEvent;
var fileSourceEvent: TFSWatcherEventData ): Boolean;
begin
Result:= Self.toFileSourceEventCommon( event, fileSourceEvent );
Result:= TDarwinFSWatcherUtil.convertToFileSourceEvent( event, fileSourceEvent );
if Result = false then
Exit;