Răsfoiți Sursa

core: increase stat() timestamp precision

Daniele Bartolini 3 ani în urmă
părinte
comite
4013433382
3 a modificat fișierele cu 28 adăugiri și 13 ștergeri
  1. 4 0
      docs/changelog.rst
  2. 23 12
      src/core/os.cpp
  3. 1 1
      src/core/os.h

+ 4 - 0
docs/changelog.rst

@@ -5,6 +5,10 @@ Changelog
 ------
 *DD MMM YYYY*
 
+**Data Compiler**
+
+* Fixed file changes not detected sometimes.
+
 **Tools**
 
 * Fixed minor issues when toggling the Console.

+ 23 - 12
src/core/os.cpp

@@ -106,15 +106,15 @@ namespace os
 		else if (S_ISDIR(buf.st_mode) == 1)
 			info.file_type = Stat::DIRECTORY;
 
-		info.size = buf.st_size;
-		info.mtime = buf.st_mtime;
+		info.size  = buf.st_size;
+		info.mtime = buf.st_mtim.tv_sec * s64(1000000000) + buf.st_mtim.tv_nsec;
 	}
 #endif
 
 	void stat(Stat& info, const char* path)
 	{
 		info.file_type = Stat::NO_ENTRY;
-		info.size = 0;
+		info.size  = 0;
 		info.mtime = 0;
 
 #if CROWN_PLATFORM_POSIX
@@ -128,20 +128,31 @@ namespace os
 			info.file_type = Stat::REGULAR;
 		else if (S_ISDIR(buf.st_mode) == 1)
 			info.file_type = Stat::DIRECTORY;
+
+		info.size  = buf.st_size;
+		info.mtime = buf.st_mtim.tv_sec * s64(1000000000) + buf.st_mtim.tv_nsec;
 #elif CROWN_PLATFORM_WINDOWS
-		struct _stat64 buf;
-		int err = ::_stat64(path, &buf);
-		if (err != 0)
+		WIN32_FIND_DATAA wfd;
+		HANDLE fh = FindFirstFileA(path, &wfd);
+		if (fh == INVALID_HANDLE_VALUE)
 			return;
+		FindClose(fh);
 
-		if ((buf.st_mode & _S_IFREG) != 0)
-			info.file_type = Stat::REGULAR;
-		else if ((buf.st_mode & _S_IFDIR) != 0)
+		if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
 			info.file_type = Stat::DIRECTORY;
-#endif
+		else // Assume regular file.
+			info.file_type = Stat::REGULAR;
+
+		ULARGE_INTEGER large_int = {};
 
-		info.size = buf.st_size;
-		info.mtime = buf.st_mtime;
+		large_int.LowPart  = wfd.nFileSizeLow;
+		large_int.HighPart = wfd.nFileSizeHigh;
+		info.size = large_int.QuadPart;
+
+		large_int.LowPart  = wfd.ftLastWriteTime.dwLowDateTime;
+		large_int.HighPart = wfd.ftLastWriteTime.dwHighDateTime;
+		info.mtime = large_int.QuadPart * u64(100); // See https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
+#endif
 	}
 
 	DeleteResult delete_file(const char* path)

+ 1 - 1
src/core/os.h

@@ -26,7 +26,7 @@ struct Stat
 	} file_type;
 
 	u64 size;  ///< Size in bytes.
-	u64 mtime; ///< Last modified time.
+	u64 mtime; ///< Last modified time in nanoseconds (actual precision depends on underlying filesystem).
 };
 
 /// Result from os::delete_file() or os::delete_directory().