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.
o3de/Code/Tools/AssetProcessor/native/AssetManager/FileStateCache.cpp

221 lines
6.3 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#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