!XT (BREAK-16) (Sandbox) Remove double-newlines at the end of files.
[CRYENGINE.git] / Code / Sandbox / Plugins / EditorCommon / AssetSystem / DependencyTracker.cpp
blob168e0ae4c3d5f3890a63fc7b14344c7eb6c785c7
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
4 #include "DependencyTracker.h"
5 #include "AssetManager.h"
7 namespace Private_DependencyTracker
10 struct SLessKey
12 bool operator()(const std::pair<string, SAssetDependencyInfo>& a, const string& b)
14 return stricmp(a.first.c_str(), b.c_str()) < 0;
17 bool operator()(const string& a, const std::pair<string, SAssetDependencyInfo>& b)
19 return stricmp(a.c_str(), b.first.c_str()) < 0;
23 struct SLessValue
25 bool operator()(const std::pair<string, SAssetDependencyInfo>& a, const string& b)
27 return stricmp(a.second.path.c_str(), b.c_str()) < 0;
30 bool operator()(const string& a, const std::pair<string, SAssetDependencyInfo>& b)
32 return stricmp(a.c_str(), b.second.path.c_str()) < 0;
39 CDependencyTracker::CDependencyTracker()
41 CAssetManager* pAssetManager = CAssetManager::GetInstance();
43 pAssetManager->signalAfterAssetsInserted.Connect([this](const std::vector<CAsset*>&)
45 CreateIndex();
46 }, (uintptr_t)this);
48 pAssetManager->signalAfterAssetsUpdated.Connect([this]()
50 CreateIndex();
51 }, (uintptr_t)this);
53 pAssetManager->signalAssetChanged.Connect([this](CAsset&)
55 CreateIndex();
56 }, (uintptr_t)this);
58 pAssetManager->signalAfterAssetsRemoved.Connect([this]()
60 CreateIndex();
61 }, (uintptr_t)this);
64 CDependencyTracker::~CDependencyTracker()
66 CAssetManager* pAssetManager = CAssetManager::GetInstance();
67 pAssetManager->signalAfterAssetsInserted.DisconnectById((uintptr_t)this);
68 pAssetManager->signalAfterAssetsUpdated.DisconnectById((uintptr_t)this);
69 pAssetManager->signalAssetChanged.DisconnectById((uintptr_t)this);
70 pAssetManager->signalAfterAssetsRemoved.DisconnectById((uintptr_t)this);
73 std::vector<SAssetDependencyInfo> CDependencyTracker::GetReverseDependencies(const char* szAssetPath) const
75 const auto range = GetRange(szAssetPath);
77 std::vector<SAssetDependencyInfo> dependencies;
78 dependencies.reserve(3); // just an empirical expectation.
80 std::transform(range.first, range.second, std::back_inserter(dependencies), [](const auto& x)
82 return x.second;
83 });
85 return dependencies;
88 std::pair<bool, int> CDependencyTracker::IsAssetUsedBy(const char* szAssetPath, const char* szAnotherAssetPath) const
90 using namespace Private_DependencyTracker;
92 const auto range = GetRange(szAssetPath);
93 if (range.first == range.second)
95 return { false, 0 };
98 const string value = PathUtil::ToUnixPath(szAnotherAssetPath);
99 const auto lowerBound = std::lower_bound(range.first, range.second, value, SLessValue());
100 if (lowerBound != range.second && (*lowerBound).second.path.CompareNoCase(value) == 0)
102 return { true, (*lowerBound).second.usageCount };
105 return { false, 0 };
108 void CDependencyTracker::CreateIndex()
110 // Do nothing if the future has already referred to the deffered request.
111 if (m_future.valid() && m_future.wait_for(std::chrono::seconds(0)) != std::future_status::ready)
113 return;
116 m_future = std::async(std::launch::deferred, [this]()
118 m_index.clear();
119 CAssetManager* pAssetManager = CAssetManager::GetInstance();
120 pAssetManager->ForeachAsset([this](CAsset* pAsset)
122 MAKE_SURE(pAsset->GetFilesCount(), return);
124 const std::vector<SAssetDependencyInfo>& dependencies = pAsset->GetDependencies();
125 for (const auto& item : dependencies)
127 m_index.emplace_back(item.path, SAssetDependencyInfo( pAsset->GetFile(0), item.usageCount ));
131 std::sort(m_index.begin(), m_index.end(), [](const auto& a, const auto& b)
133 const int first = stricmp(a.first.c_str(), b.first.c_str());
134 if (first != 0)
136 return first < 0;
139 return stricmp(a.second.path.c_str(), b.second.path.c_str()) < 0;
144 std::pair<CDependencyTracker::IndexIterator, CDependencyTracker::IndexIterator> CDependencyTracker::GetRange(const char* szAssetPath) const
146 using namespace Private_DependencyTracker;
148 if (m_future.valid())
150 m_future.wait();
153 const string key = PathUtil::ToUnixPath(szAssetPath);
154 const auto lowerBound = std::lower_bound(m_index.cbegin(), m_index.cend(), key, SLessKey());
155 const auto upperBound = std::upper_bound(lowerBound, m_index.cend(), key, SLessKey());
156 return { lowerBound, upperBound };