You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
6.0 KiB
C++
217 lines
6.0 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#include "FileStateCache.h"
|
|
#include "native/utilities/assetUtils.h"
|
|
#include <AssetProcessor_Traits_Platform.h>
|
|
|
|
#include <QDir>
|
|
|
|
namespace AssetProcessor
|
|
{
|
|
|
|
bool FileStateCache::GetFileInfo(const QString& absolutePath, FileStateInfo* foundFileInfo) const
|
|
{
|
|
LockGuardType scopeLock(m_mapMutex);
|
|
auto itr = m_fileInfoMap.find(PathToKey(absolutePath));
|
|
|
|
if (itr != m_fileInfoMap.end())
|
|
{
|
|
*foundFileInfo = itr.value();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool FileStateCache::Exists(const QString& absolutePath) const
|
|
{
|
|
LockGuardType scopeLock(m_mapMutex);
|
|
auto itr = m_fileInfoMap.find(PathToKey(absolutePath));
|
|
|
|
return itr != m_fileInfoMap.end();
|
|
}
|
|
|
|
bool FileStateCache::GetHash(const QString& absolutePath, FileHash* foundHash)
|
|
{
|
|
LockGuardType scopeLock(m_mapMutex);
|
|
auto fileInfoItr = m_fileInfoMap.find(PathToKey(absolutePath));
|
|
|
|
if(fileInfoItr == m_fileInfoMap.end())
|
|
{
|
|
// No info on this file, return false
|
|
return false;
|
|
}
|
|
|
|
auto itr = m_fileHashMap.find(PathToKey(absolutePath));
|
|
|
|
if (itr != m_fileHashMap.end())
|
|
{
|
|
*foundHash = itr.value();
|
|
return true;
|
|
}
|
|
|
|
// There's no hash stored yet or its been invalidated, calculate it
|
|
*foundHash = AssetUtilities::GetFileHash(absolutePath.toUtf8().constData(), true);
|
|
|
|
m_fileHashMap[PathToKey(absolutePath)] = *foundHash;
|
|
return true;
|
|
}
|
|
|
|
void FileStateCache::AddInfoSet(QSet<AssetFileInfo> infoSet)
|
|
{
|
|
LockGuardType scopeLock(m_mapMutex);
|
|
for (const AssetFileInfo& info : infoSet)
|
|
{
|
|
m_fileInfoMap[PathToKey(info.m_filePath)] = FileStateInfo(info);
|
|
}
|
|
}
|
|
|
|
void FileStateCache::AddFile(const QString& absolutePath)
|
|
{
|
|
QFileInfo fileInfo(absolutePath);
|
|
LockGuardType scopeLock(m_mapMutex);
|
|
|
|
AddOrUpdateFileInternal(fileInfo);
|
|
InvalidateHash(absolutePath);
|
|
|
|
if(fileInfo.isDir())
|
|
{
|
|
ScanFolder(absolutePath);
|
|
}
|
|
}
|
|
|
|
void FileStateCache::UpdateFile(const QString& absolutePath)
|
|
{
|
|
QFileInfo fileInfo(absolutePath);
|
|
LockGuardType scopeLock(m_mapMutex);
|
|
|
|
AddOrUpdateFileInternal(fileInfo);
|
|
InvalidateHash(absolutePath);
|
|
}
|
|
|
|
void FileStateCache::RemoveFile(const QString& absolutePath)
|
|
{
|
|
LockGuardType scopeLock(m_mapMutex);
|
|
|
|
auto itr = m_fileInfoMap.find(PathToKey(absolutePath));
|
|
|
|
if (itr != m_fileInfoMap.end())
|
|
{
|
|
bool isDirectory = itr.value().m_isDirectory;
|
|
QString parentPath = itr.value().m_absolutePath;
|
|
m_fileInfoMap.erase(itr);
|
|
|
|
if (isDirectory)
|
|
{
|
|
for (itr = m_fileInfoMap.begin(); itr != m_fileInfoMap.end(); )
|
|
{
|
|
if (itr.value().m_absolutePath.startsWith(parentPath))
|
|
{
|
|
itr = m_fileInfoMap.erase(itr);
|
|
continue;
|
|
}
|
|
|
|
++itr;
|
|
}
|
|
}
|
|
}
|
|
|
|
InvalidateHash(absolutePath);
|
|
}
|
|
|
|
void FileStateCache::InvalidateHash(const QString& absolutePath)
|
|
{
|
|
auto fileHashItr = m_fileHashMap.find(PathToKey(absolutePath));
|
|
|
|
if (fileHashItr != m_fileHashMap.end())
|
|
{
|
|
m_fileHashMap.erase(fileHashItr);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
QString FileStateCache::PathToKey(const QString& absolutePath) const
|
|
{
|
|
QString normalized = AssetUtilities::NormalizeFilePath(absolutePath);
|
|
|
|
if constexpr (!ASSETPROCESSOR_TRAIT_CASE_SENSITIVE_FILESYSTEM)
|
|
{
|
|
return normalized.toLower();
|
|
}
|
|
else
|
|
{
|
|
return normalized;
|
|
}
|
|
}
|
|
|
|
void FileStateCache::AddOrUpdateFileInternal(QFileInfo fileInfo)
|
|
{
|
|
m_fileInfoMap[PathToKey(fileInfo.absoluteFilePath())] = FileStateInfo(fileInfo.absoluteFilePath(), fileInfo.lastModified(), fileInfo.size(), fileInfo.isDir());
|
|
}
|
|
|
|
void FileStateCache::ScanFolder(const QString& absolutePath)
|
|
{
|
|
QDir inputFolder(absolutePath);
|
|
QFileInfoList entries = inputFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files);
|
|
|
|
for (const QFileInfo& entry : entries)
|
|
{
|
|
AddOrUpdateFileInternal(entry);
|
|
|
|
if (entry.isDir())
|
|
{
|
|
ScanFolder(entry.absoluteFilePath());
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
bool FileStatePassthrough::GetFileInfo(const QString& absolutePath, FileStateInfo* foundFileInfo) const
|
|
{
|
|
QFileInfo fileInfo(absolutePath);
|
|
|
|
if (fileInfo.exists())
|
|
{
|
|
*foundFileInfo = FileStateInfo(fileInfo.absoluteFilePath(), fileInfo.lastModified(), fileInfo.size(), fileInfo.isDir());
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool FileStatePassthrough::Exists(const QString& absolutePath) const
|
|
{
|
|
return QFile(absolutePath).exists();
|
|
}
|
|
|
|
bool FileStatePassthrough::GetHash(const QString& absolutePath, FileHash* foundHash)
|
|
{
|
|
if(!Exists(absolutePath))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
*foundHash = AssetUtilities::GetFileHash(absolutePath.toUtf8().constData(), true);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool FileStateInfo::operator==(const FileStateInfo& rhs) const
|
|
{
|
|
return m_absolutePath == rhs.m_absolutePath
|
|
&& m_modTime == rhs.m_modTime
|
|
&& m_fileSize == rhs.m_fileSize
|
|
&& m_isDirectory == rhs.m_isDirectory;
|
|
}
|
|
|
|
} // namespace AssetProcessor
|