activity_sdk_pack_composer_rows.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. #include <cstddef>
  2. #include <cstdint>
  3. #include <limits>
  4. #include <span>
  5. #include <string_view>
  6. #include "activity_sdk_activity_inventory.h"
  7. #include "activity_sdk_actor_rsat_inventory.h"
  8. #include "activity_sdk_authored_scene_inventory.h"
  9. #include "activity_sdk_behavior_inventory.h"
  10. #include "activity_sdk_pack_composer_internal.h"
  11. #include "activity_sdk_policy_inventory.h"
  12. #include "activity_sdk_squad_inventory.h"
  13. #include "activity_sdk_topology_enrichment.h"
  14. #include "activity_sdk_topology_inventory.h"
  15. namespace sunrise::client::content::activity::sdk_generation::pack_composer {
  16. namespace {
  17. /** State rows use bit zero for enabled and bit one for extraction-complete. */
  18. constexpr std::uint32_t kStateEnabled = 0x1U;
  19. constexpr std::uint32_t kStateExtractionComplete = 0x2U;
  20. static_assert((kStateEnabled | kStateExtractionComplete) == format::kStateFlagMask);
  21. template <typename Text>
  22. [[nodiscard]] bool text_view(const Text& input, std::string_view& output) noexcept {
  23. output = {};
  24. if (input.length >= input.value.size() || input.value[input.length] != '\0') {
  25. return false;
  26. }
  27. output = {input.value.data(), input.length};
  28. return true;
  29. }
  30. [[nodiscard]] bool policy_text_view(const policy_inventory::Snapshot& source,
  31. policy_inventory::Text input,
  32. std::string_view& output) noexcept {
  33. output = {};
  34. if (input.stringIndex >= source.strings.size()) {
  35. return false;
  36. }
  37. output = source.strings[input.stringIndex];
  38. return true;
  39. }
  40. template <typename Text>
  41. [[nodiscard]] bool link_text(const detail::StringResolver& strings,
  42. const Text& input,
  43. format::StringRef& output) noexcept {
  44. std::string_view value{};
  45. return text_view(input, value) && strings.resolve(value, output);
  46. }
  47. [[nodiscard]] bool link_string(const detail::StringResolver& strings,
  48. std::string_view input,
  49. format::StringRef& output) noexcept {
  50. return strings.resolve(input, output);
  51. }
  52. [[nodiscard]] bool link_policy_text(const detail::StringResolver& strings,
  53. const policy_inventory::Snapshot& source,
  54. policy_inventory::Text input,
  55. format::StringRef& output) noexcept {
  56. std::string_view value{};
  57. return policy_text_view(source, input, value) && strings.resolve(value, output);
  58. }
  59. /** Appends one canonical tag set and returns its exact range in the shared tag section. */
  60. [[nodiscard]] bool append_binding_tags(std::span<const std::uint32_t> source,
  61. std::vector<format::ActivityBindingTag>& rows,
  62. format::Range& output) {
  63. if (rows.size() >= format::kAbsentIndex || source.size() > format::kAbsentIndex - rows.size()) {
  64. return false;
  65. }
  66. output = {static_cast<std::uint32_t>(rows.size()), static_cast<std::uint32_t>(source.size())};
  67. for (const std::uint32_t tag : source) {
  68. rows.push_back({tag});
  69. }
  70. return true;
  71. }
  72. /** Appends exact package locators and returns their activity-owned range. */
  73. [[nodiscard]] bool
  74. append_binding_locators(std::span<const activity_inventory::PackageLocator> source,
  75. std::vector<format::ActivityBindingLocator>& rows,
  76. format::Range& output) {
  77. if (rows.size() >= format::kAbsentIndex || source.size() > format::kAbsentIndex - rows.size()) {
  78. return false;
  79. }
  80. output = {static_cast<std::uint32_t>(rows.size()), static_cast<std::uint32_t>(source.size())};
  81. for (const activity_inventory::PackageLocator& locator : source) {
  82. rows.push_back({locator.tag, 0, locator.offset});
  83. }
  84. return true;
  85. }
  86. /**
  87. * Translates activity topology and its direct child sections.
  88. * @param inputs Accepted native inventories.
  89. * @param ranges Final parent-to-child ranges.
  90. * @param linker Resolver for the frozen string table.
  91. * @param output Composer-owned final rows.
  92. * @return True when every source row and string reference is valid.
  93. */
  94. [[nodiscard]] bool translate_topology(const Inputs& inputs,
  95. const detail::PreparedRanges& ranges,
  96. const detail::StringResolver& linker,
  97. Storage& output) {
  98. const topology_inventory::Snapshot& topology = *inputs.topology;
  99. const topology_enrichment::Snapshot& enrichment = *inputs.topologyEnrichment;
  100. const policy_inventory::Snapshot& policy = *inputs.policy;
  101. const activity_inventory::Snapshot& activityInventory = *inputs.activityInventory;
  102. output.activities.resize(topology.activities.size());
  103. for (std::size_t index = 0; index < topology.activities.size(); ++index) {
  104. const topology_inventory::Activity& source = topology.activities[index];
  105. const activity_inventory::ActivityVariant& binding = activityInventory.activities[index];
  106. format::Activity& target = output.activities[index];
  107. target.activityIndex = source.activityIndex;
  108. target.definitionHash = source.definitionHash;
  109. target.scenarioIndex = source.scenarioIndex;
  110. target.flags = source.exactFlags;
  111. target.aliases = policy.activityAliases[index];
  112. target.capabilities = ranges.activityCapabilities[index];
  113. target.selectedActivityRootTag =
  114. binding.activityRootTag == 0 ? format::kAbsentIndex : binding.activityRootTag;
  115. target.selectedScenarioTag =
  116. binding.scenarioTag == 0 ? format::kAbsentIndex : binding.scenarioTag;
  117. target.matchmakingConfigTag = binding.bindingEvidence.matchmakingConfigTag;
  118. target.joinStatus = static_cast<std::uint32_t>(binding.joinStatus);
  119. target.bindingDisposition = static_cast<std::uint32_t>(binding.bindingDisposition);
  120. target.bindingReason = static_cast<std::uint32_t>(binding.bindingReason);
  121. target.bindingEvidenceBasis = static_cast<std::uint32_t>(binding.bindingEvidenceBasis);
  122. target.runnableStatus = static_cast<std::uint32_t>(binding.runnableStatus);
  123. target.bindingFlags =
  124. (binding.fullSdkAcceptable ? format::kActivityBindingFullSdkAcceptable : 0U)
  125. | (binding.bindingEvidence.hasInternalName ? format::kActivityBindingHasInternalName
  126. : 0U)
  127. | (binding.bindingEvidence.hasMatchmakingConfig
  128. ? format::kActivityBindingHasMatchmakingConfig
  129. : 0U);
  130. if (!link_text(linker, source.id, target.id)
  131. || !link_text(linker, source.internalName, target.internalName)
  132. || !link_text(linker, source.displayName, target.displayName)
  133. || !append_binding_tags(binding.bindingEvidence.activityRootCandidateTags,
  134. output.activityBindingTags,
  135. target.activityRootCandidateTags)
  136. || !append_binding_tags(binding.bindingEvidence.scenarioNameCandidateTags,
  137. output.activityBindingTags,
  138. target.scenarioNameCandidateTags)
  139. || !append_binding_tags(binding.bindingEvidence.evidenceRootTags,
  140. output.activityBindingTags,
  141. target.evidenceRootTags)
  142. || !append_binding_locators(binding.bindingEvidence.locators,
  143. output.activityBindingLocators,
  144. target.bindingLocators)) {
  145. return false;
  146. }
  147. }
  148. output.scenarios.resize(topology.scenarios.size());
  149. for (std::size_t index = 0; index < topology.scenarios.size(); ++index) {
  150. const topology_inventory::Scenario& source = topology.scenarios[index];
  151. format::Scenario& target = output.scenarios[index];
  152. target.tag = source.tag;
  153. target.bubbles = ranges.scenarioBubbles[index];
  154. target.states = ranges.scenarioStates[index];
  155. target.occurrences = ranges.scenarioOccurrences[index];
  156. if (!link_text(linker, source.id, target.id)
  157. || !link_text(linker, source.name, target.name)) {
  158. return false;
  159. }
  160. }
  161. output.bubbles.resize(topology.bubbles.size());
  162. for (std::size_t index = 0; index < topology.bubbles.size(); ++index) {
  163. const topology_inventory::Bubble& source = topology.bubbles[index];
  164. format::Bubble& target = output.bubbles[index];
  165. target.scenarioIndex = source.scenarioIndex;
  166. target.bubbleOrdinal = source.bubbleOrdinal;
  167. target.nameHash = source.nameHash;
  168. target.states = ranges.bubbleStates[index];
  169. if (!link_text(linker, source.id, target.id)
  170. || !link_text(linker, enrichment.bubbleNames[index], target.name)) {
  171. return false;
  172. }
  173. }
  174. output.states.resize(topology.states.size());
  175. for (std::size_t index = 0; index < topology.states.size(); ++index) {
  176. const topology_inventory::State& source = topology.states[index];
  177. format::State& target = output.states[index];
  178. target.scenarioIndex = source.scenarioIndex;
  179. target.bubbleIndex = source.bubbleIndex;
  180. target.stateOrdinal = source.stateOrdinal;
  181. target.entryIndex = source.entryIndex;
  182. target.sliceSetIndex = source.sliceSetIndex;
  183. target.mapBubbleIndex = source.mapBubbleIndex;
  184. target.stateHash = source.stateHash;
  185. target.publicValue = source.rawU32At12;
  186. target.flags = kStateExtractionComplete | (source.enabled ? kStateEnabled : 0U);
  187. target.registryTag = source.registryTag;
  188. if (!link_text(linker, source.id, target.id)
  189. || !link_text(linker, source.entryId, target.entryId)
  190. || !link_text(linker, source.registryId, target.registryId)) {
  191. return false;
  192. }
  193. }
  194. output.objects.resize(topology.objects.size());
  195. for (std::size_t index = 0; index < topology.objects.size(); ++index) {
  196. const topology_inventory::Object& source = topology.objects[index];
  197. format::Object& target = output.objects[index];
  198. target.objectTag = source.objectTag;
  199. target.objectKey = source.objectKey;
  200. target.slots = ranges.objectSlots[index];
  201. target.configCount = source.configCount;
  202. target.descriptorCount = source.descriptorCount;
  203. target.placedSubblockCount = source.placedSubblockCount;
  204. target.placedLeafCount = source.placedLeafCount;
  205. target.placedHopCount = source.placedHopCount;
  206. target.bareTargetCount = source.bareTargetCount;
  207. target.replicatedPlacementCount = source.replicatedPlacementCount;
  208. if (!link_text(linker, source.id, target.id)) {
  209. return false;
  210. }
  211. }
  212. output.occurrences.resize(topology.occurrences.size());
  213. for (std::size_t index = 0; index < topology.occurrences.size(); ++index) {
  214. const topology_inventory::Occurrence& source = topology.occurrences[index];
  215. format::Occurrence& target = output.occurrences[index];
  216. target.scenarioIndex = source.scenarioIndex;
  217. target.bubbleIndex = source.bubbleIndex;
  218. target.stateIndex = source.stateIndex;
  219. target.objectIndex = source.objectIndex;
  220. target.registryField = source.registryField;
  221. target.objectOrdinal = source.objectOrdinal;
  222. if (!link_text(linker, source.id, target.id)
  223. || !link_text(linker, source.contextRegistryKey, target.contextRegistryKey)
  224. || !link_text(linker, source.registryId, target.registryId)
  225. || !link_text(linker, source.entryId, target.entryId)) {
  226. return false;
  227. }
  228. }
  229. output.slots.resize(topology.slots.size());
  230. for (std::size_t index = 0; index < topology.slots.size(); ++index) {
  231. const topology_inventory::Slot& source = topology.slots[index];
  232. const topology_enrichment::Slot& linked = enrichment.slots[index];
  233. format::Slot& target = output.slots[index];
  234. target.objectIndex = source.objectIndex;
  235. target.slotIndex = source.slotIndex;
  236. target.slotType = source.slotType;
  237. target.componentClass = linked.componentClass;
  238. target.senseSchema = linked.senseSchema;
  239. target.authSchema = linked.authSchema;
  240. target.flags = linked.flags;
  241. target.reserved = linked.dialogueCueCount;
  242. target.aliases = policy.slotAliases[index];
  243. target.capabilities = ranges.slotCapabilities[index];
  244. if (!link_text(linker, source.id, target.id) || !link_text(linker, linked.name, target.name)
  245. || !link_text(linker, linked.senseSchemaId, target.senseSchemaId)
  246. || !link_text(linker, linked.authSchemaId, target.authSchemaId)) {
  247. return false;
  248. }
  249. }
  250. return true;
  251. }
  252. /** Copies policy rows after resolving every handle in the policy-owned pool. */
  253. [[nodiscard]] bool translate_policy(const policy_inventory::Snapshot& source,
  254. const detail::StringResolver& linker,
  255. Storage& output) {
  256. output.texts.resize(source.texts.size());
  257. for (std::size_t index = 0; index < source.texts.size(); ++index) {
  258. const policy_inventory::TextRow& input = source.texts[index];
  259. format::Text& target = output.texts[index];
  260. target.kind = input.kind;
  261. target.reserved = input.reserved;
  262. if (!link_policy_text(linker, source, input.value, target.value)) {
  263. return false;
  264. }
  265. }
  266. output.capabilities.resize(source.capabilities.size());
  267. for (std::size_t index = 0; index < source.capabilities.size(); ++index) {
  268. const policy_inventory::Capability& input = source.capabilities[index];
  269. format::Capability& target = output.capabilities[index];
  270. target.subjectKind = input.subjectKind;
  271. target.subjectIndex = input.subjectIndex;
  272. target.exposureFlags = input.exposureFlags;
  273. target.candidateExposureFlags = input.candidateExposureFlags;
  274. target.gates = input.gates;
  275. target.refusals = input.refusals;
  276. if (!link_policy_text(linker, source, input.id, target.id)
  277. || !link_policy_text(linker, source, input.operation, target.operation)
  278. || !link_policy_text(linker, source, input.valueSchemaId, target.valueSchemaId)) {
  279. return false;
  280. }
  281. }
  282. output.gates.resize(source.gates.size());
  283. for (std::size_t index = 0; index < source.gates.size(); ++index) {
  284. const policy_inventory::Gate& input = source.gates[index];
  285. format::Gate& target = output.gates[index];
  286. if (!link_policy_text(linker, source, input.gate, target.gate)
  287. || !link_policy_text(linker, source, input.status, target.status)
  288. || !link_policy_text(linker, source, input.reasonCode, target.reasonCode)
  289. || !link_policy_text(linker, source, input.required, target.required)
  290. || !link_policy_text(linker, source, input.observed, target.observed)
  291. || !link_policy_text(linker, source, input.wouldConfirm, target.wouldConfirm)) {
  292. return false;
  293. }
  294. }
  295. output.refusals.resize(source.refusals.size());
  296. for (std::size_t index = 0; index < source.refusals.size(); ++index) {
  297. const policy_inventory::Refusal& input = source.refusals[index];
  298. format::Refusal& target = output.refusals[index];
  299. target.reasonCodes = input.reasonCodes;
  300. target.capabilityIndex = input.capabilityIndex;
  301. target.reserved = input.reserved;
  302. if (!link_policy_text(linker, source, input.id, target.id)
  303. || !link_policy_text(linker, source, input.exposure, target.exposure)
  304. || !link_policy_text(linker, source, input.status, target.status)) {
  305. return false;
  306. }
  307. }
  308. return true;
  309. }
  310. /** Copies actor, RSAT, squad, and panel placement sections. */
  311. [[nodiscard]] bool
  312. translate_native_rows(const Inputs& inputs, const detail::StringResolver& linker, Storage& output) {
  313. const actor_rsat_inventory::Snapshot& actorRsat = *inputs.actorRsat;
  314. const squad_inventory::Snapshot& squads = *inputs.squads;
  315. const authored_scene_inventory::Snapshot& authoredScenes = *inputs.authoredScenes;
  316. const behavior_inventory::Snapshot& behaviors = *inputs.behaviors;
  317. output.actorClasses.resize(actorRsat.actorClasses.size());
  318. for (std::size_t index = 0; index < actorRsat.actorClasses.size(); ++index) {
  319. const actor_rsat_inventory::ActorClass& input = actorRsat.actorClasses[index];
  320. format::ActorClass& target = output.actorClasses[index];
  321. target.definitionTag = input.definitionTag;
  322. target.nameHash = input.nameHash;
  323. target.rsatTag = input.rsatTag;
  324. target.rsatReverseDefinitionTag = input.rsatReverseDefinitionTag;
  325. target.objectType = input.objectType;
  326. target.descriptorArrayOffset = input.descriptorArrayOffset;
  327. target.descriptorArrayRelative = input.descriptorArrayRelative;
  328. target.descriptorArrayHeaderOffset = input.descriptorArrayHeaderOffset;
  329. target.descriptorArrayDataOffset = input.descriptorArrayDataOffset;
  330. target.descriptorElementClass = input.descriptorElementClass;
  331. target.descriptors = input.descriptors;
  332. target.dynamicPresenceTailCount = input.dynamicPresenceTailCount;
  333. target.authoredSpawnProfile = input.authoredSpawnProfile;
  334. if (!link_text(linker, input.id, target.id)) {
  335. return false;
  336. }
  337. }
  338. output.actorMessageSchemas.resize(actorRsat.messageSchemas.size());
  339. for (std::size_t index = 0; index < actorRsat.messageSchemas.size(); ++index) {
  340. const actor_rsat_inventory::ActorMessageSchema& input = actorRsat.messageSchemas[index];
  341. format::ActorMessageSchema& target = output.actorMessageSchemas[index];
  342. target.definitionHandle = input.definitionHandle;
  343. target.durableKey = input.durableKey;
  344. target.ownerClass = input.ownerClass;
  345. target.handlerSlot = input.handlerSlot;
  346. target.bodyType = input.bodyType;
  347. target.provenance = input.provenance;
  348. target.commands = input.commands;
  349. target.flags = input.flags;
  350. if (!link_text(linker, input.name, target.name)) {
  351. return false;
  352. }
  353. }
  354. output.actorCommandDefinitions.resize(actorRsat.commandDefinitions.size());
  355. for (std::size_t index = 0; index < actorRsat.commandDefinitions.size(); ++index) {
  356. const actor_rsat_inventory::ActorCommandDefinition& input =
  357. actorRsat.commandDefinitions[index];
  358. format::ActorCommandDefinition& target = output.actorCommandDefinitions[index];
  359. target.selector = input.selector;
  360. target.payloadHandle = input.payloadHandle;
  361. target.effect = input.effect;
  362. target.provenance = input.provenance;
  363. target.factionNone = input.factionNone;
  364. target.factionRemoved = input.factionRemoved;
  365. target.factionHostileToAll = input.factionHostileToAll;
  366. target.flags = input.flags;
  367. if (!link_text(linker, input.name, target.name)
  368. || !link_text(linker, input.factionNoneName, target.factionNoneName)
  369. || !link_text(linker, input.factionRemovedName, target.factionRemovedName)
  370. || !link_text(linker, input.factionHostileToAllName, target.factionHostileToAllName)) {
  371. return false;
  372. }
  373. }
  374. output.actorBehaviorProfiles.resize(actorRsat.behaviorProfiles.size());
  375. for (std::size_t index = 0; index < actorRsat.behaviorProfiles.size(); ++index) {
  376. const actor_rsat_inventory::ActorBehaviorProfile& input = actorRsat.behaviorProfiles[index];
  377. format::ActorBehaviorProfile& target = output.actorBehaviorProfiles[index];
  378. target.actorClassIndex = input.actorClassIndex;
  379. target.behaviorConfigTag = input.behaviorConfigTag;
  380. target.behaviorConfigClass = input.behaviorConfigClass;
  381. target.behaviorConfigOffset = input.behaviorConfigOffset;
  382. target.defaultFaction = input.defaultFaction;
  383. target.behaviorProvenance = input.behaviorProvenance;
  384. target.factionProvenance = input.factionProvenance;
  385. target.flags = input.flags;
  386. }
  387. output.simulationEventDefinitions.resize(actorRsat.simulationEvents.size());
  388. for (std::size_t index = 0; index < actorRsat.simulationEvents.size(); ++index) {
  389. const actor_rsat_inventory::SimulationEventDefinition& input =
  390. actorRsat.simulationEvents[index];
  391. format::SimulationEventDefinition& target = output.simulationEventDefinitions[index];
  392. target.eventType = input.eventType;
  393. target.primarySchema = input.primarySchema;
  394. target.secondarySchema = input.secondarySchema;
  395. target.provenance = input.provenance;
  396. target.descriptorEvidenceAddress = input.descriptorEvidenceAddress;
  397. target.primaryEvidenceAddress = input.primaryEvidenceAddress;
  398. target.secondaryEvidenceAddress = input.secondaryEvidenceAddress;
  399. target.flags = input.flags;
  400. if (!link_text(linker, input.name, target.name)) {
  401. return false;
  402. }
  403. }
  404. output.runtimeSchemas = actorRsat.runtimeSchemas;
  405. output.runtimeFields = actorRsat.runtimeFields;
  406. output.runtimeTypeDefinitions.resize(actorRsat.runtimeTypes.size());
  407. for (std::size_t index = 0; index < actorRsat.runtimeTypes.size(); ++index) {
  408. const actor_rsat_inventory::RuntimeTypeDefinition& input = actorRsat.runtimeTypes[index];
  409. format::RuntimeTypeDefinition& target = output.runtimeTypeDefinitions[index];
  410. target.codecFamilies = input.codecFamilies;
  411. target.typeCode = input.typeCode;
  412. target.decodedSize = input.decodedSize;
  413. target.fixedBits = input.fixedBits;
  414. target.minimumBits = input.minimumBits;
  415. target.maximumBits = input.maximumBits;
  416. target.writerEvidenceAddress = input.writerEvidenceAddress;
  417. target.readerEvidenceAddress = input.readerEvidenceAddress;
  418. target.flags = input.flags;
  419. if (!link_text(linker, input.name, target.name)) {
  420. return false;
  421. }
  422. }
  423. output.sobjectRsats = actorRsat.sobjectRsats;
  424. output.sobjectRsatDescriptors = actorRsat.sobjectRsatDescriptors;
  425. output.sobjectRsatFieldBindings = actorRsat.sobjectRsatFieldBindings;
  426. output.actorStateNames = actorRsat.actorStateNames;
  427. output.actorSequenceTables = actorRsat.sequenceTables;
  428. output.actorSequenceBindings = actorRsat.sequenceBindings;
  429. output.actorAbilities = actorRsat.actorAbilities;
  430. output.actorAbilityTargets = actorRsat.actorAbilityTargets;
  431. output.actorSequenceEntries.reserve(actorRsat.sequenceEntries.size());
  432. for (const auto& input : actorRsat.sequenceEntries) {
  433. auto row = input.row;
  434. if (!link_string(linker, input.id, row.id) || !link_string(linker, input.name, row.name)
  435. || !link_string(linker, input.symbol, row.symbol)
  436. || !link_string(linker, input.sourcePath, row.sourcePath)) {
  437. return false;
  438. }
  439. output.actorSequenceEntries.push_back(row);
  440. }
  441. output.entityTypeDefinitions.resize(actorRsat.entityTypes.size());
  442. for (std::size_t index = 0; index < actorRsat.entityTypes.size(); ++index) {
  443. const actor_rsat_inventory::EntityTypeDefinition& input = actorRsat.entityTypes[index];
  444. format::EntityTypeDefinition& target = output.entityTypeDefinitions[index];
  445. target.entityType = input.entityType;
  446. target.baselineSchema = input.baselineSchema;
  447. target.updateSchema = input.updateSchema;
  448. target.provenance = input.provenance;
  449. target.vtableEvidenceAddress = input.vtableEvidenceAddress;
  450. target.baselineEvidenceAddress = input.baselineEvidenceAddress;
  451. target.updateEvidenceAddress = input.updateEvidenceAddress;
  452. target.flags = input.flags;
  453. if (!link_text(linker, input.name, target.name)) {
  454. return false;
  455. }
  456. }
  457. output.rsatDescriptors.resize(actorRsat.descriptors.size());
  458. for (std::size_t index = 0; index < actorRsat.descriptors.size(); ++index) {
  459. const actor_rsat_inventory::RsatDescriptor& input = actorRsat.descriptors[index];
  460. format::RsatDescriptor& target = output.rsatDescriptors[index];
  461. target.actorClassIndex = input.actorClassIndex;
  462. target.rsatTag = input.rsatTag;
  463. target.descriptorOrdinal = input.descriptorOrdinal;
  464. target.descriptorOffset = input.descriptorOffset;
  465. target.descriptorElementClass = input.descriptorElementClass;
  466. target.componentTag = input.componentTag;
  467. target.schemaIndex = input.schemaIndex;
  468. target.schemaTag = input.schemaTag;
  469. target.schemaFieldCount = input.schemaFieldCount;
  470. target.schemaFirstFieldRuntimeGate = input.schemaFirstFieldRuntimeGate;
  471. target.schemaFirstFieldRawU32At10 = input.schemaFirstFieldRawU32At10;
  472. target.flags = input.flags;
  473. target.dynamicPresenceTailOrdinal = input.dynamicPresenceTailOrdinal;
  474. target.rawRow = input.rawRow;
  475. if (!link_text(linker, input.id, target.id)) {
  476. return false;
  477. }
  478. }
  479. output.rsatSchemas.resize(actorRsat.schemas.size());
  480. for (std::size_t index = 0; index < actorRsat.schemas.size(); ++index) {
  481. const actor_rsat_inventory::RsatSchema& input = actorRsat.schemas[index];
  482. format::RsatSchema& target = output.rsatSchemas[index];
  483. target.schemaTag = input.schemaTag;
  484. target.schemaClass = input.schemaClass;
  485. target.fieldCount = input.fieldCount;
  486. target.fieldArrayOffset = input.fieldArrayOffset;
  487. target.fieldArrayRelative = input.fieldArrayRelative;
  488. target.fieldArrayHeaderOffset = input.fieldArrayHeaderOffset;
  489. target.fieldArrayDataOffset = input.fieldArrayDataOffset;
  490. target.fieldElementClass = input.fieldElementClass;
  491. target.firstFieldRuntimeGate = input.firstFieldRuntimeGate;
  492. target.firstFieldRawU32At10 = input.firstFieldRawU32At10;
  493. target.flags = input.flags;
  494. target.fields = input.fields;
  495. if (!link_text(linker, input.id, target.id)) {
  496. return false;
  497. }
  498. }
  499. output.rsatFields.resize(actorRsat.fields.size());
  500. for (std::size_t index = 0; index < actorRsat.fields.size(); ++index) {
  501. output.rsatFields[index].rawRow = actorRsat.fields[index].rawRow;
  502. }
  503. output.squads.resize(squads.squads.size());
  504. for (std::size_t index = 0; index < squads.squads.size(); ++index) {
  505. const squad_inventory::Squad& input = squads.squads[index];
  506. format::Squad& target = output.squads[index];
  507. target.scenarioIndex = input.scenarioIndex;
  508. target.objectIndex = input.objectIndex;
  509. target.slotIndex = input.slotIndex;
  510. target.spawnerConfigTag = input.spawnerConfigTag;
  511. target.spawnRuleConfigTag = input.spawnRuleConfigTag;
  512. target.flags = input.flags;
  513. target.occurrenceIndex = input.occurrenceIndex;
  514. target.members = input.members;
  515. target.anchors = input.anchors;
  516. if (!link_string(linker, input.id, target.id)) {
  517. return false;
  518. }
  519. }
  520. output.squadMembers.resize(squads.members.size());
  521. for (std::size_t index = 0; index < squads.members.size(); ++index) {
  522. const squad_inventory::SquadMember& input = squads.members[index];
  523. format::SquadMember& target = output.squadMembers[index];
  524. target.squadIndex = input.squadIndex;
  525. target.memberOrdinal = input.memberOrdinal;
  526. target.memberKey = input.memberKey;
  527. target.actorClassIndex = input.actorClassIndex;
  528. target.flags = input.flags;
  529. target.candidateCounts = input.candidateCounts;
  530. target.defaultCount = input.defaultCount;
  531. target.authoredSpawnProfile = input.authoredSpawnProfile;
  532. if (!link_string(linker, input.id, target.id)) {
  533. return false;
  534. }
  535. }
  536. output.squadAnchors.resize(squads.anchors.size());
  537. for (std::size_t index = 0; index < squads.anchors.size(); ++index) {
  538. const squad_inventory::SquadAnchor& input = squads.anchors[index];
  539. format::SquadAnchor& target = output.squadAnchors[index];
  540. target.squadIndex = input.squadIndex;
  541. target.pointOrdinal = input.pointOrdinal;
  542. target.objectListTag = input.objectListTag;
  543. target.placementOrdinal = input.placementOrdinal;
  544. target.flags = input.flags;
  545. target.placedEntryIdentity = input.placedEntryIdentity;
  546. target.positionBits = input.positionBits;
  547. if (!link_string(linker, input.id, target.id)) {
  548. return false;
  549. }
  550. }
  551. output.authoredSceneResources.resize(authoredScenes.resources.size());
  552. for (std::size_t index = 0; index < authoredScenes.resources.size(); ++index) {
  553. const authored_scene_inventory::Resource& input = authoredScenes.resources[index];
  554. format::AuthoredSceneResource& target = output.authoredSceneResources[index];
  555. target.slotIndex = input.slotIndex;
  556. target.configTag = input.configTag;
  557. target.descriptorOffset = input.descriptorOffset;
  558. target.resourceFieldOffset = input.resourceFieldOffset;
  559. target.resourceTag = input.resourceTag;
  560. target.resourceClass = input.resourceClass;
  561. target.flags = input.flags;
  562. target.reserved = input.reserved;
  563. if (!link_text(linker, input.id, target.id)) {
  564. return false;
  565. }
  566. }
  567. output.authoredSceneEventKeys.resize(authoredScenes.eventKeys.size());
  568. for (std::size_t index = 0; index < authoredScenes.eventKeys.size(); ++index) {
  569. const authored_scene_inventory::EventKey& input = authoredScenes.eventKeys[index];
  570. format::AuthoredSceneEventKey& target = output.authoredSceneEventKeys[index];
  571. target.sceneSlotIndex = input.slotIndex;
  572. target.resourceTag = input.resourceTag;
  573. target.graphTag = input.graphTag;
  574. target.gateOffset = input.gateOffset;
  575. target.ordinal = input.ordinal;
  576. target.key = input.key;
  577. target.flags = input.flags;
  578. target.reserved = input.reserved;
  579. if (!link_text(linker, input.id, target.id)) {
  580. return false;
  581. }
  582. }
  583. output.authoredSceneSquadEdges.resize(authoredScenes.squadEdges.size());
  584. for (std::size_t index = 0; index < authoredScenes.squadEdges.size(); ++index) {
  585. const authored_scene_inventory::SquadEdge& input = authoredScenes.squadEdges[index];
  586. format::AuthoredSceneSquadEdge& target = output.authoredSceneSquadEdges[index];
  587. target.sceneSlotIndex = input.sceneSlotIndex;
  588. target.squadSlotIndex = input.squadSlotIndex;
  589. target.configTag = input.configTag;
  590. target.descriptorOffset = input.descriptorOffset;
  591. target.referenceFieldOffset = input.referenceFieldOffset;
  592. target.targetObjectKey = input.targetObjectKey;
  593. target.flags = input.flags;
  594. target.reserved = input.reserved;
  595. if (!link_text(linker, input.id, target.id)) {
  596. return false;
  597. }
  598. }
  599. output.taskTargets.resize(authoredScenes.taskTargets.size());
  600. for (std::size_t index = 0; index < authoredScenes.taskTargets.size(); ++index) {
  601. const authored_scene_inventory::TaskTarget& input = authoredScenes.taskTargets[index];
  602. format::TaskTarget& target = output.taskTargets[index];
  603. target.taskSlotIndex = input.taskSlotIndex;
  604. target.objectiveSlotIndex = input.objectiveSlotIndex;
  605. target.configTag = input.configTag;
  606. target.descriptorOffset = input.descriptorOffset;
  607. target.referenceFieldOffset = input.referenceFieldOffset;
  608. target.targetObjectKey = input.targetObjectKey;
  609. target.bitIndex = input.bitIndex;
  610. target.flags = input.flags;
  611. target.reserved = input.reserved;
  612. if (!link_text(linker, input.id, target.id)) {
  613. return false;
  614. }
  615. }
  616. output.combatObjectiveGroups = authoredScenes.combatObjectiveGroups;
  617. output.dialogueCues.resize(authoredScenes.dialogueCues.size());
  618. for (std::size_t index = 0; index < authoredScenes.dialogueCues.size(); ++index) {
  619. const authored_scene_inventory::DialogueCue& input = authoredScenes.dialogueCues[index];
  620. format::DialogueCue& target = output.dialogueCues[index];
  621. target.slotIndex = input.slotIndex;
  622. target.cueIndex = input.cueIndex;
  623. target.listTag = input.listTag;
  624. target.definitionHash = input.definitionHash;
  625. target.authoredWindowSeconds = input.authoredWindowSeconds;
  626. target.lineCount = input.lineCount;
  627. target.flags = input.flags;
  628. if (!link_text(linker, input.id, target.id)) {
  629. return false;
  630. }
  631. }
  632. output.dialogueCueTexts.resize(authoredScenes.dialogueCueTexts.size());
  633. for (std::size_t index = 0; index < authoredScenes.dialogueCueTexts.size(); ++index) {
  634. const authored_scene_inventory::DialogueCueText& input =
  635. authoredScenes.dialogueCueTexts[index];
  636. format::DialogueCueText& target = output.dialogueCueTexts[index];
  637. target.slotIndex = input.slotIndex;
  638. target.cueIndex = input.cueIndex;
  639. target.definitionHash = input.definitionHash;
  640. target.containerTag = input.containerTag;
  641. target.stringHash = input.stringHash;
  642. target.lineIndex = input.lineIndex;
  643. target.takeIndex = input.takeIndex;
  644. target.audioTag = input.audioTag;
  645. target.durationMs = input.durationMs;
  646. if (!link_text(linker, input.id, target.id)
  647. || !link_text(linker, input.text, target.text)) {
  648. return false;
  649. }
  650. }
  651. output.directiveElements.resize(authoredScenes.directiveElements.size());
  652. for (std::size_t index = 0; index < authoredScenes.directiveElements.size(); ++index) {
  653. const authored_scene_inventory::DirectiveElement& input =
  654. authoredScenes.directiveElements[index];
  655. format::DirectiveElement& target = output.directiveElements[index];
  656. target.slotIndex = input.slotIndex;
  657. target.nameHash = input.nameHash;
  658. target.elementIndex = input.elementIndex;
  659. target.elementCount = input.elementCount;
  660. target.titleContainerTag = input.titleContainerTag;
  661. target.titleStringHash = input.titleStringHash;
  662. target.descriptionContainerTag = input.descriptionContainerTag;
  663. target.descriptionStringHash = input.descriptionStringHash;
  664. target.progressContainerTag = input.progressContainerTag;
  665. target.progressStringHash = input.progressStringHash;
  666. target.flags = input.flags;
  667. if (!link_text(linker, input.id, target.id) || !link_text(linker, input.title, target.title)
  668. || !link_text(linker, input.description, target.description)
  669. || !link_text(linker, input.progress, target.progress)) {
  670. return false;
  671. }
  672. }
  673. output.behaviorPrograms.reserve(behaviors.programs.size());
  674. for (const behavior_inventory::Program& input : behaviors.programs) {
  675. output.behaviorPrograms.push_back({input.rootTag,
  676. {input.firstInput, input.inputCount},
  677. {input.firstWrite, input.writeCount},
  678. input.nodeCount,
  679. input.expressionCount});
  680. }
  681. output.behaviorInputs.reserve(behaviors.inputs.size());
  682. for (const behavior_inventory::Input& input : behaviors.inputs) {
  683. output.behaviorInputs.push_back({input.programRow,
  684. input.nodeOffset,
  685. input.expressionOffset,
  686. input.channelHash,
  687. input.inputOrMode,
  688. input.nativeOverride,
  689. input.activeField,
  690. input.selector,
  691. input.role,
  692. 0});
  693. }
  694. output.behaviorChannelWrites.reserve(behaviors.writes.size());
  695. for (const behavior_inventory::ChannelWrite& input : behaviors.writes) {
  696. output.behaviorChannelWrites.push_back(
  697. {input.programRow, input.nodeOffset, input.channelHash, 0});
  698. }
  699. output.behaviorOwners.reserve(behaviors.owners.size());
  700. for (const behavior_inventory::Owner& input : behaviors.owners) {
  701. output.behaviorOwners.push_back(
  702. {input.programRow,
  703. input.actorClassIndex,
  704. input.configTag,
  705. input.configFieldOffset,
  706. input.buildOrdinal,
  707. input.descriptorOrdinal,
  708. input.submitterSubtype,
  709. static_cast<format::BehaviorSubmissionKind>(input.submissionKind)});
  710. }
  711. for (std::size_t ownerIndex = 0; ownerIndex < output.behaviorOwners.size(); ++ownerIndex) {
  712. if (ownerIndex > (std::numeric_limits<std::uint32_t>::max)()) {
  713. return false;
  714. }
  715. const format::BehaviorOwner& owner = output.behaviorOwners[ownerIndex];
  716. for (std::size_t memberIndex = 0; memberIndex < output.squadMembers.size(); ++memberIndex) {
  717. if (memberIndex > (std::numeric_limits<std::uint32_t>::max)()) {
  718. return false;
  719. }
  720. const format::SquadMember& member = output.squadMembers[memberIndex];
  721. if (member.actorClassIndex != owner.actorClassIndex
  722. || member.squadIndex >= output.squads.size()) {
  723. continue;
  724. }
  725. const format::Squad& squad = output.squads[member.squadIndex];
  726. if (squad.occurrenceIndex >= output.occurrences.size()) {
  727. return false;
  728. }
  729. const format::Occurrence& occurrence = output.occurrences[squad.occurrenceIndex];
  730. output.behaviorActivityBindings.push_back({static_cast<std::uint32_t>(ownerIndex),
  731. member.squadIndex,
  732. static_cast<std::uint32_t>(memberIndex),
  733. occurrence.scenarioIndex,
  734. squad.occurrenceIndex,
  735. occurrence.stateIndex,
  736. occurrence.objectIndex,
  737. 0});
  738. }
  739. }
  740. return true;
  741. }
  742. } // namespace
  743. /** Translates topology, policy and native rows into pack storage. @return False on failure. */
  744. bool detail::translate_rows(const Inputs& inputs,
  745. const PreparedRanges& ranges,
  746. const StringResolver& strings,
  747. Storage& output) {
  748. if (!translate_topology(inputs, ranges, strings, output)) {
  749. return false;
  750. }
  751. if (!translate_policy(*inputs.policy, strings, output)) {
  752. return false;
  753. }
  754. if (!translate_native_rows(inputs, strings, output)) {
  755. return false;
  756. }
  757. return true;
  758. }
  759. } // namespace sunrise::client::content::activity::sdk_generation::pack_composer