94 lines
3.2 KiB
C++
94 lines
3.2 KiB
C++
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
|
|
#if PLATFORM_MAC
|
|
|
|
#include "MacFileSystemWatcher.h"
|
|
#include "Engine/Platform/Apple/AppleUtils.h"
|
|
#include "Engine/Platform/CriticalSection.h"
|
|
#include "Engine/Platform/Thread.h"
|
|
#include "Engine/Threading/ThreadSpawner.h"
|
|
#include "Engine/Core/Collections/Array.h"
|
|
#include "Engine/Core/Types/StringView.h"
|
|
|
|
void DirectoryWatchCallback( ConstFSEventStreamRef StreamRef, void* FileWatcherPtr, size_t EventCount, void* EventPaths, const FSEventStreamEventFlags EventFlags[], const FSEventStreamEventId EventIDs[])
|
|
{
|
|
MacFileSystemWatcher* macFileSystemWatcher = (MacFileSystemWatcher*)FileWatcherPtr;
|
|
if (macFileSystemWatcher)
|
|
{
|
|
CFArrayRef EventPathArray = (CFArrayRef)EventPaths;
|
|
for (size_t eventIndex = 0; eventIndex < EventCount; eventIndex++)
|
|
{
|
|
const FSEventStreamEventFlags flags = EventFlags[eventIndex];
|
|
if (!(flags & kFSEventStreamEventFlagItemIsFile) && !(flags & kFSEventStreamEventFlagItemIsDir))
|
|
{
|
|
// Events about symlinks don't concern us
|
|
continue;
|
|
}
|
|
|
|
auto action = FileSystemAction::Unknown;
|
|
if (flags & kFSEventStreamEventFlagItemCreated)
|
|
action = FileSystemAction::Create;
|
|
if (flags & kFSEventStreamEventFlagItemRenamed)
|
|
action = FileSystemAction::Rename;
|
|
if (flags & kFSEventStreamEventFlagItemModified)
|
|
action = FileSystemAction::Modify;
|
|
if (flags & kFSEventStreamEventFlagItemRemoved)
|
|
action = FileSystemAction::Delete;
|
|
|
|
const String resolvedPath = AppleUtils::ToString((CFStringRef)CFArrayGetValueAtIndex(EventPathArray, eventIndex));
|
|
macFileSystemWatcher->OnEvent(resolvedPath, action);
|
|
}
|
|
}
|
|
}
|
|
|
|
MacFileSystemWatcher::MacFileSystemWatcher(const String& directory, bool withSubDirs)
|
|
: FileSystemWatcherBase(directory, withSubDirs)
|
|
{
|
|
|
|
CFStringRef FullPathMac = AppleUtils::ToString(StringView(directory));
|
|
CFArrayRef PathsToWatch = CFArrayCreate(NULL, (const void**)&FullPathMac, 1, NULL);
|
|
|
|
CFAbsoluteTime Latency = 0.2;
|
|
FSEventStreamContext Context;
|
|
Context.version = 0;
|
|
Context.info = this;
|
|
Context.retain = NULL;
|
|
Context.release = NULL;
|
|
Context.copyDescription = NULL;
|
|
|
|
_eventStream = FSEventStreamCreate(NULL,
|
|
&DirectoryWatchCallback,
|
|
&Context,
|
|
PathsToWatch,
|
|
kFSEventStreamEventIdSinceNow,
|
|
Latency,
|
|
kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents
|
|
);
|
|
|
|
CFRelease(PathsToWatch);
|
|
CFRelease(FullPathMac);
|
|
|
|
_queue = dispatch_queue_create("MacFileSystemWatcher", NULL);
|
|
FSEventStreamSetDispatchQueue(_eventStream, _queue);
|
|
FSEventStreamStart(_eventStream);
|
|
}
|
|
|
|
MacFileSystemWatcher::~MacFileSystemWatcher()
|
|
{
|
|
if (_eventStream)
|
|
{
|
|
FSEventStreamStop(_eventStream);
|
|
FSEventStreamSetDispatchQueue(_eventStream, nullptr);
|
|
FSEventStreamInvalidate(_eventStream);
|
|
FSEventStreamRelease(_eventStream);
|
|
_eventStream = nullptr;
|
|
}
|
|
if (_queue != nullptr)
|
|
{
|
|
dispatch_release(_queue);
|
|
_queue = nullptr;
|
|
}
|
|
}
|
|
|
|
#endif
|