activity_sdk_external_placements.h 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #pragma once
  2. #include <array>
  3. #include <cstdint>
  4. #include <span>
  5. #include <unordered_map>
  6. #include <vector>
  7. #include "../../../state/build_data/scriptables/definition.h"
  8. namespace sunrise::client::content::activity::sdk_generation::external_placements {
  9. namespace catalog = state::build_data::scriptables;
  10. /**
  11. * A placement a scenario loads that the activity object's own lists do not carry.
  12. * The map package holds most of them, and a type-4 descriptor's embedded array holds the rest.
  13. */
  14. struct Row final {
  15. std::uint64_t placedEntryIdentity{};
  16. /** Zero when the row came from a descriptor-embedded array, which names no object list. */
  17. std::uint32_t objectListTag{};
  18. std::uint32_t placementOrdinal{};
  19. std::uint32_t classListTag{};
  20. std::uint32_t nameHash{};
  21. std::array<std::uint32_t, 3> positionBits{};
  22. std::array<std::uint32_t, 4> quaternionBits{};
  23. std::uint32_t uniformScaleBits{};
  24. };
  25. /** One scenario's reference to a deduplicated row. */
  26. struct ScenarioRow final {
  27. std::uint32_t scenarioTag{};
  28. std::uint32_t rowIndex{};
  29. };
  30. /** Identity and transform decide the row, so one list and its mirror copy share it. */
  31. struct RowKey final {
  32. std::uint64_t placedEntryIdentity{};
  33. std::array<std::uint32_t, 3> positionBits{};
  34. std::array<std::uint32_t, 4> quaternionBits{};
  35. std::uint32_t uniformScaleBits{};
  36. [[nodiscard]] bool operator==(const RowKey&) const noexcept = default;
  37. };
  38. struct RowKeyHash final {
  39. [[nodiscard]] std::size_t operator()(const RowKey& value) const noexcept;
  40. };
  41. /**
  42. * Deduplicated rows plus the scenarios that carry each one.
  43. * One destination's rows repeat across all its scenarios, so the rows are stored once and the
  44. * scenario dimension costs one pair per carrying scenario.
  45. */
  46. struct Index final {
  47. std::vector<Row> rows{};
  48. /** Sorted by scenario tag once `finalize` has run. */
  49. std::vector<ScenarioRow> scenarioRows{};
  50. /** Pass-local row lookup, released by `finalize`. */
  51. std::unordered_map<RowKey, std::uint32_t, RowKeyHash> lookup{};
  52. /** False when a harvest was dropped, so no consumer may treat this as closed. */
  53. bool complete{true};
  54. };
  55. /** Harvests one scenario's container and descriptor-embedded placements into the index. */
  56. [[nodiscard]] bool
  57. append(std::uint32_t scenarioTag, const catalog::Snapshot& snapshot, Index& output) noexcept;
  58. /** Sorts the scenario references, drops repeats, and releases the pass-local lookup. */
  59. void finalize(Index& output) noexcept;
  60. /** The sorted references one scenario tag owns. */
  61. [[nodiscard]] std::span<const ScenarioRow> scenario_rows(const Index& index,
  62. std::uint32_t scenarioTag) noexcept;
  63. } // namespace sunrise::client::content::activity::sdk_generation::external_placements