void FFeaturePackContentSourceProvider::StartUpDirectoryWatcher()
{
	FDirectoryWatcherModule& DirectoryWatcherModule = FModuleManager::LoadModuleChecked<FDirectoryWatcherModule>(TEXT("DirectoryWatcher"));
	IDirectoryWatcher* DirectoryWatcher = DirectoryWatcherModule.Get();
	if (DirectoryWatcher)
	{
		// If the path doesn't exist on disk, make it so the watcher will work.
		IFileManager::Get().MakeDirectory(*FeaturePackPath);
		DirectoryChangedDelegate = IDirectoryWatcher::FDirectoryChanged::CreateRaw(this, &FFeaturePackContentSourceProvider::OnFeaturePackDirectoryChanged);
		DirectoryWatcher->RegisterDirectoryChangedCallback_Handle(FeaturePackPath, DirectoryChangedDelegate, DirectoryChangedDelegateHandle);
	}
}
示例#2
0
void UDirectoryWatcher::Watch(const FString& InDirectory)
{	
	Unwatch();

	FDirectoryWatcherModule& DirectoryWatcherModule = FModuleManager::Get().LoadModuleChecked<FDirectoryWatcherModule>(TEXT("DirectoryWatcher"));
	IDirectoryWatcher* DirectoryWatcher = DirectoryWatcherModule.Get();

	Directory = FPaths::IsRelative(InDirectory) ? FPaths::ConvertRelativePathToFull(InDirectory) : InDirectory;

	Changed = IDirectoryWatcher::FDirectoryChanged::CreateLambda([&](const TArray<FFileChangeData>& FileChanges){		
		for (auto Change : FileChanges)
		{
			FPaths::NormalizeFilename(Change.Filename);
			
			switch (Change.Action)
			{
			case FFileChangeData::FCA_Added:
				Added.Add(Change.Filename);
				break;
			case FFileChangeData::FCA_Modified:
				Modified.Add(Change.Filename);
				break;
			case FFileChangeData::FCA_Removed:
				Removed.Add(Change.Filename);
				break;
			}
		}
		OnChanged.Broadcast();
		Added.Empty();
		Modified.Empty();
		Removed.Empty();
	});	
	
	if (IFileManager::Get().DirectoryExists(*Directory))
	{
		DirectoryWatcher->RegisterDirectoryChangedCallback_Handle(Directory, Changed, DelegateHandle, true);
	}	
}
/**
 * Kicks directory watcher test/
 */
