mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
Ressurect old FileMonitor à la Frankenstein
ActiveFileMonitor combines QFileSystemWatcher with the previous checksum approach.
This commit is contained in:
parent
6c4b9c97cb
commit
9926927fb1
@ -3,6 +3,7 @@
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Angus Leeming
|
||||
* \author Guillaume Munch
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
@ -42,17 +43,32 @@ FileSystemWatcher::FileSystemWatcher()
|
||||
{}
|
||||
|
||||
|
||||
//static
|
||||
FileMonitorPtr FileSystemWatcher::monitor(FileName const & file_with_path)
|
||||
shared_ptr<FileMonitorGuard>
|
||||
FileSystemWatcher::getGuard(FileName const & filename)
|
||||
{
|
||||
FileSystemWatcher & f = instance();
|
||||
string const filename = file_with_path.absFileName();
|
||||
weak_ptr<FileMonitorGuard> & wptr = f.store_[filename];
|
||||
string const absfilename = filename.absFileName();
|
||||
weak_ptr<FileMonitorGuard> & wptr = store_[absfilename];
|
||||
if (shared_ptr<FileMonitorGuard> mon = wptr.lock())
|
||||
return make_unique<FileMonitor>(mon);
|
||||
auto mon = make_shared<FileMonitorGuard>(filename, f.qwatcher_.get());
|
||||
return mon;
|
||||
auto mon = make_shared<FileMonitorGuard>(absfilename, qwatcher_.get());
|
||||
wptr = mon;
|
||||
return make_unique<FileMonitor>(mon);
|
||||
return mon;
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
FileMonitorPtr FileSystemWatcher::monitor(FileName const & filename)
|
||||
{
|
||||
return make_unique<FileMonitor>(instance().getGuard(filename));
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
ActiveFileMonitorPtr FileSystemWatcher::activeMonitor(FileName const & filename,
|
||||
int interval)
|
||||
{
|
||||
return make_unique<ActiveFileMonitor>(instance().getGuard(filename),
|
||||
filename, interval);
|
||||
}
|
||||
|
||||
|
||||
@ -211,6 +227,59 @@ FileMonitorBlockerGuard::~FileMonitorBlockerGuard()
|
||||
QTimer::singleShot(delay_, monitor_, SLOT(reconnectToFileMonitorGuard()));
|
||||
}
|
||||
|
||||
|
||||
ActiveFileMonitor::ActiveFileMonitor(std::shared_ptr<FileMonitorGuard> monitor,
|
||||
FileName const & filename, int interval)
|
||||
: FileMonitor(monitor), filename_(filename), interval_(interval),
|
||||
timestamp_(0), checksum_(0), cooldown_(true)
|
||||
{
|
||||
QObject::connect(this, SIGNAL(fileChanged()), this, SLOT(setCooldown()));
|
||||
QTimer::singleShot(interval_, this, SLOT(clearCooldown()));
|
||||
if (!filename_.exists())
|
||||
return;
|
||||
timestamp_ = filename_.lastModified();
|
||||
checksum_ = filename_.checksum();
|
||||
}
|
||||
|
||||
|
||||
void ActiveFileMonitor::checkModified()
|
||||
{
|
||||
if (cooldown_)
|
||||
return;
|
||||
|
||||
cooldown_ = true;
|
||||
bool changed = false;
|
||||
if (!filename_.exists()) {
|
||||
changed = timestamp_ || checksum_;
|
||||
timestamp_ = 0;
|
||||
checksum_ = 0;
|
||||
} else {
|
||||
time_t const new_timestamp = filename_.lastModified();
|
||||
|
||||
if (new_timestamp != timestamp_) {
|
||||
timestamp_ = new_timestamp;
|
||||
|
||||
unsigned long const new_checksum = filename_.checksum();
|
||||
if (new_checksum != checksum_) {
|
||||
checksum_ = new_checksum;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
FileMonitor::changed();
|
||||
QTimer::singleShot(interval_, this, SLOT(clearCooldown()));
|
||||
}
|
||||
|
||||
|
||||
void ActiveFileMonitor::checkModifiedAsync()
|
||||
{
|
||||
if (!cooldown_)
|
||||
QTimer::singleShot(0, this, SLOT(checkModified()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace support
|
||||
} // namespace lyx
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Angus Leeming
|
||||
* \author Guillaume Munch
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
@ -15,6 +16,8 @@
|
||||
#ifndef FILEMONITOR_H
|
||||
#define FILEMONITOR_H
|
||||
|
||||
#include "support/FileName.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QFileSystemWatcher>
|
||||
@ -27,15 +30,15 @@
|
||||
namespace lyx {
|
||||
namespace support {
|
||||
|
||||
class FileName;
|
||||
|
||||
///
|
||||
/// FileMonitor, a file monitor based on QFileSystemWatcher
|
||||
///
|
||||
|
||||
class FileMonitor;
|
||||
class ActiveFileMonitor;
|
||||
class FileMonitorGuard;
|
||||
typedef std::unique_ptr<FileMonitor> FileMonitorPtr;
|
||||
typedef std::unique_ptr<ActiveFileMonitor> ActiveFileMonitorPtr;
|
||||
|
||||
///
|
||||
/// Watch a file:
|
||||
@ -72,14 +75,19 @@ class FileSystemWatcher
|
||||
{
|
||||
public:
|
||||
// as described above
|
||||
static FileMonitorPtr monitor(FileName const & file_with_path);
|
||||
static FileMonitorPtr monitor(FileName const & filename);
|
||||
/// same but with an ActiveFileMonitor
|
||||
static ActiveFileMonitorPtr activeMonitor(FileName const & filename,
|
||||
int interval = 10000);
|
||||
// Output whether the paths tracked by qwatcher_ and the active
|
||||
// FileMonitorGuards are in correspondence.
|
||||
static void debug();
|
||||
private:
|
||||
FileSystemWatcher();
|
||||
// A global instance is created automatically on first call to monitor
|
||||
/// A global instance is created automatically on first call
|
||||
static FileSystemWatcher & instance();
|
||||
///
|
||||
std::shared_ptr<FileMonitorGuard> getGuard(FileName const & filename);
|
||||
// Caches the monitor guards but allow them to be destroyed
|
||||
std::map<std::string, std::weak_ptr<FileMonitorGuard>> store_;
|
||||
// This class is a wrapper for QFileSystemWatcher
|
||||
@ -87,8 +95,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// Must be unique per path
|
||||
// Ends the watch when deleted
|
||||
/// Must be unique per path
|
||||
/// Ends the watch when deleted
|
||||
class FileMonitorGuard : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -174,7 +182,7 @@ Q_SIGNALS:
|
||||
/// Connect to this to be notified when the file changes
|
||||
void fileChanged() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
protected Q_SLOTS:
|
||||
/// Receive notifications from the FileMonitorGuard
|
||||
void changed();
|
||||
///
|
||||
@ -190,6 +198,39 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/// When a more active monitoring style is needed.
|
||||
/// For instance because QFileSystemWatcher does not work for remote file
|
||||
/// systems.
|
||||
class ActiveFileMonitor : public FileMonitor
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ActiveFileMonitor(std::shared_ptr<FileMonitorGuard> monitor,
|
||||
FileName const & filename, int interval);
|
||||
/// call checkModified asynchronously
|
||||
void checkModifiedAsync();
|
||||
|
||||
public Q_SLOTS:
|
||||
/// Check explicitly for a modification, but not more than once every
|
||||
/// interval ms.
|
||||
void checkModified();
|
||||
|
||||
private Q_SLOTS:
|
||||
void setCooldown() { cooldown_ = true; }
|
||||
void clearCooldown() { cooldown_ = false; }
|
||||
|
||||
private:
|
||||
FileName const filename_;
|
||||
///
|
||||
int const interval_;
|
||||
///
|
||||
time_t timestamp_;
|
||||
///
|
||||
unsigned long checksum_;
|
||||
///
|
||||
bool cooldown_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace support
|
||||
} // namespace lyx
|
||||
|
Loading…
Reference in New Issue
Block a user