rcjoblistmodel.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "rcjoblistmodel.h"
  9. // uncomment this in order to add additional verbose log output for this class.
  10. // can drastically slow down function since this class is a hotspot
  11. // #define DEBUG_RCJOB_MODEL
  12. namespace AssetProcessor
  13. {
  14. RCJobListModel::RCJobListModel(QObject* parent)
  15. : QAbstractItemModel(parent)
  16. {
  17. }
  18. int RCJobListModel::rowCount(const QModelIndex& parent) const
  19. {
  20. if (parent.isValid())
  21. {
  22. return 0;
  23. }
  24. return itemCount();
  25. }
  26. QModelIndex RCJobListModel::parent(const QModelIndex& /*index*/) const
  27. {
  28. return QModelIndex();
  29. }
  30. QModelIndex RCJobListModel::index(int row, int column, const QModelIndex& parent) const
  31. {
  32. if (row >= rowCount(parent) || column >= columnCount(parent))
  33. {
  34. return QModelIndex();
  35. }
  36. return createIndex(row, column);
  37. }
  38. int RCJobListModel::columnCount(const QModelIndex& parent) const
  39. {
  40. return parent.isValid() ? 0 : Column::Max;
  41. }
  42. QVariant RCJobListModel::headerData(int section, Qt::Orientation orientation, int role) const
  43. {
  44. if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
  45. {
  46. switch (section)
  47. {
  48. case ColumnState:
  49. return tr("State");
  50. case ColumnJobId:
  51. return tr("Job Id");
  52. case ColumnCommand:
  53. return tr("Asset");
  54. case ColumnCompleted:
  55. return tr("Completed");
  56. case ColumnPlatform:
  57. return tr("Platform");
  58. default:
  59. break;
  60. }
  61. }
  62. return QAbstractItemModel::headerData(section, orientation, role);
  63. }
  64. unsigned int RCJobListModel::jobsInFlight() const
  65. {
  66. return m_jobsInFlight.size();
  67. }
  68. unsigned int RCJobListModel::jobsInQueueWithoutMissingDependencies() const
  69. {
  70. unsigned int jobsWithNoMissingDependencies = 0;
  71. for (const auto& job : m_jobsInQueueLookup)
  72. {
  73. if (!job->HasMissingSourceDependency())
  74. {
  75. ++jobsWithNoMissingDependencies;
  76. }
  77. }
  78. return jobsWithNoMissingDependencies;
  79. }
  80. unsigned int RCJobListModel::jobsPendingCatalog() const
  81. {
  82. return m_finishedJobsNotInCatalog.count();
  83. }
  84. void RCJobListModel::UpdateJobEscalation(AssetProcessor::RCJob* rcJob, int jobEscalation)
  85. {
  86. for (int idx = 0; idx < rowCount(); ++idx)
  87. {
  88. RCJob* job = getItem(idx);
  89. if (job == rcJob)
  90. {
  91. rcJob->SetJobEscalation(jobEscalation);
  92. Q_EMIT dataChanged(index(idx, 0), index(idx, columnCount() - 1));
  93. break;
  94. }
  95. }
  96. }
  97. void RCJobListModel::UpdateRow(int jobIndex)
  98. {
  99. Q_EMIT dataChanged(index(jobIndex, 0), index(jobIndex, columnCount() - 1));
  100. }
  101. QVariant RCJobListModel::data(const QModelIndex& index, int role) const
  102. {
  103. if (!index.isValid())
  104. {
  105. return QVariant();
  106. }
  107. if (index.row() >= itemCount())
  108. {
  109. return QVariant();
  110. }
  111. switch (role)
  112. {
  113. case jobIndexRole:
  114. return getItem(index.row())->GetJobEntry().m_jobRunKey;
  115. case stateRole:
  116. return RCJob::GetStateDescription(getItem(index.row())->GetState());
  117. case displayNameRole:
  118. return getItem(index.row())->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  119. case timeCreatedRole:
  120. return getItem(index.row())->GetTimeCreated().toString("hh:mm:ss.zzz");
  121. case timeLaunchedRole:
  122. return getItem(index.row())->GetTimeLaunched().toString("hh:mm:ss.zzz");
  123. case timeCompletedRole:
  124. return getItem(index.row())->GetTimeCompleted().toString("hh:mm:ss.zzz");
  125. case Qt::DisplayRole:
  126. switch (index.column())
  127. {
  128. case ColumnJobId:
  129. return getItem(index.row())->GetJobEntry().m_jobRunKey;
  130. case ColumnState:
  131. return RCJob::GetStateDescription(getItem(index.row())->GetState());
  132. case ColumnCommand:
  133. return getItem(index.row())->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  134. case ColumnCompleted:
  135. return getItem(index.row())->GetTimeCompleted().toString("hh:mm:ss.zzz");
  136. case ColumnPlatform:
  137. return QString::fromUtf8(getItem(index.row())->GetPlatformInfo().m_identifier.c_str());
  138. default:
  139. break;
  140. }
  141. default:
  142. break;
  143. }
  144. return QVariant();
  145. }
  146. int RCJobListModel::itemCount() const
  147. {
  148. return aznumeric_caster(m_jobs.size());
  149. }
  150. RCJob* RCJobListModel::getItem(int index) const
  151. {
  152. if (index >= 0 && index < m_jobs.size())
  153. {
  154. return m_jobs[index];
  155. }
  156. return nullptr; //invalid index
  157. }
  158. bool RCJobListModel::isEmpty()
  159. {
  160. return m_jobs.empty();
  161. }
  162. void RCJobListModel::addNewJob(RCJob* rcJob)
  163. {
  164. int posForInsert = aznumeric_caster(m_jobs.size());
  165. beginInsertRows(QModelIndex(), posForInsert, posForInsert);
  166. m_jobs.push_back(rcJob);
  167. #if defined(DEBUG_RCJOB_MODEL)
  168. AZ_TracePrintf(AssetProcessor::DebugChannel, "JobTrace AddNewJob(%i %s,%s,%s)\n", rcJob, rcJob->GetInputFileAbsolutePath().toUtf8().constData(), rcJob->GetPlatformInfo().m_identifier.c_str(), rcJob->GetJobKey().toUtf8().constData());
  169. #endif
  170. if (rcJob->GetState() == RCJob::pending)
  171. {
  172. m_jobsInQueueLookup.insert(rcJob->GetElementID(), rcJob);
  173. }
  174. endInsertRows();
  175. }
  176. void RCJobListModel::markAsProcessing(RCJob* rcJob)
  177. {
  178. #if defined(DEBUG_RCJOB_MODEL)
  179. AZ_TracePrintf(AssetProcessor::DebugChannel, "JobTrace markAsProcessing(%i %s,%s,%s)\n", rcJob, rcJob->GetJobEntry().m_databaseSourceName.toUtf8().constData(), rcJob->GetPlatformInfo().m_identifier.c_str(), rcJob->GetJobKey().toUtf8().constData());
  180. #endif
  181. rcJob->SetState(RCJob::processing);
  182. rcJob->SetTimeLaunched(QDateTime::currentDateTime());
  183. m_jobsInFlight.insert(rcJob);
  184. for(int jobIndex = static_cast<int>(m_jobs.size()) - 1; jobIndex >= 0; --jobIndex)
  185. {
  186. if(m_jobs[jobIndex] == rcJob)
  187. {
  188. Q_EMIT dataChanged(index(jobIndex, 0, QModelIndex()), index(jobIndex, 0, QModelIndex()));
  189. return;
  190. }
  191. }
  192. AZ_TracePrintf(AssetProcessor::DebugChannel, "JobTrace jobIndex == -1!!! (%i %s,%s,%s)\n",
  193. rcJob, rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  194. rcJob->GetPlatformInfo().m_identifier.c_str(),
  195. rcJob->GetJobKey().toUtf8().constData());
  196. AZ_Assert(false, "Job not found!!!");
  197. }
  198. void RCJobListModel::markAsStarted(RCJob* rcJob)
  199. {
  200. #if defined(DEBUG_RCJOB_MODEL)
  201. AZ_TracePrintf(AssetProcessor::DebugChannel, "JobTrace markAsStarted(%i %s,%s,%s)\n", rcJob, rcJob->GetInputFileAbsolutePath().toUtf8().constData(), rcJob->GetPlatformInfo().m_identifier.c_str(), rcJob->GetJobKey().toUtf8().constData());
  202. #endif
  203. auto foundInQueue = m_jobsInQueueLookup.find(rcJob->GetElementID());
  204. while ((foundInQueue != m_jobsInQueueLookup.end()) && (foundInQueue.value() == rcJob))
  205. {
  206. foundInQueue = m_jobsInQueueLookup.erase(foundInQueue);
  207. }
  208. }
  209. void RCJobListModel::markAsCompleted(RCJob* rcJob)
  210. {
  211. #if defined(DEBUG_RCJOB_MODEL)
  212. AZ_TracePrintf(AssetProcessor::DebugChannel, "JobTrace markAsCompleted(%i %s,%s,%s)\n", rcJob, rcJob->GetInputFileAbsolutePath().toUtf8().constData(), rcJob->GetPlatformInfo().m_identifier.c_str(), rcJob->GetJobKey().toUtf8().constData());
  213. #endif
  214. rcJob->SetTimeCompleted(QDateTime::currentDateTime());
  215. auto foundInQueue = m_jobsInQueueLookup.find(rcJob->GetElementID());
  216. while ((foundInQueue != m_jobsInQueueLookup.end()) && (foundInQueue.value() == rcJob))
  217. {
  218. foundInQueue = m_jobsInQueueLookup.erase(foundInQueue);
  219. }
  220. for (int jobIndex = static_cast<int>(m_jobs.size()) - 1; jobIndex >= 0; --jobIndex)
  221. {
  222. if(m_jobs[jobIndex] == rcJob)
  223. {
  224. m_jobsInFlight.remove(rcJob);
  225. // remove it from the list and delete it - there is a separate model that keeps track for the GUI so no need to keep jobs around.
  226. {
  227. #if defined(DEBUG_RCJOB_MODEL)
  228. AZ_TracePrintf(AssetProcessor::DebugChannel, "JobTrace =>JobCompleted(%i %s,%s,%s)\n", rcJob, rcJob->GetJobEntry().m_databaseSourceName.toUtf8().constData(), rcJob->GetPlatformInfo().m_identifier.c_str(), rcJob->GetJobKey().toUtf8().constData());
  229. #endif
  230. beginRemoveRows(QModelIndex(), jobIndex, jobIndex);
  231. m_jobs.erase(m_jobs.begin() + jobIndex);
  232. endRemoveRows();
  233. // Only completed jobs need to wait on a catalog write
  234. if (rcJob->GetState() == RCJob::completed)
  235. {
  236. const auto& id = rcJob->GetElementID();
  237. auto itr = m_finishedJobsNotInCatalog.find(id);
  238. if (itr != m_finishedJobsNotInCatalog.end())
  239. {
  240. itr.value()++;
  241. }
  242. else
  243. {
  244. m_finishedJobsNotInCatalog.insert(id, 1);
  245. }
  246. }
  247. rcJob->deleteLater();
  248. }
  249. return;
  250. }
  251. }
  252. AZ_Error(
  253. AssetProcessor::ConsoleChannel,
  254. false,
  255. "Programmer Error: Could not mark job for file %s as completed, job was not tracked in the m_jobs container. It was either already finished, or never queued. (platform:%s, job key:%s)\n",
  256. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  257. rcJob->GetPlatformInfo().m_identifier.c_str(),
  258. rcJob->GetJobKey().toUtf8().constData());
  259. }
  260. void RCJobListModel::markAsCataloged(const AssetProcessor::QueueElementID& check)
  261. {
  262. auto itr = m_finishedJobsNotInCatalog.find(check);
  263. if(itr == m_finishedJobsNotInCatalog.end())
  264. {
  265. AZ_Assert(false, "Attempting to mark a job as written to the catalog before the job has been put in the waiting queue! %s", check.GetSourceAssetReference().AbsolutePath().c_str());
  266. return;
  267. }
  268. itr.value()--;
  269. if (itr.value() == 0)
  270. {
  271. m_finishedJobsNotInCatalog.erase(itr);
  272. }
  273. }
  274. bool RCJobListModel::isInFlight(const AssetProcessor::QueueElementID& check) const
  275. {
  276. for (auto rcJob : m_jobsInFlight)
  277. {
  278. if (check == rcJob->GetElementID())
  279. {
  280. return true;
  281. }
  282. }
  283. return false;
  284. }
  285. int RCJobListModel::GetIndexOfJobByState(const QueueElementID& elementId, RCJob::JobState jobState)
  286. {
  287. for (int idx = 0; idx < rowCount(); ++idx)
  288. {
  289. RCJob* job = getItem(idx);
  290. if (job->GetState() == jobState && job->GetElementID() == elementId)
  291. {
  292. return idx;
  293. break;
  294. }
  295. }
  296. return -1; // invalid index
  297. }
  298. void RCJobListModel::EraseJobs(const SourceAssetReference& sourceAsset, AZStd::vector<RCJob*>& pendingJobs)
  299. {
  300. for (int jobIdx = 0; jobIdx < rowCount(); ++jobIdx)
  301. {
  302. RCJob* job = getItem(jobIdx);
  303. if (job->GetJobEntry().m_sourceAssetReference == sourceAsset)
  304. {
  305. const QueueElementID& target = job->GetElementID();
  306. if ((isInQueue(target)) || (isInFlight(target)))
  307. {
  308. // Its important that this still follows the 'cancelled' flow, so that other parts of the code can update their "in progress" and other maps.
  309. AZ_TracePrintf(
  310. AssetProcessor::DebugChannel,
  311. "Cancelling Job [%s, %s, %s] because the source file no longer exists.\n",
  312. target.GetSourceAssetReference().AbsolutePath().c_str(),
  313. target.GetPlatform().toUtf8().data(),
  314. target.GetJobDescriptor().toUtf8().data());
  315. // if a job is pending, it was never started and thus will never enter Finished state,
  316. // so simply changing its state to cancelled is not enough, collect them and return to rccontroller to process manually
  317. if (job->GetState() == RCJob::JobState::pending)
  318. {
  319. pendingJobs.push_back(job);
  320. }
  321. job->SetState(RCJob::JobState::cancelled);
  322. AssetBuilderSDK::JobCommandBus::Event(job->GetJobEntry().m_jobRunKey, &AssetBuilderSDK::JobCommandBus::Events::Cancel);
  323. UpdateRow(jobIdx);
  324. }
  325. }
  326. }
  327. }
  328. bool RCJobListModel::isInQueue(const AssetProcessor::QueueElementID& check) const
  329. {
  330. return m_jobsInQueueLookup.contains(check);
  331. }
  332. bool RCJobListModel::isWaitingOnCatalog(const QueueElementID& check) const
  333. {
  334. return m_finishedJobsNotInCatalog.contains(check);
  335. }
  336. void RCJobListModel::PerformHeuristicSearch(QString searchTerm, QString platform, QSet<QueueElementID>& found, AssetProcessor::JobIdEscalationList& escalationList, bool isStatusRequest, int searchRules)
  337. {
  338. int escalationValue = 0;
  339. if (isStatusRequest)
  340. {
  341. escalationValue = AssetProcessor::JobEscalation::ProcessAssetRequestStatusEscalation;
  342. }
  343. else
  344. {
  345. escalationValue = AssetProcessor::JobEscalation::ProcessAssetRequestSyncEscalation;
  346. }
  347. // try to narrowly exact-match the search term in case the search term refers to a specific actual source file:
  348. for (const RCJob* rcJob : m_jobs)
  349. {
  350. if ((platform != rcJob->GetPlatformInfo().m_identifier.c_str()) || (rcJob->GetState() != RCJob::pending))
  351. {
  352. continue;
  353. }
  354. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  355. if (input.endsWith(searchTerm, Qt::CaseInsensitive))
  356. {
  357. AZ_TracePrintf(
  358. AssetProcessor::DebugChannel,
  359. "Job Queue: Heuristic search found exact match (%s,%s,%s).\n",
  360. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  361. rcJob->GetPlatformInfo().m_identifier.c_str(),
  362. rcJob->GetJobKey().toUtf8().constData());
  363. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  364. escalationList.append(qMakePair(rcJob->GetJobEntry().m_jobRunKey, escalationValue));
  365. }
  366. }
  367. for (const RCJob* rcJob : m_jobsInFlight)
  368. {
  369. if (platform != rcJob->GetPlatformInfo().m_identifier.c_str())
  370. {
  371. continue;
  372. }
  373. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  374. if (input.endsWith(searchTerm, Qt::CaseInsensitive))
  375. {
  376. AZ_TracePrintf(
  377. AssetProcessor::DebugChannel,
  378. "Job Queue: Heuristic search found exact match (%s,%s,%s).\n",
  379. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  380. rcJob->GetPlatformInfo().m_identifier.c_str(),
  381. rcJob->GetJobKey().toUtf8().constData());
  382. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  383. }
  384. }
  385. if (!found.isEmpty() || searchRules == AzFramework::AssetSystem::RequestAssetStatus::SearchType::Exact)
  386. {
  387. return;
  388. }
  389. // broaden the heuristic. Try without extensions - that is, ignore everything after the dot.
  390. // if there are dashes, ignore them also. This is how you match "blah.dds" to actually mean "blah.tif"
  391. // since we have no idea what products will be generated by a source still in the queue until it runs
  392. int dotIndex = searchTerm.lastIndexOf('.');
  393. QStringRef searchTermWithNoExtension = searchTerm.midRef(0, dotIndex);
  394. if (dotIndex != -1)
  395. {
  396. for (const auto& rcJob : m_jobs)
  397. {
  398. if ((platform != rcJob->GetPlatformInfo().m_identifier.c_str()) || (rcJob->GetState() != RCJob::pending))
  399. {
  400. continue;
  401. }
  402. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  403. dotIndex = input.lastIndexOf('.');
  404. if (dotIndex != -1)
  405. {
  406. QStringRef testref = input.midRef(0, dotIndex);
  407. if (testref.endsWith(searchTermWithNoExtension, Qt::CaseInsensitive))
  408. {
  409. AZ_TracePrintf(
  410. AssetProcessor::DebugChannel,
  411. "Job Queue: Heuristic search found broad match (%s,%s,%s).\n",
  412. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  413. rcJob->GetPlatformInfo().m_identifier.c_str(),
  414. rcJob->GetJobKey().toUtf8().constData());
  415. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  416. escalationList.append(qMakePair(rcJob->GetJobEntry().m_jobRunKey, escalationValue));
  417. }
  418. }
  419. }
  420. for (const RCJob* rcJob : m_jobsInFlight)
  421. {
  422. if (platform != rcJob->GetPlatformInfo().m_identifier.c_str())
  423. {
  424. continue;
  425. }
  426. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  427. dotIndex = input.lastIndexOf('.');
  428. if (dotIndex != -1)
  429. {
  430. QStringRef testref = input.midRef(0, dotIndex);
  431. if (testref.endsWith(searchTermWithNoExtension, Qt::CaseInsensitive))
  432. {
  433. AZ_TracePrintf(
  434. AssetProcessor::DebugChannel,
  435. "Job Queue: Heuristic search found broad match (%s,%s,%s).\n",
  436. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  437. rcJob->GetPlatformInfo().m_identifier.c_str(),
  438. rcJob->GetJobKey().toUtf8().constData());
  439. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  440. }
  441. }
  442. }
  443. }
  444. if (!found.isEmpty())
  445. {
  446. return;
  447. }
  448. // broaden the heuristic further. Eliminate anything after the last underscore in the file name
  449. // (so blahblah_diff.dds just becomes blahblah) and then allow anything which has that file somewhere in it.
  450. int slashIndex = searchTerm.lastIndexOf('/');
  451. int dashIndex = searchTerm.lastIndexOf('_');
  452. QStringRef searchTermWithNoSuffix = searchTermWithNoExtension;
  453. if ((dashIndex != -1) && (slashIndex == -1) || (dashIndex > slashIndex))
  454. {
  455. searchTermWithNoSuffix = searchTermWithNoSuffix.mid(0, dashIndex);
  456. }
  457. for (const auto& rcJob : m_jobs)
  458. {
  459. if ((platform != rcJob->GetPlatformInfo().m_identifier.c_str()) || (rcJob->GetState() != RCJob::pending))
  460. {
  461. continue;
  462. }
  463. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  464. if (input.contains(searchTermWithNoSuffix, Qt::CaseInsensitive)) //notice here that we use simply CONTAINS instead of endswith - this can potentially be very broad!
  465. {
  466. AZ_TracePrintf(
  467. AssetProcessor::DebugChannel,
  468. "Job Queue: Heuristic search found ultra-broad match (%s,%s,%s).\n",
  469. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  470. rcJob->GetPlatformInfo().m_identifier.c_str(),
  471. rcJob->GetJobKey().toUtf8().constData());
  472. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  473. escalationList.append(qMakePair(rcJob->GetJobEntry().m_jobRunKey, escalationValue));
  474. }
  475. }
  476. for (const RCJob* rcJob : m_jobsInFlight)
  477. {
  478. if (platform != rcJob->GetPlatformInfo().m_identifier.c_str())
  479. {
  480. continue;
  481. }
  482. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  483. if (input.contains(searchTermWithNoSuffix, Qt::CaseInsensitive)) //notice here that we use simply CONTAINS instead of endswith - this can potentially be very broad!
  484. {
  485. AZ_TracePrintf(
  486. AssetProcessor::DebugChannel,
  487. "Job Queue: Heuristic search found ultra-broad match (%s,%s,%s).\n",
  488. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  489. rcJob->GetPlatformInfo().m_identifier.c_str(),
  490. rcJob->GetJobKey().toUtf8().constData());
  491. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  492. }
  493. }
  494. }
  495. void RCJobListModel::PerformUUIDSearch(AZ::Uuid searchUuid, QString platform, QSet<QueueElementID>& found, AssetProcessor::JobIdEscalationList& escalationList, bool isStatusRequest)
  496. {
  497. int escalationValue = 0;
  498. if (isStatusRequest)
  499. {
  500. escalationValue = AssetProcessor::JobEscalation::ProcessAssetRequestStatusEscalation;
  501. }
  502. else
  503. {
  504. escalationValue = AssetProcessor::JobEscalation::ProcessAssetRequestSyncEscalation;
  505. }
  506. for (const RCJob* rcJob : m_jobs)
  507. {
  508. if ((platform != rcJob->GetPlatformInfo().m_identifier.c_str()) || (rcJob->GetState() != RCJob::pending))
  509. {
  510. continue;
  511. }
  512. if (rcJob->GetJobEntry().m_sourceFileUUID == searchUuid)
  513. {
  514. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  515. escalationList.append(qMakePair(rcJob->GetJobEntry().m_jobRunKey, escalationValue));
  516. }
  517. }
  518. }
  519. }// namespace AssetProcessor