Merge branch 'development' into cmake/SPEC-7484
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> # Conflicts: # Code/Editor/ConfigGroup.cpp # Code/Editor/ControlMRU.cpp # Code/Editor/CryEdit.cpp # Code/Editor/CryEdit.h # Code/Editor/IEditorImpl.cpp # Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/GameController.cpp
This commit is contained in:
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : Tagged files database for 'SmartFileOpen' dialog
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "IndexedFiles.h"
|
||||
|
||||
volatile TIntAtomic CIndexedFiles::s_bIndexingDone;
|
||||
CIndexedFiles* CIndexedFiles::s_pIndexedFiles = nullptr;
|
||||
|
||||
bool CIndexedFiles::m_startedFileIndexing = false;
|
||||
|
||||
void CIndexedFiles::Initialize(const QString& path, IFileUtil::ScanDirectoryUpdateCallBack updateCB)
|
||||
{
|
||||
m_files.clear();
|
||||
m_pathToIndex.clear();
|
||||
m_tags.clear();
|
||||
m_rootPath = path;
|
||||
|
||||
bool anyFiles = CFileUtil::ScanDirectory(path, "*.*", m_files, true, true, updateCB);
|
||||
|
||||
if (anyFiles == false)
|
||||
{
|
||||
m_files.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (updateCB)
|
||||
{
|
||||
updateCB("Parsing & tagging...");
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_files.size(); ++i)
|
||||
{
|
||||
m_pathToIndex[m_files[i].filename] = i;
|
||||
}
|
||||
|
||||
PrepareTagTable();
|
||||
|
||||
InvokeUpdateCallbacks();
|
||||
}
|
||||
|
||||
void CIndexedFiles::AddFile(const IFileUtil::FileDesc& path)
|
||||
{
|
||||
assert(m_pathToIndex.find(path.filename) == m_pathToIndex.end());
|
||||
m_files.push_back(path);
|
||||
m_pathToIndex[path.filename] = m_files.size() - 1;
|
||||
QStringList tags;
|
||||
GetTags(tags, path.filename);
|
||||
for (int k = 0; k < tags.size(); ++k)
|
||||
{
|
||||
m_tags[tags[k]].insert(m_files.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void CIndexedFiles::RemoveFile(const QString& path)
|
||||
{
|
||||
if (m_pathToIndex.find(path) == m_pathToIndex.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::map<QString, int>::iterator itr = m_pathToIndex.find(path);
|
||||
int index = itr->second;
|
||||
m_pathToIndex.erase(itr);
|
||||
m_files.erase(m_files.begin() + index);
|
||||
QStringList tags;
|
||||
GetTags(tags, path);
|
||||
for (int k = 0; k < tags.size(); ++k)
|
||||
{
|
||||
m_tags[tags[k]].erase(index);
|
||||
}
|
||||
}
|
||||
|
||||
void CIndexedFiles::Refresh(const QString& path, bool recursive)
|
||||
{
|
||||
IFileUtil::FileArray files;
|
||||
bool anyFiles = CFileUtil::ScanDirectory(m_rootPath, Path::Make(path, "*.*"), files, recursive, recursive ? true : false);
|
||||
|
||||
if (anyFiles == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < files.size(); ++i)
|
||||
{
|
||||
if (m_pathToIndex.find(files[i].filename) == m_pathToIndex.end())
|
||||
{
|
||||
AddFile(files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
InvokeUpdateCallbacks();
|
||||
}
|
||||
|
||||
void CIndexedFiles::GetFilesWithTags(IFileUtil::FileArray& files, const QStringList& tags) const
|
||||
{
|
||||
files.clear();
|
||||
if (tags.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
int_set candidates;
|
||||
TagTable::const_iterator i;
|
||||
// Gets candidate files from the first tag.
|
||||
for (i = m_tags.begin(); i != m_tags.end(); ++i)
|
||||
{
|
||||
if (i->first.startsWith(tags[0]))
|
||||
{
|
||||
candidates.insert(i->second.begin(), i->second.end());
|
||||
}
|
||||
}
|
||||
// Reduces the candidates further using additional tags, if any.
|
||||
for (int k = 1; k < tags.size(); ++k)
|
||||
{
|
||||
// Gathers the filter set.
|
||||
int_set filter;
|
||||
for (i = m_tags.begin(); i != m_tags.end(); ++i)
|
||||
{
|
||||
if (i->first.startsWith(tags[k]))
|
||||
{
|
||||
filter.insert(i->second.begin(), i->second.end());
|
||||
}
|
||||
}
|
||||
|
||||
// Filters the candidates using it.
|
||||
for (int_set::iterator m = candidates.begin(); m != candidates.end(); )
|
||||
{
|
||||
if (filter.find(*m) == filter.end())
|
||||
{
|
||||
int_set::iterator target = m;
|
||||
++m;
|
||||
candidates.erase(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
++m;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Outputs the result.
|
||||
files.reserve(candidates.size());
|
||||
for (int_set::const_iterator m = candidates.begin(); m != candidates.end(); ++m)
|
||||
{
|
||||
files.push_back(m_files[*m]);
|
||||
}
|
||||
}
|
||||
|
||||
void CIndexedFiles::GetTags(QStringList& tags, const QString& path) const
|
||||
{
|
||||
tags = path.split(QRegularExpression(QStringLiteral(R"([\\/.])")), Qt::SkipEmptyParts);
|
||||
}
|
||||
|
||||
void CIndexedFiles::GetTagsOfPrefix(QStringList& tags, const QString& prefix) const
|
||||
{
|
||||
tags.clear();
|
||||
TagTable::const_iterator i;
|
||||
for (i = m_tags.begin(); i != m_tags.end(); ++i)
|
||||
{
|
||||
if (i->first.startsWith(prefix))
|
||||
{
|
||||
tags.push_back(i->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CIndexedFiles::PrepareTagTable()
|
||||
{
|
||||
QStringList tags;
|
||||
for (int i = 0; i < m_files.size(); ++i)
|
||||
{
|
||||
GetTags(tags, m_files[i].filename);
|
||||
for (int k = 0; k < tags.size(); ++k)
|
||||
{
|
||||
m_tags[tags[k]].insert(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CIndexedFiles::AddUpdateCallback(std::function<void()> updateCallback)
|
||||
{
|
||||
CryAutoLock<CryMutex> lock(m_updateCallbackMutex);
|
||||
|
||||
m_updateCallbacks.push_back(updateCallback);
|
||||
}
|
||||
|
||||
void CIndexedFiles::InvokeUpdateCallbacks()
|
||||
{
|
||||
CryAutoLock<CryMutex> lock(m_updateCallbackMutex);
|
||||
|
||||
for (auto updateCallback : m_updateCallbacks)
|
||||
{
|
||||
updateCallback();
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : Tagged files database for 'SmartFileOpen' dialog
|
||||
//
|
||||
// Notice : Refer SmartFileOpenDialog h
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_UTIL_INDEXEDFILES_H
|
||||
#define CRYINCLUDE_EDITOR_UTIL_INDEXEDFILES_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "FileUtil.h"
|
||||
#include <functional>
|
||||
|
||||
class CIndexedFiles
|
||||
{
|
||||
friend class CFileIndexingThread;
|
||||
public:
|
||||
static CIndexedFiles& GetDB()
|
||||
{
|
||||
if (!s_pIndexedFiles)
|
||||
{
|
||||
assert(!"CIndexedFiles not created! Make sure you use CIndexedFiles::GetDB() after CIndexedFiles::StartFileIndexing() is called.");
|
||||
}
|
||||
assert(s_pIndexedFiles);
|
||||
return *s_pIndexedFiles;
|
||||
}
|
||||
|
||||
static bool HasFileIndexingDone()
|
||||
{ return s_bIndexingDone > 0; }
|
||||
|
||||
static void Create()
|
||||
{
|
||||
assert(!s_pIndexedFiles);
|
||||
s_pIndexedFiles = new CIndexedFiles;
|
||||
}
|
||||
|
||||
static void Destroy()
|
||||
{
|
||||
SAFE_DELETE(s_pIndexedFiles);
|
||||
}
|
||||
|
||||
static void StartFileIndexing()
|
||||
{
|
||||
assert(s_bIndexingDone == 0);
|
||||
assert(s_pIndexedFiles);
|
||||
|
||||
if (!s_pIndexedFiles)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GetFileIndexingThread().Start(-1, "FileIndexing");
|
||||
m_startedFileIndexing = true;
|
||||
}
|
||||
|
||||
static void AbortFileIndexing()
|
||||
{
|
||||
if (!m_startedFileIndexing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasFileIndexingDone() == false)
|
||||
{
|
||||
GetFileIndexingThread().Abort();
|
||||
}
|
||||
m_startedFileIndexing = false;
|
||||
}
|
||||
|
||||
static void RegisterCallback(std::function<void()> callback)
|
||||
{
|
||||
assert(s_pIndexedFiles);
|
||||
if (!s_pIndexedFiles)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s_pIndexedFiles->AddUpdateCallback(callback);
|
||||
}
|
||||
|
||||
public:
|
||||
void Initialize(const QString& path, IFileUtil::ScanDirectoryUpdateCallBack updateCB = nullptr);
|
||||
|
||||
// Adds a new file to the database.
|
||||
void AddFile(const IFileUtil::FileDesc& path);
|
||||
// Removes a no-longer-existing file from the database.
|
||||
void RemoveFile(const QString& path);
|
||||
// Refreshes this database for the subdirectory.
|
||||
void Refresh(const QString& path, bool recursive = true);
|
||||
|
||||
void GetFilesWithTags(IFileUtil::FileArray& files, const QStringList& tags) const;
|
||||
|
||||
//! This method returns all the tags which start with a given prefix.
|
||||
//! It is useful for the tag auto-completion.
|
||||
void GetTagsOfPrefix(QStringList& tags, const QString& prefix) const;
|
||||
|
||||
uint32 GetTotalCount() const
|
||||
{ return (uint32)m_files.size(); }
|
||||
|
||||
private:
|
||||
static bool m_startedFileIndexing;
|
||||
|
||||
std::vector <std::function<void()> > m_updateCallbacks;
|
||||
IFileUtil::FileArray m_files;
|
||||
std::map<QString, int> m_pathToIndex;
|
||||
typedef std::set<int, std::less<int> > int_set;
|
||||
typedef std::map<QString, int_set, std::less<QString> > TagTable;
|
||||
TagTable m_tags;
|
||||
QString m_rootPath;
|
||||
|
||||
void GetTags(QStringList& tags, const QString& path) const;
|
||||
void PrepareTagTable();
|
||||
|
||||
CryMutex m_updateCallbackMutex;
|
||||
|
||||
void AddUpdateCallback(std::function<void()> updateCallback);
|
||||
void InvokeUpdateCallbacks();
|
||||
|
||||
// A done flag for the background file indexing
|
||||
static volatile TIntAtomic s_bIndexingDone;
|
||||
// A thread for the background file indexing
|
||||
class CFileIndexingThread
|
||||
: public CryThread<CFileIndexingThread>
|
||||
{
|
||||
public:
|
||||
virtual void Run()
|
||||
{
|
||||
CIndexedFiles::GetDB().Initialize("@assets@", CallBack);
|
||||
CryInterlockedAdd(CIndexedFiles::s_bIndexingDone.Addr(), 1);
|
||||
}
|
||||
|
||||
CFileIndexingThread()
|
||||
: m_abort(false) {}
|
||||
|
||||
void Abort()
|
||||
{
|
||||
m_abort = true;
|
||||
WaitForThread();
|
||||
}
|
||||
|
||||
virtual ~CFileIndexingThread()
|
||||
{
|
||||
Abort();
|
||||
}
|
||||
private:
|
||||
bool m_abort;
|
||||
static bool CallBack([[maybe_unused]] const QString& msg)
|
||||
{
|
||||
if (CIndexedFiles::GetFileIndexingThread().m_abort)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static CFileIndexingThread& GetFileIndexingThread()
|
||||
{
|
||||
static CFileIndexingThread s_fileIndexingThread;
|
||||
|
||||
return s_fileIndexingThread;
|
||||
}
|
||||
|
||||
// A global database for tagged files
|
||||
static CIndexedFiles* s_pIndexedFiles;
|
||||
};
|
||||
#endif // CRYINCLUDE_EDITOR_UTIL_INDEXEDFILES_H
|
||||
Reference in New Issue
Block a user