rcjoblistmodel.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  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(const QueueElementID& toEscalate, int valueToEscalateTo)
  85. {
  86. for (auto foundInQueue = m_jobsInQueueLookup.find(toEscalate); foundInQueue != m_jobsInQueueLookup.end(); ++foundInQueue)
  87. {
  88. RCJob* job = foundInQueue.value();
  89. // this is a multi-map, so we have to keep going until it no longer matches.
  90. if (!job)
  91. {
  92. continue;
  93. }
  94. if (job->GetElementID() != toEscalate)
  95. {
  96. break;
  97. }
  98. if (job->JobEscalation() != valueToEscalateTo)
  99. {
  100. UpdateJobEscalation(job, valueToEscalateTo);
  101. }
  102. }
  103. }
  104. void RCJobListModel::UpdateJobEscalation(AssetProcessor::RCJob* rcJob, int valueToEscalateTo)
  105. {
  106. for (int idx = 0; idx < rowCount(); ++idx)
  107. {
  108. RCJob* job = getItem(idx);
  109. if (job == rcJob)
  110. {
  111. if (job->JobEscalation() != valueToEscalateTo)
  112. {
  113. job->SetJobEscalation(valueToEscalateTo);
  114. Q_EMIT dataChanged(index(idx, 0), index(idx, columnCount() - 1));
  115. }
  116. break;
  117. }
  118. }
  119. }
  120. void RCJobListModel::UpdateRow(int jobIndex)
  121. {
  122. Q_EMIT dataChanged(index(jobIndex, 0), index(jobIndex, columnCount() - 1));
  123. }
  124. QVariant RCJobListModel::data(const QModelIndex& index, int role) const
  125. {
  126. if (!index.isValid())
  127. {
  128. return QVariant();
  129. }
  130. if (index.row() >= itemCount())
  131. {
  132. return QVariant();
  133. }
  134. switch (role)
  135. {
  136. case jobIndexRole:
  137. return getItem(index.row())->GetJobEntry().m_jobRunKey;
  138. case stateRole:
  139. return RCJob::GetStateDescription(getItem(index.row())->GetState());
  140. case displayNameRole:
  141. return getItem(index.row())->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  142. case timeCreatedRole:
  143. return getItem(index.row())->GetTimeCreated().toString("hh:mm:ss.zzz");
  144. case timeLaunchedRole:
  145. return getItem(index.row())->GetTimeLaunched().toString("hh:mm:ss.zzz");
  146. case timeCompletedRole:
  147. return getItem(index.row())->GetTimeCompleted().toString("hh:mm:ss.zzz");
  148. case Qt::DisplayRole:
  149. switch (index.column())
  150. {
  151. case ColumnJobId:
  152. return getItem(index.row())->GetJobEntry().m_jobRunKey;
  153. case ColumnState:
  154. return RCJob::GetStateDescription(getItem(index.row())->GetState());
  155. case ColumnCommand:
  156. return getItem(index.row())->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  157. case ColumnCompleted:
  158. return getItem(index.row())->GetTimeCompleted().toString("hh:mm:ss.zzz");
  159. case ColumnPlatform:
  160. return QString::fromUtf8(getItem(index.row())->GetPlatformInfo().m_identifier.c_str());
  161. default:
  162. break;
  163. }
  164. default:
  165. break;
  166. }
  167. return QVariant();
  168. }
  169. int RCJobListModel::itemCount() const
  170. {
  171. return aznumeric_caster(m_jobs.size());
  172. }
  173. RCJob* RCJobListModel::getItem(int index) const
  174. {
  175. if (index >= 0 && index < m_jobs.size())
  176. {
  177. return m_jobs[index];
  178. }
  179. return nullptr; //invalid index
  180. }
  181. bool RCJobListModel::isEmpty()
  182. {
  183. return m_jobs.empty();
  184. }
  185. void RCJobListModel::addNewJob(RCJob* rcJob)
  186. {
  187. int posForInsert = aznumeric_caster(m_jobs.size());
  188. beginInsertRows(QModelIndex(), posForInsert, posForInsert);
  189. m_jobs.push_back(rcJob);
  190. #if defined(DEBUG_RCJOB_MODEL)
  191. 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());
  192. #endif
  193. if (rcJob->GetState() == RCJob::pending)
  194. {
  195. m_jobsInQueueLookup.insert(rcJob->GetElementID(), rcJob);
  196. }
  197. endInsertRows();
  198. }
  199. void RCJobListModel::markAsProcessing(RCJob* rcJob)
  200. {
  201. #if defined(DEBUG_RCJOB_MODEL)
  202. 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());
  203. #endif
  204. rcJob->SetState(RCJob::processing);
  205. rcJob->SetTimeLaunched(QDateTime::currentDateTime());
  206. m_jobsInFlight.insert(rcJob);
  207. for(int jobIndex = static_cast<int>(m_jobs.size()) - 1; jobIndex >= 0; --jobIndex)
  208. {
  209. if(m_jobs[jobIndex] == rcJob)
  210. {
  211. Q_EMIT dataChanged(index(jobIndex, 0, QModelIndex()), index(jobIndex, 0, QModelIndex()));
  212. return;
  213. }
  214. }
  215. AZ_TracePrintf(AssetProcessor::DebugChannel, "JobTrace jobIndex == -1!!! (%i %s,%s,%s)\n",
  216. rcJob, rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  217. rcJob->GetPlatformInfo().m_identifier.c_str(),
  218. rcJob->GetJobKey().toUtf8().constData());
  219. AZ_Assert(false, "Job not found!!!");
  220. }
  221. void RCJobListModel::markAsStarted(RCJob* rcJob)
  222. {
  223. #if defined(DEBUG_RCJOB_MODEL)
  224. 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());
  225. #endif
  226. auto foundInQueue = m_jobsInQueueLookup.find(rcJob->GetElementID());
  227. while ((foundInQueue != m_jobsInQueueLookup.end()) && (foundInQueue.value() == rcJob))
  228. {
  229. foundInQueue = m_jobsInQueueLookup.erase(foundInQueue);
  230. }
  231. }
  232. void RCJobListModel::markAsCompleted(RCJob* rcJob)
  233. {
  234. #if defined(DEBUG_RCJOB_MODEL)
  235. 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());
  236. #endif
  237. rcJob->SetTimeCompleted(QDateTime::currentDateTime());
  238. auto foundInQueue = m_jobsInQueueLookup.find(rcJob->GetElementID());
  239. while ((foundInQueue != m_jobsInQueueLookup.end()) && (foundInQueue.value() == rcJob))
  240. {
  241. foundInQueue = m_jobsInQueueLookup.erase(foundInQueue);
  242. }
  243. for (int jobIndex = static_cast<int>(m_jobs.size()) - 1; jobIndex >= 0; --jobIndex)
  244. {
  245. if(m_jobs[jobIndex] == rcJob)
  246. {
  247. m_jobsInFlight.remove(rcJob);
  248. // 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.
  249. {
  250. #if defined(DEBUG_RCJOB_MODEL)
  251. 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());
  252. #endif
  253. beginRemoveRows(QModelIndex(), jobIndex, jobIndex);
  254. m_jobs.erase(m_jobs.begin() + jobIndex);
  255. endRemoveRows();
  256. // Only completed jobs need to wait on a catalog write
  257. if (rcJob->GetState() == RCJob::completed)
  258. {
  259. const auto& id = rcJob->GetElementID();
  260. auto itr = m_finishedJobsNotInCatalog.find(id);
  261. if (itr != m_finishedJobsNotInCatalog.end())
  262. {
  263. itr.value()++;
  264. }
  265. else
  266. {
  267. m_finishedJobsNotInCatalog.insert(id, 1);
  268. }
  269. }
  270. rcJob->deleteLater();
  271. }
  272. return;
  273. }
  274. }
  275. AZ_Error(
  276. AssetProcessor::ConsoleChannel,
  277. false,
  278. "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",
  279. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  280. rcJob->GetPlatformInfo().m_identifier.c_str(),
  281. rcJob->GetJobKey().toUtf8().constData());
  282. }
  283. void RCJobListModel::markAsCataloged(const AssetProcessor::QueueElementID& check)
  284. {
  285. auto itr = m_finishedJobsNotInCatalog.find(check);
  286. if(itr == m_finishedJobsNotInCatalog.end())
  287. {
  288. 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());
  289. return;
  290. }
  291. itr.value()--;
  292. if (itr.value() == 0)
  293. {
  294. m_finishedJobsNotInCatalog.erase(itr);
  295. }
  296. }
  297. bool RCJobListModel::isInFlight(const AssetProcessor::QueueElementID& check) const
  298. {
  299. for (auto rcJob : m_jobsInFlight)
  300. {
  301. if (check == rcJob->GetElementID())
  302. {
  303. return true;
  304. }
  305. }
  306. return false;
  307. }
  308. int RCJobListModel::GetIndexOfJobByState(const QueueElementID& elementId, RCJob::JobState jobState)
  309. {
  310. for (int idx = 0; idx < rowCount(); ++idx)
  311. {
  312. RCJob* job = getItem(idx);
  313. if (job->GetState() == jobState && job->GetElementID() == elementId)
  314. {
  315. return idx;
  316. break;
  317. }
  318. }
  319. return -1; // invalid index
  320. }
  321. void RCJobListModel::EraseJobs(const SourceAssetReference& sourceAsset, AZStd::vector<RCJob*>& pendingJobs)
  322. {
  323. for (int jobIdx = 0; jobIdx < rowCount(); ++jobIdx)
  324. {
  325. RCJob* job = getItem(jobIdx);
  326. if (job->GetJobEntry().m_sourceAssetReference == sourceAsset)
  327. {
  328. const QueueElementID& target = job->GetElementID();
  329. if ((isInQueue(target)) || (isInFlight(target)))
  330. {
  331. // Its important that this still follows the 'cancelled' flow, so that other parts of the code can update their "in progress" and other maps.
  332. AZ_TracePrintf(
  333. AssetProcessor::DebugChannel,
  334. "Cancelling Job [%s, %s, %s] because the source file no longer exists.\n",
  335. target.GetSourceAssetReference().AbsolutePath().c_str(),
  336. target.GetPlatform().toUtf8().data(),
  337. target.GetJobDescriptor().toUtf8().data());
  338. // if a job is pending, it was never started and thus will never enter Finished state,
  339. // so simply changing its state to cancelled is not enough, collect them and return to rccontroller to process manually
  340. if (job->GetState() == RCJob::JobState::pending)
  341. {
  342. pendingJobs.push_back(job);
  343. }
  344. job->SetState(RCJob::JobState::cancelled);
  345. AssetBuilderSDK::JobCommandBus::Event(job->GetJobEntry().m_jobRunKey, &AssetBuilderSDK::JobCommandBus::Events::Cancel);
  346. UpdateRow(jobIdx);
  347. }
  348. }
  349. }
  350. }
  351. bool RCJobListModel::isInQueue(const AssetProcessor::QueueElementID& check) const
  352. {
  353. return m_jobsInQueueLookup.contains(check);
  354. }
  355. bool RCJobListModel::isWaitingOnCatalog(const QueueElementID& check) const
  356. {
  357. return m_finishedJobsNotInCatalog.contains(check);
  358. }
  359. void RCJobListModel::PerformHeuristicSearch(QString searchTerm, QString platform, QSet<QueueElementID>& found, AssetProcessor::JobIdEscalationList& escalationList, bool isStatusRequest, int searchRules)
  360. {
  361. int escalationValue = 0;
  362. if (isStatusRequest)
  363. {
  364. escalationValue = AssetProcessor::JobEscalation::ProcessAssetRequestStatusEscalation;
  365. }
  366. else
  367. {
  368. escalationValue = AssetProcessor::JobEscalation::ProcessAssetRequestSyncEscalation;
  369. }
  370. // try to narrowly exact-match the search term in case the search term refers to a specific actual source file:
  371. for (const RCJob* rcJob : m_jobs)
  372. {
  373. if ((platform != rcJob->GetPlatformInfo().m_identifier.c_str()) || (rcJob->GetState() != RCJob::pending))
  374. {
  375. continue;
  376. }
  377. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  378. if (input.endsWith(searchTerm, Qt::CaseInsensitive))
  379. {
  380. AZ_TracePrintf(
  381. AssetProcessor::DebugChannel,
  382. "Job Queue: Heuristic search found exact match (%s,%s,%s).\n",
  383. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  384. rcJob->GetPlatformInfo().m_identifier.c_str(),
  385. rcJob->GetJobKey().toUtf8().constData());
  386. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  387. escalationList.append(qMakePair(rcJob->GetJobEntry().m_jobRunKey, escalationValue));
  388. }
  389. }
  390. for (const RCJob* rcJob : m_jobsInFlight)
  391. {
  392. if (platform != rcJob->GetPlatformInfo().m_identifier.c_str())
  393. {
  394. continue;
  395. }
  396. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  397. if (input.endsWith(searchTerm, Qt::CaseInsensitive))
  398. {
  399. AZ_TracePrintf(
  400. AssetProcessor::DebugChannel,
  401. "Job Queue: Heuristic search found exact match (%s,%s,%s).\n",
  402. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  403. rcJob->GetPlatformInfo().m_identifier.c_str(),
  404. rcJob->GetJobKey().toUtf8().constData());
  405. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  406. }
  407. }
  408. if (!found.isEmpty() || searchRules == AzFramework::AssetSystem::RequestAssetStatus::SearchType::Exact)
  409. {
  410. return;
  411. }
  412. // broaden the heuristic. Try without extensions - that is, ignore everything after the dot.
  413. // if there are dashes, ignore them also. This is how you match "blah.dds" to actually mean "blah.tif"
  414. // since we have no idea what products will be generated by a source still in the queue until it runs
  415. int dotIndex = searchTerm.lastIndexOf('.');
  416. QStringRef searchTermWithNoExtension = searchTerm.midRef(0, dotIndex);
  417. if (dotIndex != -1)
  418. {
  419. for (const auto& rcJob : m_jobs)
  420. {
  421. if ((platform != rcJob->GetPlatformInfo().m_identifier.c_str()) || (rcJob->GetState() != RCJob::pending))
  422. {
  423. continue;
  424. }
  425. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  426. dotIndex = input.lastIndexOf('.');
  427. if (dotIndex != -1)
  428. {
  429. QStringRef testref = input.midRef(0, dotIndex);
  430. if (testref.endsWith(searchTermWithNoExtension, Qt::CaseInsensitive))
  431. {
  432. AZ_TracePrintf(
  433. AssetProcessor::DebugChannel,
  434. "Job Queue: Heuristic search found broad match (%s,%s,%s).\n",
  435. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  436. rcJob->GetPlatformInfo().m_identifier.c_str(),
  437. rcJob->GetJobKey().toUtf8().constData());
  438. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  439. escalationList.append(qMakePair(rcJob->GetJobEntry().m_jobRunKey, escalationValue));
  440. }
  441. }
  442. }
  443. for (const RCJob* rcJob : m_jobsInFlight)
  444. {
  445. if (platform != rcJob->GetPlatformInfo().m_identifier.c_str())
  446. {
  447. continue;
  448. }
  449. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  450. dotIndex = input.lastIndexOf('.');
  451. if (dotIndex != -1)
  452. {
  453. QStringRef testref = input.midRef(0, dotIndex);
  454. if (testref.endsWith(searchTermWithNoExtension, Qt::CaseInsensitive))
  455. {
  456. AZ_TracePrintf(
  457. AssetProcessor::DebugChannel,
  458. "Job Queue: Heuristic search found broad match (%s,%s,%s).\n",
  459. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  460. rcJob->GetPlatformInfo().m_identifier.c_str(),
  461. rcJob->GetJobKey().toUtf8().constData());
  462. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  463. }
  464. }
  465. }
  466. }
  467. if (!found.isEmpty())
  468. {
  469. return;
  470. }
  471. // broaden the heuristic further. Eliminate anything after the last underscore in the file name
  472. // (so blahblah_diff.dds just becomes blahblah) and then allow anything which has that file somewhere in it.
  473. int slashIndex = searchTerm.lastIndexOf('/');
  474. int dashIndex = searchTerm.lastIndexOf('_');
  475. QStringRef searchTermWithNoSuffix = searchTermWithNoExtension;
  476. if ((dashIndex != -1) && (slashIndex == -1) || (dashIndex > slashIndex))
  477. {
  478. searchTermWithNoSuffix = searchTermWithNoSuffix.mid(0, dashIndex);
  479. }
  480. for (const auto& rcJob : m_jobs)
  481. {
  482. if ((platform != rcJob->GetPlatformInfo().m_identifier.c_str()) || (rcJob->GetState() != RCJob::pending))
  483. {
  484. continue;
  485. }
  486. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  487. if (input.contains(searchTermWithNoSuffix, Qt::CaseInsensitive)) //notice here that we use simply CONTAINS instead of endswith - this can potentially be very broad!
  488. {
  489. AZ_TracePrintf(
  490. AssetProcessor::DebugChannel,
  491. "Job Queue: Heuristic search found ultra-broad match (%s,%s,%s).\n",
  492. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  493. rcJob->GetPlatformInfo().m_identifier.c_str(),
  494. rcJob->GetJobKey().toUtf8().constData());
  495. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  496. escalationList.append(qMakePair(rcJob->GetJobEntry().m_jobRunKey, escalationValue));
  497. }
  498. }
  499. for (const RCJob* rcJob : m_jobsInFlight)
  500. {
  501. if (platform != rcJob->GetPlatformInfo().m_identifier.c_str())
  502. {
  503. continue;
  504. }
  505. QString input = rcJob->GetJobEntry().m_sourceAssetReference.RelativePath().c_str();
  506. if (input.contains(searchTermWithNoSuffix, Qt::CaseInsensitive)) //notice here that we use simply CONTAINS instead of endswith - this can potentially be very broad!
  507. {
  508. AZ_TracePrintf(
  509. AssetProcessor::DebugChannel,
  510. "Job Queue: Heuristic search found ultra-broad match (%s,%s,%s).\n",
  511. rcJob->GetJobEntry().GetAbsoluteSourcePath().toUtf8().constData(),
  512. rcJob->GetPlatformInfo().m_identifier.c_str(),
  513. rcJob->GetJobKey().toUtf8().constData());
  514. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  515. }
  516. }
  517. }
  518. void RCJobListModel::PerformUUIDSearch(AZ::Uuid searchUuid, QString platform, QSet<QueueElementID>& found, AssetProcessor::JobIdEscalationList& escalationList, bool isStatusRequest)
  519. {
  520. int escalationValue = 0;
  521. if (isStatusRequest)
  522. {
  523. escalationValue = AssetProcessor::JobEscalation::ProcessAssetRequestStatusEscalation;
  524. }
  525. else
  526. {
  527. escalationValue = AssetProcessor::JobEscalation::ProcessAssetRequestSyncEscalation;
  528. }
  529. for (const RCJob* rcJob : m_jobs)
  530. {
  531. if ((platform != rcJob->GetPlatformInfo().m_identifier.c_str()) || (rcJob->GetState() != RCJob::pending))
  532. {
  533. continue;
  534. }
  535. if (rcJob->GetJobEntry().m_sourceFileUUID == searchUuid)
  536. {
  537. found.insert(QueueElementID(rcJob->GetJobEntry().m_sourceAssetReference, platform, rcJob->GetJobKey()));
  538. escalationList.append(qMakePair(rcJob->GetJobEntry().m_jobRunKey, escalationValue));
  539. }
  540. }
  541. }
  542. }// namespace AssetProcessor