Browse Source

Add one second delay to file change notifications by default. Possibly helps with #408. Removed FileWatcher from Lua bindings as it's not a class you can readily use from script and it is not exposed to AngelScript either.

Lasse Öörni 11 years ago
parent
commit
3f5280aa3a

+ 21 - 6
Source/Engine/IO/FileWatcher.cpp

@@ -49,6 +49,7 @@ static const unsigned BUFFERSIZE = 4096;
 FileWatcher::FileWatcher(Context* context) :
     Object(context),
     fileSystem_(GetSubsystem<FileSystem>()),
+    delay_(1.0f),
     watchSubDirs_(false)
 {
 #if defined(URHO3D_FILEWATCHER)
@@ -214,6 +215,11 @@ void FileWatcher::StopWatching()
     }
 }
 
+void FileWatcher::SetDelay(float interval)
+{
+    delay_ = Max(interval, 0.0f);
+}
+
 void FileWatcher::ThreadFunction()
 {
 #if defined(URHO3D_FILEWATCHER)
@@ -307,22 +313,31 @@ void FileWatcher::AddChange(const String& fileName)
 {
     MutexLock lock(changesMutex_);
     
-    // If we have 2 unprocessed modifies in a row into the same file, only record the first
-    if (changes_.Empty() || changes_.Back() != fileName)
-        changes_.Push(fileName);
+    // Reset the timer associated with the filename. Will be notified once timer exceeds the delay
+    changes_[fileName].Reset();
 }
 
 bool FileWatcher::GetNextChange(String& dest)
 {
     MutexLock lock(changesMutex_);
     
+    unsigned delayMsec = (unsigned)(delay_ * 1000.0f);
+    
     if (changes_.Empty())
         return false;
     else
     {
-        dest = changes_.Front();
-        changes_.Erase(changes_.Begin());
-        return true;
+        for (HashMap<String, Timer>::Iterator i = changes_.Begin(); i != changes_.End(); ++i)
+        {
+            if (i->second_.GetMSec(false) >= delayMsec)
+            {
+                dest = i->first_;
+                changes_.Erase(i);
+                return true;
+            }
+        }
+        
+        return false;
     }
 }
 

+ 9 - 2
Source/Engine/IO/FileWatcher.h

@@ -26,6 +26,7 @@
 #include "Mutex.h"
 #include "Object.h"
 #include "Thread.h"
+#include "Timer.h"
 
 namespace Urho3D
 {
@@ -50,6 +51,8 @@ public:
     bool StartWatching(const String& pathName, bool watchSubDirs);
     /// Stop watching the directory.
     void StopWatching();
+    /// Set the delay in seconds before file changes are notified. This (hopefully) avoids notifying when a file save is still in progress. Default 1 second.
+    void SetDelay(float interval);
     /// Add a file change into the changes queue.
     void AddChange(const String& fileName);
     /// Return a file change (true if was found, false if not.)
@@ -57,16 +60,20 @@ public:
     
     /// Return the path being watched, or empty if not watching.
     const String& GetPath() const { return path_; }
+    /// Return the delay in seconds for notifying file changes.
+    float GetDelay() const { return delay_;}
     
 private:
     /// Filesystem.
     SharedPtr<FileSystem> fileSystem_;
     /// The path being watched.
     String path_;
-    /// Buffered file changes.
-    List<String> changes_;
+    /// Pending changes. These will be returned and removed from the list when their timer has exceeded the delay.
+    HashMap<String, Timer> changes_;
     /// Mutex for the change buffer.
     Mutex changesMutex_;
+    /// Delay in seconds for notifying changes.
+    float delay_;
     /// Watch subdirectories flag.
     bool watchSubDirs_;
 

+ 0 - 9
Source/Engine/LuaScript/pkgs/IO/FileWatcher.pkg

@@ -1,9 +0,0 @@
-$#include "FileWatcher.h"
-
-class FileWatcher : public Object
-{
-    bool StartWatching(const String pathName, bool watchSubDirs);
-    void StopWatching();
-    void AddChange(const String fileName);
-    const String GetPath() const;
-};

+ 0 - 1
Source/Engine/LuaScript/pkgs/IOLuaAPI.pkg

@@ -1,7 +1,6 @@
 $pfile "IO/Deserializer.pkg"
 $pfile "IO/File.pkg"
 $pfile "IO/FileSystem.pkg"
-$pfile "IO/FileWatcher.pkg"
 $pfile "IO/Log.pkg"
 $pfile "IO/PackageFile.pkg"
 $pfile "IO/Serializer.pkg"