scriptable_catalog_names.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. #include "scriptable_catalog_names.h"
  2. #include <algorithm>
  3. #include <cstddef>
  4. #include <cstdint>
  5. #include <span>
  6. #include <string_view>
  7. #include <utility>
  8. #include <vector>
  9. #include "../../../middleware/content/packages/tables/authored_placement_reader.h"
  10. #include "../../../middleware/content/packages/tables/component_container_reader.h"
  11. #include "../../../middleware/content/packages/tables/container_placement_reader.h"
  12. #include "../../../middleware/content/packages/tables/scenario_reader.h"
  13. #include "../../../middleware/content/packages/tables/slot_descriptor_reader.h"
  14. #include "../../../middleware/content/packages/tables/static_spatial_candidate_reader.h"
  15. #include "../../../state/build_data/runtime.h"
  16. #include "../../../state/build_data/scriptables/inline_name_evidence.h"
  17. #include "../../../state/content/content_catalog.h"
  18. namespace sunrise::client::content::activity::scriptables::internal {
  19. namespace {
  20. namespace catalog = state::build_data::scriptables;
  21. namespace names_state = state::build_data::hash_names;
  22. namespace tables = middleware::content::packages::tables;
  23. struct HashDefinition final {
  24. std::uint32_t hash{};
  25. std::uint32_t definitionRow{};
  26. };
  27. [[nodiscard]] bool cancelled(NameCancelCheck check) noexcept {
  28. return check != nullptr && check();
  29. }
  30. /**
  31. * Finds one identifier name by its hash.
  32. * @param hashNames Rows sorted by hash, or null for the table State publishes.
  33. * @param hash Name hash.
  34. * @param name Receives the matching row.
  35. * @return True when the chosen table holds that exact hash.
  36. */
  37. [[nodiscard]] bool find_identifier(const std::vector<names_state::Name>* hashNames,
  38. std::uint32_t hash,
  39. names_state::Name& name) noexcept {
  40. if (hashNames == nullptr) {
  41. return state::build_data::find_hash_name(hash, name);
  42. }
  43. const auto found =
  44. std::lower_bound(hashNames->begin(),
  45. hashNames->end(),
  46. hash,
  47. [](const names_state::Name& row, std::uint32_t value) noexcept {
  48. return row.hash < value;
  49. });
  50. if (found == hashNames->end() || found->hash != hash) {
  51. return false;
  52. }
  53. name = *found;
  54. return true;
  55. }
  56. [[nodiscard]] bool same_candidate(const catalog::NameCandidate& candidate,
  57. std::string_view value,
  58. catalog::NameProvenance provenance,
  59. std::uint32_t sourceTag,
  60. std::uint32_t sourceClassId) noexcept {
  61. return candidate.provenance == provenance && candidate.length == value.size()
  62. && candidate.sourceTag == sourceTag && candidate.sourceClassId == sourceClassId
  63. && std::equal(value.begin(), value.end(), candidate.value.begin());
  64. }
  65. /** Appends one unique bounded name candidate at its stated evidence tier. */
  66. template <typename NameRow>
  67. [[nodiscard]] bool append_candidate(catalog::Snapshot& output,
  68. NameRow& name,
  69. std::string_view value,
  70. catalog::NameProvenance provenance,
  71. std::uint32_t sourceTag,
  72. std::uint32_t sourceClassId = 0) {
  73. if (value.empty() || value.size() >= catalog::kNameCapacity) {
  74. return true;
  75. }
  76. const std::size_t begin = name.firstCandidate;
  77. const std::size_t end = begin + name.candidateCount;
  78. for (std::size_t index = begin; index < end; ++index) {
  79. if (same_candidate(
  80. output.nameCandidates[index], value, provenance, sourceTag, sourceClassId)) {
  81. return true;
  82. }
  83. }
  84. if (output.nameCandidates.size() >= catalog::kNoRow || name.candidateCount == catalog::kNoRow) {
  85. return false;
  86. }
  87. catalog::NameCandidate candidate{};
  88. std::copy(value.begin(), value.end(), candidate.value.begin());
  89. candidate.length = static_cast<std::uint16_t>(value.size());
  90. candidate.provenance = provenance;
  91. candidate.sourceTag = sourceTag;
  92. candidate.sourceClassId = sourceClassId;
  93. output.nameCandidates.push_back(candidate);
  94. ++name.candidateCount;
  95. return true;
  96. }
  97. /** Selects one display value while retaining every package source that supplied it. */
  98. [[nodiscard]] std::uint32_t uniform_value_candidate(const catalog::Snapshot& output,
  99. std::uint32_t first,
  100. std::uint32_t count) noexcept {
  101. if (count == 0 || first >= output.nameCandidates.size()) {
  102. return catalog::kNoRow;
  103. }
  104. const catalog::NameCandidate& expected = output.nameCandidates[first];
  105. for (std::uint32_t offset = 1; offset < count; ++offset) {
  106. const std::size_t row = static_cast<std::size_t>(first) + offset;
  107. if (row >= output.nameCandidates.size()) {
  108. return catalog::kNoRow;
  109. }
  110. const catalog::NameCandidate& candidate = output.nameCandidates[row];
  111. if (candidate.length != expected.length
  112. || !std::equal(expected.value.begin(),
  113. expected.value.begin() + expected.length,
  114. candidate.value.begin())) {
  115. return catalog::kNoRow;
  116. }
  117. }
  118. return first;
  119. }
  120. /** Selects a hash name only when the strongest available evidence tier is unique. */
  121. [[nodiscard]] bool resolve_one_hash_name(catalog::Snapshot& output,
  122. std::span<const InlineName> inlineNames,
  123. std::span<const state::content::Definition> definitions,
  124. std::span<const HashDefinition> hashDefinitions,
  125. const std::vector<names_state::Name>* hashNames,
  126. NameCancelCheck cancel,
  127. std::uint32_t hash) {
  128. catalog::Name name{};
  129. name.hash = hash;
  130. name.firstCandidate = static_cast<std::uint32_t>(output.nameCandidates.size());
  131. const auto rawFirst =
  132. std::lower_bound(output.inlineNameCandidates.begin(),
  133. output.inlineNameCandidates.end(),
  134. hash,
  135. [](const catalog::InlineNameCandidate& candidate,
  136. std::uint32_t value) noexcept { return candidate.hash < value; });
  137. for (auto current = rawFirst;
  138. current != output.inlineNameCandidates.end() && current->hash == hash;
  139. ++current) {
  140. if (cancelled(cancel) || current->firstByte > output.inlineNameBytes.size()
  141. || current->byteCount > output.inlineNameBytes.size() - current->firstByte) {
  142. return false;
  143. }
  144. const char* value =
  145. reinterpret_cast<const char*>(output.inlineNameBytes.data() + current->firstByte);
  146. if (!append_candidate(output,
  147. name,
  148. std::string_view(value, current->byteCount),
  149. catalog::NameProvenance::packageInline,
  150. 0)) {
  151. return false;
  152. }
  153. }
  154. for (const InlineName& candidate : inlineNames) {
  155. if (cancelled(cancel)) {
  156. return false;
  157. }
  158. if (candidate.hash == hash
  159. && !append_candidate(output,
  160. name,
  161. candidate.value,
  162. catalog::NameProvenance::packageInline,
  163. candidate.sourceTag)) {
  164. return false;
  165. }
  166. }
  167. const std::uint32_t inlineCount = name.candidateCount;
  168. const auto first =
  169. std::lower_bound(hashDefinitions.begin(),
  170. hashDefinitions.end(),
  171. hash,
  172. [](const HashDefinition& definition, std::uint32_t value) noexcept {
  173. return definition.hash < value;
  174. });
  175. for (auto current = first; current != hashDefinitions.end() && current->hash == hash;
  176. ++current) {
  177. if (cancelled(cancel) || current->definitionRow >= definitions.size()) {
  178. return false;
  179. }
  180. const state::content::Definition& definition = definitions[current->definitionRow];
  181. if (!append_candidate(output,
  182. name,
  183. std::string_view(definition.name.data(), definition.nameLength),
  184. catalog::NameProvenance::packagePath,
  185. definition.tag,
  186. definition.classId)) {
  187. return false;
  188. }
  189. }
  190. const std::uint32_t pathCount = name.candidateCount - inlineCount;
  191. if (cancelled(cancel)) {
  192. return false;
  193. }
  194. names_state::Name identifier{};
  195. if (find_identifier(hashNames, hash, identifier)
  196. && !append_candidate(output,
  197. name,
  198. std::string_view(identifier.name.data(), identifier.nameLength),
  199. catalog::NameProvenance::packageIdentifierCandidate,
  200. 0)) {
  201. return false;
  202. }
  203. std::uint32_t bestFirst = name.firstCandidate;
  204. std::uint32_t bestCount = inlineCount;
  205. catalog::NameProvenance best = catalog::NameProvenance::packageInline;
  206. if (bestCount == 0 && pathCount != 0) {
  207. bestFirst += inlineCount;
  208. bestCount = pathCount;
  209. best = catalog::NameProvenance::packagePath;
  210. }
  211. if (bestCount == 0 && name.candidateCount != inlineCount + pathCount) {
  212. bestFirst += inlineCount + pathCount;
  213. bestCount = name.candidateCount - inlineCount - pathCount;
  214. best = catalog::NameProvenance::packageIdentifierCandidate;
  215. }
  216. name.selectedCandidate = uniform_value_candidate(output, bestFirst, bestCount);
  217. if (name.selectedCandidate != catalog::kNoRow) {
  218. name.provenance = best;
  219. }
  220. output.names.push_back(name);
  221. return true;
  222. }
  223. /** Selects an exact package-definition name only when the distinct path is unique. */
  224. [[nodiscard]] bool resolve_one_tag_name(catalog::Snapshot& output,
  225. std::span<const state::content::Definition> definitions,
  226. NameCancelCheck cancel,
  227. std::uint32_t tag,
  228. std::uint32_t classId) {
  229. catalog::TagName name{};
  230. name.tag = tag;
  231. name.classId = classId;
  232. name.firstCandidate = static_cast<std::uint32_t>(output.nameCandidates.size());
  233. const auto first =
  234. std::lower_bound(definitions.begin(),
  235. definitions.end(),
  236. tag,
  237. [](const state::content::Definition& definition,
  238. std::uint32_t value) noexcept { return definition.tag < value; });
  239. for (auto current = first; current != definitions.end() && current->tag == tag; ++current) {
  240. if (cancelled(cancel)) {
  241. return false;
  242. }
  243. if (classId != 0 && current->classId != classId) {
  244. continue;
  245. }
  246. if (!append_candidate(output,
  247. name,
  248. std::string_view(current->name.data(), current->nameLength),
  249. catalog::NameProvenance::packagePath,
  250. current->tag,
  251. current->classId)) {
  252. return false;
  253. }
  254. }
  255. name.selectedCandidate =
  256. uniform_value_candidate(output, name.firstCandidate, name.candidateCount);
  257. if (name.selectedCandidate != catalog::kNoRow) {
  258. name.provenance = catalog::NameProvenance::packagePath;
  259. }
  260. output.tagNames.push_back(name);
  261. return true;
  262. }
  263. /** @return The exact sorted hash-name row, or kNoRow when the hash is unresolved. */
  264. [[nodiscard]] std::uint32_t hash_name_row(const catalog::Snapshot& output,
  265. std::uint32_t hash) noexcept {
  266. const auto found = std::lower_bound(
  267. output.names.begin(),
  268. output.names.end(),
  269. hash,
  270. [](const catalog::Name& row, std::uint32_t value) noexcept { return row.hash < value; });
  271. return found != output.names.end() && found->hash == hash
  272. ? static_cast<std::uint32_t>(found - output.names.begin())
  273. : catalog::kNoRow;
  274. }
  275. /** Finds one exact tag/class query row in the sorted package-definition name table. */
  276. [[nodiscard]] std::uint32_t
  277. tag_name_row(const catalog::Snapshot& output, std::uint32_t tag, std::uint32_t classId) noexcept {
  278. const std::pair<std::uint32_t, std::uint32_t> key{tag, classId};
  279. const auto found = std::lower_bound(
  280. output.tagNames.begin(),
  281. output.tagNames.end(),
  282. key,
  283. [](const catalog::TagName& row,
  284. const std::pair<std::uint32_t, std::uint32_t>& value) noexcept {
  285. return std::pair<std::uint32_t, std::uint32_t>{row.tag, row.classId} < value;
  286. });
  287. return found != output.tagNames.end() && found->tag == tag && found->classId == classId
  288. ? static_cast<std::uint32_t>(found - output.tagNames.begin())
  289. : catalog::kNoRow;
  290. }
  291. } // namespace
  292. /** Resolves authored hashes and exact installed-package definition tags in one snapshot. */
  293. bool resolve_names(catalog::Snapshot& output,
  294. std::span<const InlineName> inlineNames,
  295. const std::vector<state::content::Definition>* installed,
  296. const std::vector<names_state::Name>* hashNames,
  297. NameCancelCheck cancel) noexcept {
  298. try {
  299. std::vector<state::content::Definition> definitions{};
  300. if (installed != nullptr) {
  301. definitions = *installed;
  302. } else {
  303. definitions.resize(state::content::kDefinitionCatalogCapacity);
  304. std::size_t definitionCount = 0;
  305. if (!state::content::snapshot(definitions, definitionCount)) {
  306. return false;
  307. }
  308. definitions.resize(definitionCount);
  309. }
  310. std::sort(definitions.begin(),
  311. definitions.end(),
  312. [](const state::content::Definition& first,
  313. const state::content::Definition& second) noexcept {
  314. if (first.tag != second.tag) {
  315. return first.tag < second.tag;
  316. }
  317. if (first.classId != second.classId) {
  318. return first.classId < second.classId;
  319. }
  320. return std::string_view(first.name.data(), first.nameLength)
  321. < std::string_view(second.name.data(), second.nameLength);
  322. });
  323. if (cancelled(cancel)) {
  324. return false;
  325. }
  326. std::vector<HashDefinition> hashDefinitions{};
  327. hashDefinitions.reserve(definitions.size());
  328. for (std::size_t row = 0; row < definitions.size(); ++row) {
  329. const state::content::Definition& definition = definitions[row];
  330. hashDefinitions.push_back({catalog::inline_name_evidence::hash(std::as_bytes(std::span(
  331. definition.name.data(), definition.nameLength))),
  332. static_cast<std::uint32_t>(row)});
  333. }
  334. std::sort(
  335. hashDefinitions.begin(),
  336. hashDefinitions.end(),
  337. [&definitions](const HashDefinition& first, const HashDefinition& second) noexcept {
  338. if (first.hash != second.hash) {
  339. return first.hash < second.hash;
  340. }
  341. const state::content::Definition& firstDefinition =
  342. definitions[first.definitionRow];
  343. const state::content::Definition& secondDefinition =
  344. definitions[second.definitionRow];
  345. if (firstDefinition.tag != secondDefinition.tag) {
  346. return firstDefinition.tag < secondDefinition.tag;
  347. }
  348. if (firstDefinition.classId != secondDefinition.classId) {
  349. return firstDefinition.classId < secondDefinition.classId;
  350. }
  351. return std::string_view(firstDefinition.name.data(), firstDefinition.nameLength)
  352. < std::string_view(secondDefinition.name.data(),
  353. secondDefinition.nameLength);
  354. });
  355. if (cancelled(cancel)) {
  356. return false;
  357. }
  358. std::vector<std::uint32_t> hashes{};
  359. hashes.reserve(output.bubbles.size() + output.states.size() + output.slots.size());
  360. for (const catalog::Bubble& bubble : output.bubbles) {
  361. hashes.push_back(bubble.nameHash);
  362. }
  363. for (const catalog::State& state : output.states) {
  364. hashes.push_back(state.stateHash);
  365. }
  366. for (const catalog::Slot& slot : output.slots) {
  367. hashes.push_back(slot.nameHash);
  368. }
  369. if (cancelled(cancel)) {
  370. return false;
  371. }
  372. std::sort(hashes.begin(), hashes.end());
  373. hashes.erase(std::unique(hashes.begin(), hashes.end()), hashes.end());
  374. if (cancelled(cancel)) {
  375. return false;
  376. }
  377. output.names.reserve(hashes.size());
  378. for (const std::uint32_t hash : hashes) {
  379. if (cancelled(cancel)
  380. || !resolve_one_hash_name(
  381. output, inlineNames, definitions, hashDefinitions, hashNames, cancel, hash)) {
  382. return false;
  383. }
  384. }
  385. for (catalog::Bubble& bubble : output.bubbles) {
  386. if (cancelled(cancel)) {
  387. return false;
  388. }
  389. bubble.nameRow = hash_name_row(output, bubble.nameHash);
  390. }
  391. for (catalog::State& state : output.states) {
  392. if (cancelled(cancel)) {
  393. return false;
  394. }
  395. state.nameRow = hash_name_row(output, state.stateHash);
  396. }
  397. for (catalog::Slot& slot : output.slots) {
  398. if (cancelled(cancel)) {
  399. return false;
  400. }
  401. slot.nameRow = hash_name_row(output, slot.nameHash);
  402. }
  403. std::vector<std::pair<std::uint32_t, std::uint32_t>> tags{};
  404. tags.reserve(
  405. output.states.size() * 2 + output.objects.size() * 2 + output.descriptors.size()
  406. + output.references.size() + output.authoredPlacements.size() * 2
  407. + output.containerPlacementLists.size() * 2 + output.containerPlacementOwners.size()
  408. + output.containerPlacements.size() + output.containerPlacementConfigs.size()
  409. + output.staticSpatialTables.size() * 2 + output.staticSpatialOwners.size() * 3
  410. + output.staticSpatialInstances.size() + output.triggerVolumeTables.size()
  411. + output.triggerVolumeInstances.size() * 2);
  412. const auto offer_tag = [&tags](std::uint32_t tag, std::uint32_t classId) {
  413. if (tag != 0) {
  414. tags.emplace_back(tag, classId);
  415. }
  416. };
  417. for (const catalog::State& state : output.states) {
  418. if (cancelled(cancel)) {
  419. return false;
  420. }
  421. offer_tag(state.entryTag, tables::kSliceEntryClass);
  422. offer_tag(state.registryTag, tables::kObjectRegistryClass);
  423. }
  424. for (const catalog::Object& object : output.objects) {
  425. if (cancelled(cancel)) {
  426. return false;
  427. }
  428. offer_tag(object.registryTag, tables::kObjectRegistryClass);
  429. offer_tag(object.objectTag, tables::kObjectClass);
  430. }
  431. for (const catalog::Descriptor& descriptor : output.descriptors) {
  432. if (cancelled(cancel)) {
  433. return false;
  434. }
  435. offer_tag(descriptor.configTag, tables::kPlacedObjectClass);
  436. }
  437. for (const catalog::TypedReference& reference : output.references) {
  438. if (cancelled(cancel)) {
  439. return false;
  440. }
  441. offer_tag(reference.sourceConfigTag, tables::kPlacedObjectClass);
  442. }
  443. for (const catalog::AuthoredPlacement& placement : output.authoredPlacements) {
  444. if (cancelled(cancel)) {
  445. return false;
  446. }
  447. offer_tag(placement.objectListTag, tables::kAuthoredPlacementListClass);
  448. offer_tag(placement.classListTag, 0);
  449. }
  450. for (const catalog::ContainerPlacementList& list : output.containerPlacementLists) {
  451. if (cancelled(cancel)) {
  452. return false;
  453. }
  454. offer_tag(list.objectListTag, tables::kAuthoredPlacementListClass);
  455. if (list.resourceResolved) {
  456. offer_tag(list.resourceTag, list.resourceClass);
  457. }
  458. }
  459. for (const catalog::ContainerPlacementOwner& owner : output.containerPlacementOwners) {
  460. if (cancelled(cancel)) {
  461. return false;
  462. }
  463. offer_tag(owner.containerTag, tables::kContainerClass);
  464. }
  465. for (const catalog::ContainerPlacement& placement : output.containerPlacements) {
  466. if (cancelled(cancel)) {
  467. return false;
  468. }
  469. offer_tag(placement.classListTag, tables::kPlacedClassDefinitionClass);
  470. }
  471. for (const catalog::ContainerPlacementConfig& config : output.containerPlacementConfigs) {
  472. if (cancelled(cancel)) {
  473. return false;
  474. }
  475. offer_tag(config.configTag, tables::kPlacedConfigClass);
  476. }
  477. for (const catalog::EmbeddedPlacement& placement : output.embeddedPlacements) {
  478. if (cancelled(cancel)) {
  479. return false;
  480. }
  481. offer_tag(placement.classListTag, tables::kPlacedClassDefinitionClass);
  482. }
  483. for (const catalog::StaticSpatialTable& table : output.staticSpatialTables) {
  484. if (cancelled(cancel)) {
  485. return false;
  486. }
  487. offer_tag(table.tableTag, tables::kStaticSpatialTableClass);
  488. offer_tag(table.boundsTag, tables::kStaticSpatialBoundsTableClass);
  489. }
  490. for (const catalog::StaticSpatialOwner& owner : output.staticSpatialOwners) {
  491. if (cancelled(cancel)) {
  492. return false;
  493. }
  494. offer_tag(owner.containerTag, tables::kContainerClass);
  495. offer_tag(owner.objectListTag, tables::kAuthoredPlacementListClass);
  496. offer_tag(owner.parentTag, tables::kStaticSpatialParentClass);
  497. }
  498. for (const catalog::StaticSpatialInstance& instance : output.staticSpatialInstances) {
  499. if (cancelled(cancel)) {
  500. return false;
  501. }
  502. offer_tag(instance.resourceTag, 0);
  503. }
  504. for (const catalog::TriggerVolumeTable& table : output.triggerVolumeTables) {
  505. if (cancelled(cancel)) {
  506. return false;
  507. }
  508. offer_tag(table.configTag, tables::kPlacedConfigClass);
  509. }
  510. for (const catalog::TriggerVolumeInstance& instance : output.triggerVolumeInstances) {
  511. if (cancelled(cancel)) {
  512. return false;
  513. }
  514. offer_tag(instance.classDefinitionTag, tables::kPlacedClassDefinitionClass);
  515. offer_tag(instance.shapeResourceTag, 0);
  516. }
  517. std::sort(tags.begin(), tags.end());
  518. tags.erase(std::unique(tags.begin(), tags.end()), tags.end());
  519. if (cancelled(cancel)) {
  520. return false;
  521. }
  522. output.tagNames.reserve(tags.size());
  523. for (const auto& [tag, classId] : tags) {
  524. if (cancelled(cancel)
  525. || !resolve_one_tag_name(output, definitions, cancel, tag, classId)) {
  526. return false;
  527. }
  528. }
  529. for (catalog::State& state : output.states) {
  530. if (cancelled(cancel)) {
  531. return false;
  532. }
  533. state.entryNameRow = tag_name_row(output, state.entryTag, tables::kSliceEntryClass);
  534. state.registryNameRow =
  535. tag_name_row(output, state.registryTag, tables::kObjectRegistryClass);
  536. }
  537. for (catalog::Object& object : output.objects) {
  538. if (cancelled(cancel)) {
  539. return false;
  540. }
  541. object.registryNameRow =
  542. tag_name_row(output, object.registryTag, tables::kObjectRegistryClass);
  543. object.objectNameRow = tag_name_row(output, object.objectTag, tables::kObjectClass);
  544. }
  545. for (catalog::Descriptor& descriptor : output.descriptors) {
  546. if (cancelled(cancel)) {
  547. return false;
  548. }
  549. descriptor.configNameRow =
  550. tag_name_row(output, descriptor.configTag, tables::kPlacedObjectClass);
  551. }
  552. for (catalog::TypedReference& reference : output.references) {
  553. if (cancelled(cancel)) {
  554. return false;
  555. }
  556. reference.sourceConfigNameRow =
  557. tag_name_row(output, reference.sourceConfigTag, tables::kPlacedObjectClass);
  558. }
  559. for (catalog::AuthoredPlacement& placement : output.authoredPlacements) {
  560. if (cancelled(cancel)) {
  561. return false;
  562. }
  563. placement.objectListNameRow =
  564. tag_name_row(output, placement.objectListTag, tables::kAuthoredPlacementListClass);
  565. placement.classListNameRow = tag_name_row(output, placement.classListTag, 0);
  566. }
  567. for (catalog::ContainerPlacementList& list : output.containerPlacementLists) {
  568. if (cancelled(cancel)) {
  569. return false;
  570. }
  571. list.objectListNameRow =
  572. tag_name_row(output, list.objectListTag, tables::kAuthoredPlacementListClass);
  573. if (list.resourceResolved) {
  574. list.resourceNameRow = tag_name_row(output, list.resourceTag, list.resourceClass);
  575. }
  576. }
  577. for (catalog::ContainerPlacementOwner& owner : output.containerPlacementOwners) {
  578. if (cancelled(cancel)) {
  579. return false;
  580. }
  581. owner.containerNameRow =
  582. tag_name_row(output, owner.containerTag, tables::kContainerClass);
  583. }
  584. for (catalog::ContainerPlacement& placement : output.containerPlacements) {
  585. if (cancelled(cancel)) {
  586. return false;
  587. }
  588. placement.classListNameRow =
  589. tag_name_row(output, placement.classListTag, tables::kPlacedClassDefinitionClass);
  590. }
  591. for (catalog::ContainerPlacementConfig& config : output.containerPlacementConfigs) {
  592. if (cancelled(cancel)) {
  593. return false;
  594. }
  595. config.configNameRow =
  596. tag_name_row(output, config.configTag, tables::kPlacedConfigClass);
  597. }
  598. for (catalog::EmbeddedPlacement& placement : output.embeddedPlacements) {
  599. if (cancelled(cancel)) {
  600. return false;
  601. }
  602. placement.classListNameRow =
  603. tag_name_row(output, placement.classListTag, tables::kPlacedClassDefinitionClass);
  604. }
  605. for (catalog::StaticSpatialTable& table : output.staticSpatialTables) {
  606. if (cancelled(cancel)) {
  607. return false;
  608. }
  609. table.tableNameRow =
  610. tag_name_row(output, table.tableTag, tables::kStaticSpatialTableClass);
  611. table.boundsNameRow =
  612. tag_name_row(output, table.boundsTag, tables::kStaticSpatialBoundsTableClass);
  613. }
  614. for (catalog::StaticSpatialOwner& owner : output.staticSpatialOwners) {
  615. if (cancelled(cancel)) {
  616. return false;
  617. }
  618. owner.containerNameRow =
  619. tag_name_row(output, owner.containerTag, tables::kContainerClass);
  620. owner.objectListNameRow =
  621. tag_name_row(output, owner.objectListTag, tables::kAuthoredPlacementListClass);
  622. owner.parentNameRow =
  623. tag_name_row(output, owner.parentTag, tables::kStaticSpatialParentClass);
  624. }
  625. for (catalog::StaticSpatialInstance& instance : output.staticSpatialInstances) {
  626. if (cancelled(cancel)) {
  627. return false;
  628. }
  629. instance.resourceNameRow = tag_name_row(output, instance.resourceTag, 0);
  630. }
  631. for (catalog::TriggerVolumeTable& table : output.triggerVolumeTables) {
  632. if (cancelled(cancel)) {
  633. return false;
  634. }
  635. table.configNameRow = tag_name_row(output, table.configTag, tables::kPlacedConfigClass);
  636. }
  637. for (catalog::TriggerVolumeInstance& instance : output.triggerVolumeInstances) {
  638. if (cancelled(cancel)) {
  639. return false;
  640. }
  641. instance.classDefinitionNameRow = tag_name_row(
  642. output, instance.classDefinitionTag, tables::kPlacedClassDefinitionClass);
  643. instance.shapeResourceNameRow = tag_name_row(output, instance.shapeResourceTag, 0);
  644. }
  645. return true;
  646. } catch (...) {
  647. return false;
  648. }
  649. }
  650. } // namespace sunrise::client::content::activity::scriptables::internal