You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
6.1 KiB
C++
198 lines
6.1 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
#include "FileWatcher.h"
|
|
#include <native/assetprocessor.h>
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
/// FolderWatchRoot
|
|
void FolderRootWatch::ProcessNewFileEvent(const QString& file)
|
|
{
|
|
FileChangeInfo info;
|
|
info.m_action = FileAction::FileAction_Added;
|
|
info.m_filePath = file;
|
|
const bool invoked = QMetaObject::invokeMethod(m_fileWatcher, "AnyFileChange", Qt::QueuedConnection, Q_ARG(FileChangeInfo, info));
|
|
Q_ASSERT(invoked);
|
|
}
|
|
|
|
void FolderRootWatch::ProcessDeleteFileEvent(const QString& file)
|
|
{
|
|
FileChangeInfo info;
|
|
info.m_action = FileAction::FileAction_Removed;
|
|
info.m_filePath = file;
|
|
const bool invoked = QMetaObject::invokeMethod(m_fileWatcher, "AnyFileChange", Qt::QueuedConnection, Q_ARG(FileChangeInfo, info));
|
|
Q_ASSERT(invoked);
|
|
}
|
|
|
|
void FolderRootWatch::ProcessModifyFileEvent(const QString& file)
|
|
{
|
|
FileChangeInfo info;
|
|
info.m_action = FileAction::FileAction_Modified;
|
|
info.m_filePath = file;
|
|
const bool invoked = QMetaObject::invokeMethod(m_fileWatcher, "AnyFileChange", Qt::QueuedConnection, Q_ARG(FileChangeInfo, info));
|
|
Q_ASSERT(invoked);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
/// FileWatcher
|
|
FileWatcher::FileWatcher()
|
|
: m_nextHandle(0)
|
|
{
|
|
qRegisterMetaType<FileChangeInfo>("FileChangeInfo");
|
|
}
|
|
|
|
FileWatcher::~FileWatcher()
|
|
{
|
|
}
|
|
|
|
int FileWatcher::AddFolderWatch(FolderWatchBase* pFolderWatch)
|
|
{
|
|
if (!pFolderWatch)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
FolderRootWatch* pFolderRootWatch = nullptr;
|
|
|
|
//see if this a sub folder of an already watched root
|
|
for (auto rootsIter = m_folderWatchRoots.begin(); !pFolderRootWatch && rootsIter != m_folderWatchRoots.end(); ++rootsIter)
|
|
{
|
|
if (FolderWatchBase::IsSubfolder(pFolderWatch->m_folder, (*rootsIter)->m_root))
|
|
{
|
|
pFolderRootWatch = *rootsIter;
|
|
}
|
|
}
|
|
|
|
bool bCreatedNewRoot = false;
|
|
//if its not a sub folder
|
|
if (!pFolderRootWatch)
|
|
{
|
|
//create a new root and start listening for changes
|
|
pFolderRootWatch = new FolderRootWatch(pFolderWatch->m_folder);
|
|
|
|
//make sure the folder watcher(s) get deleted before this
|
|
pFolderRootWatch->setParent(this);
|
|
bCreatedNewRoot = true;
|
|
}
|
|
|
|
pFolderRootWatch->m_fileWatcher = this;
|
|
QObject::connect(this, &FileWatcher::AnyFileChange, pFolderWatch, &FolderWatchBase::OnAnyFileChange);
|
|
|
|
if (bCreatedNewRoot)
|
|
{
|
|
if (m_startedWatching)
|
|
{
|
|
pFolderRootWatch->Start();
|
|
}
|
|
|
|
//since we created a new root, see if the new root is a super folder
|
|
//of other roots, if it is then then fold those roots into the new super root
|
|
for (auto rootsIter = m_folderWatchRoots.begin(); rootsIter != m_folderWatchRoots.end(); )
|
|
{
|
|
if (FolderWatchBase::IsSubfolder((*rootsIter)->m_root, pFolderWatch->m_folder))
|
|
{
|
|
//union the sub folder map over to the new root
|
|
pFolderRootWatch->m_subFolderWatchesMap.insert((*rootsIter)->m_subFolderWatchesMap);
|
|
|
|
//clear the old root sub folders map so they don't get deleted when we
|
|
//delete the old root as they are now pointed to by the new root
|
|
(*rootsIter)->m_subFolderWatchesMap.clear();
|
|
|
|
//delete the empty old root, deleting a root will call Stop()
|
|
//automatically which kills the thread
|
|
delete *rootsIter;
|
|
|
|
//remove the old root pointer form the watched list
|
|
rootsIter = m_folderWatchRoots.erase(rootsIter);
|
|
}
|
|
else
|
|
{
|
|
++rootsIter;
|
|
}
|
|
}
|
|
|
|
//add the new root to the watched roots
|
|
m_folderWatchRoots.push_back(pFolderRootWatch);
|
|
}
|
|
|
|
//add to the root
|
|
pFolderRootWatch->m_subFolderWatchesMap.insert(m_nextHandle, pFolderWatch);
|
|
|
|
m_nextHandle++;
|
|
|
|
return m_nextHandle - 1;
|
|
}
|
|
|
|
void FileWatcher::RemoveFolderWatch(int handle)
|
|
{
|
|
for (auto rootsIter = m_folderWatchRoots.begin(); rootsIter != m_folderWatchRoots.end(); )
|
|
{
|
|
//find an element by the handle
|
|
auto foundIter = (*rootsIter)->m_subFolderWatchesMap.find(handle);
|
|
if (foundIter != (*rootsIter)->m_subFolderWatchesMap.end())
|
|
{
|
|
//remove the element
|
|
(*rootsIter)->m_subFolderWatchesMap.erase(foundIter);
|
|
|
|
//we removed a folder watch, if it's empty then there is no reason to keep watching it.
|
|
if ((*rootsIter)->m_subFolderWatchesMap.empty())
|
|
{
|
|
delete(*rootsIter);
|
|
rootsIter = m_folderWatchRoots.erase(rootsIter);
|
|
}
|
|
else
|
|
{
|
|
++rootsIter;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
++rootsIter;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FileWatcher::StartWatching()
|
|
{
|
|
if (m_startedWatching)
|
|
{
|
|
AZ_Warning("FileWatcher", false, "StartWatching() called when already watching for file changes.");
|
|
return;
|
|
}
|
|
|
|
for (FolderRootWatch* root : m_folderWatchRoots)
|
|
{
|
|
root->Start();
|
|
}
|
|
|
|
AZ_TracePrintf(AssetProcessor::ConsoleChannel, "File Change Monitoring started.\n");
|
|
m_startedWatching = true;
|
|
}
|
|
|
|
void FileWatcher::StopWatching()
|
|
{
|
|
if (!m_startedWatching)
|
|
{
|
|
AZ_Warning("FileWatcher", false, "StartWatching() called when is not watching for file changes.");
|
|
return;
|
|
}
|
|
|
|
for (FolderRootWatch* root : m_folderWatchRoots)
|
|
{
|
|
root->Stop();
|
|
}
|
|
|
|
m_startedWatching = false;
|
|
}
|
|
|
|
#include "native/FileWatcher/moc_FileWatcher.cpp"
|
|
#include "native/FileWatcher/moc_FileWatcherAPI.cpp"
|