Files
FlaxEngine/Source/Engine/Platform/Mac/MacFileSystemWatcher.cpp
T

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