135 lines
2.8 KiB
C++
135 lines
2.8 KiB
C++
#include "Core/Util/FileWatcher.h"
|
|
|
|
FileWatcher::FileWatcher()
|
|
{
|
|
m_Worker = new Worker;
|
|
}
|
|
|
|
FileWatcher::FileWatcher(std::string rootPath)
|
|
{
|
|
m_RootPath = rootPath;
|
|
m_Worker = new Worker;
|
|
}
|
|
|
|
FileWatcher::~FileWatcher()
|
|
{
|
|
m_Thread.interrupt();
|
|
if (m_Worker != nullptr)
|
|
{
|
|
delete m_Worker;
|
|
}
|
|
}
|
|
|
|
void FileWatcher::AddWatch(std::string path, FileEventCallback_t callback)
|
|
{
|
|
m_Worker->AddWatch(path, callback);
|
|
}
|
|
|
|
void FileWatcher::Start()
|
|
{
|
|
m_Thread.interrupt();
|
|
m_Thread = boost::thread(boost::ref(*m_Worker));
|
|
m_IsRunning = true;
|
|
}
|
|
|
|
void FileWatcher::Stop()
|
|
{
|
|
m_Thread.interrupt();
|
|
m_IsRunning = false;
|
|
}
|
|
|
|
void FileWatcher::Check()
|
|
{
|
|
m_Worker->Check();
|
|
}
|
|
|
|
|
|
void FileWatcher::Worker::operator()()
|
|
{
|
|
while (true)
|
|
{
|
|
boost::this_thread::interruption_point();
|
|
Check();
|
|
boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
|
|
}
|
|
}
|
|
|
|
void FileWatcher::Worker::AddWatch(std::string path, FileEventCallback_t callback)
|
|
{
|
|
m_Mutex.lock();
|
|
boost::filesystem::path bpath(path);
|
|
m_FileCallbacks[bpath] = callback;
|
|
if (boost::filesystem::exists(bpath))
|
|
{
|
|
m_FileInfo[bpath] = GetFileInfo(bpath);
|
|
}
|
|
m_Mutex.unlock();
|
|
}
|
|
|
|
void FileWatcher::Worker::Check()
|
|
{
|
|
m_Mutex.lock();
|
|
for (auto &kv : m_FileCallbacks)
|
|
{
|
|
boost::filesystem::path path = kv.first;
|
|
FileEventCallback_t& callback = kv.second;
|
|
FileEventFlags flags = UpdateFileInfo(path);
|
|
if (flags != FileEventFlags::Nothing && callback != nullptr)
|
|
{
|
|
callback(path.string(), flags);
|
|
}
|
|
}
|
|
m_Mutex.unlock();
|
|
}
|
|
|
|
FileWatcher::Worker::FileInfo FileWatcher::Worker::GetFileInfo(boost::filesystem::path path)
|
|
{
|
|
FileInfo fi;
|
|
fi.Size = boost::filesystem::file_size(path);
|
|
fi.Timestamp = boost::filesystem::last_write_time(path);
|
|
return fi;
|
|
}
|
|
|
|
FileWatcher::FileEventFlags FileWatcher::Worker::UpdateFileInfo(boost::filesystem::path path)
|
|
{
|
|
FileEventFlags flags = FileEventFlags::Nothing;
|
|
if (boost::filesystem::exists(path))
|
|
{
|
|
FileInfo fi = GetFileInfo(path);
|
|
auto lastFileInfoIt = m_FileInfo.find(path);
|
|
if (lastFileInfoIt != m_FileInfo.end())
|
|
{
|
|
FileInfo lastFileInfo = lastFileInfoIt->second;
|
|
|
|
if (fi.Size != lastFileInfo.Size)
|
|
{
|
|
LOG_DEBUG("FileWatcher: \"%s\" size changed!", path.string().c_str());
|
|
flags = flags | FileEventFlags::SizeChanged;
|
|
}
|
|
if (fi.Timestamp != lastFileInfo.Timestamp)
|
|
{
|
|
LOG_DEBUG("FileWatcher: \"%s\" timestamp changed!", path.string().c_str());
|
|
flags = flags | FileEventFlags::TimestampChanged;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG_DEBUG("FileWatcher: \"%s\" was created!", path.string().c_str());
|
|
flags = flags | FileEventFlags::Created;
|
|
}
|
|
m_FileInfo[path] = GetFileInfo(path);
|
|
}
|
|
else
|
|
{
|
|
auto fileInfoIt = m_FileInfo.find(path);
|
|
if (fileInfoIt != m_FileInfo.end())
|
|
{
|
|
m_FileInfo.erase(fileInfoIt);
|
|
LOG_DEBUG("FileWatcher: \"%s\" was deleted!", path.string().c_str());
|
|
flags = flags | FileEventFlags::Deleted;
|
|
}
|
|
}
|
|
return flags;
|
|
}
|