int32 DirectoryWatcherTest(const TCHAR* CommandLine)
{
	FPlatformMisc::SetCrashHandler(NULL);
	FPlatformMisc::SetGracefulTerminationHandler();

	GEngineLoop.PreInit(CommandLine);
	UE_LOG(LogTestPAL, Display, TEXT("Running directory watcher test."));

	IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
	FString TestDir = FString::Printf(TEXT("%sDirectoryWatcherTest%d"), FPlatformProcess::UserTempDir(), FPlatformProcess::GetCurrentProcessId());

	if (PlatformFile.CreateDirectory(*TestDir) && PlatformFile.CreateDirectory(*(TestDir + TEXT("/subtest"))))
	{
		FChangeDetector Detector;
		FDelegateHandle DirectoryChangedHandle;

		IDirectoryWatcher* DirectoryWatcher = FModuleManager::Get().LoadModuleChecked<FDirectoryWatcherModule>(TEXT("DirectoryWatcher")).Get();
		if (DirectoryWatcher)
		{
			auto Callback = IDirectoryWatcher::FDirectoryChanged::CreateRaw(&Detector, &FChangeDetector::OnDirectoryChanged);
			DirectoryWatcher->RegisterDirectoryChangedCallback_Handle(TestDir, Callback, DirectoryChangedHandle);
			UE_LOG(LogTestPAL, Display, TEXT("Registered callback for changes in '%s'"), *TestDir);
		}
		else
		{
			UE_LOG(LogTestPAL, Fatal, TEXT("Could not get DirectoryWatcher module"));
		}

		FPlatformProcess::Sleep(1.0f);
		DirectoryWatcher->Tick(1.0f);

		// create and remove directory
		UE_LOG(LogTestPAL, Display, TEXT("Creating DIRECTORY '%s'"), *(TestDir + TEXT("/test")));
		verify(PlatformFile.CreateDirectory(*(TestDir + TEXT("/test"))));
		DirectoryWatcher->Tick(1.0f);
		FPlatformProcess::Sleep(1.0f);
		DirectoryWatcher->Tick(1.0f);

		UE_LOG(LogTestPAL, Display, TEXT("Deleting DIRECTORY '%s'"), *(TestDir + TEXT("/test")));
		verify(PlatformFile.DeleteDirectory(*(TestDir + TEXT("/test"))));
		DirectoryWatcher->Tick(1.0f);
		FPlatformProcess::Sleep(1.0f);
		DirectoryWatcher->Tick(1.0f);

		// create and remove in a sub directory
		UE_LOG(LogTestPAL, Display, TEXT("Creating DIRECTORY '%s'"), *(TestDir + TEXT("/subtest/blah")));
		verify(PlatformFile.CreateDirectory(*(TestDir + TEXT("/subtest/blah"))));
		DirectoryWatcher->Tick(1.0f);
		FPlatformProcess::Sleep(1.0f);
		DirectoryWatcher->Tick(1.0f);

		UE_LOG(LogTestPAL, Display, TEXT("Deleting DIRECTORY '%s'"), *(TestDir + TEXT("/subtest/blah")));
		verify(PlatformFile.DeleteDirectory(*(TestDir + TEXT("/subtest/blah"))));
		DirectoryWatcher->Tick(1.0f);
		FPlatformProcess::Sleep(1.0f);
		DirectoryWatcher->Tick(1.0f);

		{
			// create file
			FString DummyFileName = TestDir + TEXT("/test file.bin");
			UE_LOG(LogTestPAL, Display, TEXT("Creating FILE '%s'"), *DummyFileName);
			IFileHandle* DummyFile = PlatformFile.OpenWrite(*DummyFileName);
			check(DummyFile);
			DirectoryWatcher->Tick(1.0f);
			FPlatformProcess::Sleep(1.0f);
			DirectoryWatcher->Tick(1.0f);

			// modify file
			UE_LOG(LogTestPAL, Display, TEXT("Modifying FILE '%s'"), *DummyFileName);
			uint8 Contents = 0;
			DummyFile->Write(&Contents, sizeof(Contents));
			DirectoryWatcher->Tick(1.0f);
			FPlatformProcess::Sleep(1.0f);
			DirectoryWatcher->Tick(1.0f);

			// close the file
			UE_LOG(LogTestPAL, Display, TEXT("Closing FILE '%s'"), *DummyFileName);
			delete DummyFile;
			DummyFile = nullptr;
			DirectoryWatcher->Tick(1.0f);
			FPlatformProcess::Sleep(1.0f);
			DirectoryWatcher->Tick(1.0f);

			// delete file
			UE_LOG(LogTestPAL, Display, TEXT("Deleting FILE '%s'"), *DummyFileName);
			verify(PlatformFile.DeleteFile(*DummyFileName));
			DirectoryWatcher->Tick(1.0f);
			FPlatformProcess::Sleep(1.0f);
			DirectoryWatcher->Tick(1.0f);
		}

		// now the same in a grandchild directory
		{
			FString GrandChildDir = TestDir + TEXT("/subtest/grandchild");

			UE_LOG(LogTestPAL, Display, TEXT("Creating DIRECTORY '%s'"), *GrandChildDir);
			verify(PlatformFile.CreateDirectory(*GrandChildDir));
			DirectoryWatcher->Tick(1.0f);
			FPlatformProcess::Sleep(1.0f);
			DirectoryWatcher->Tick(1.0f);

			{
				// create file
				FString DummyFileName = GrandChildDir + TEXT("/test file.bin");
				UE_LOG(LogTestPAL, Display, TEXT("Creating FILE '%s'"), *DummyFileName);
				IFileHandle* DummyFile = PlatformFile.OpenWrite(*DummyFileName);
				check(DummyFile);
				DirectoryWatcher->Tick(1.0f);
				FPlatformProcess::Sleep(1.0f);
				DirectoryWatcher->Tick(1.0f);

				// modify file
				UE_LOG(LogTestPAL, Display, TEXT("Modifying FILE '%s'"), *DummyFileName);
				uint8 Contents = 0;
				DummyFile->Write(&Contents, sizeof(Contents));
				DirectoryWatcher->Tick(1.0f);
				FPlatformProcess::Sleep(1.0f);
				DirectoryWatcher->Tick(1.0f);

				// close the file
				UE_LOG(LogTestPAL, Display, TEXT("Closing FILE '%s'"), *DummyFileName);
				delete DummyFile;
				DummyFile = nullptr;
				DirectoryWatcher->Tick(1.0f);
				FPlatformProcess::Sleep(1.0f);
				DirectoryWatcher->Tick(1.0f);

				// delete file
				UE_LOG(LogTestPAL, Display, TEXT("Deleting FILE '%s'"), *DummyFileName);
				PlatformFile.DeleteFile(*DummyFileName);
				DirectoryWatcher->Tick(1.0f);
				FPlatformProcess::Sleep(1.0f);
				DirectoryWatcher->Tick(1.0f);
			}

			UE_LOG(LogTestPAL, Display, TEXT("Deleting DIRECTORY '%s'"), *GrandChildDir);
			verify(PlatformFile.DeleteDirectory(*GrandChildDir));
			DirectoryWatcher->Tick(1.0f);
			FPlatformProcess::Sleep(1.0f);
			DirectoryWatcher->Tick(1.0f);
		}


		// clean up
		verify(DirectoryWatcher->UnregisterDirectoryChangedCallback_Handle(TestDir, DirectoryChangedHandle));
		// remove dirs as well
		verify(PlatformFile.DeleteDirectory(*(TestDir + TEXT("/subtest"))));
		verify(PlatformFile.DeleteDirectory(*TestDir));

		UE_LOG(LogTestPAL, Display, TEXT("End of test"));
	}
	else
	{
		UE_LOG(LogTestPAL, Fatal, TEXT("Could not create test directory %s."), *TestDir);
	}

	FEngineLoop::AppPreExit();
	FEngineLoop::AppExit();
	return 0;
}