mission_script_runtime.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #pragma once
  2. #include <array>
  3. #include <cstddef>
  4. #include <cstdint>
  5. #include <span>
  6. #include <string_view>
  7. #include "../../../state/activity/definition.h"
  8. namespace sunrise::server::activity::mission {
  9. /** One bounded, value-owned diagnostic row for an attached mission program. */
  10. struct InstanceDiagnostics final {
  11. state::activity::SessionBinding binding{};
  12. std::array<char, 64> activityId{};
  13. std::array<char, 24> programStatus{};
  14. std::array<char, 32> deliveryStage{};
  15. std::array<char, 16> lastVmStage{};
  16. std::array<char, 32> lastVmStatus{};
  17. std::array<char, 256> lastVmError{};
  18. std::uint64_t eventsSeen{};
  19. std::uint64_t eventsCommitted{};
  20. std::uint64_t lastMissionSequence{};
  21. std::uint64_t vmStateRevision{};
  22. std::uint64_t missionStateRevision{};
  23. std::uint64_t activityStateRevision{};
  24. std::uint64_t vmCallbacks{};
  25. std::uint64_t vmCommittedCallbacks{};
  26. std::uint64_t vmRefusedCallbacks{};
  27. std::uint64_t intentsTransportStaged{};
  28. std::uint64_t expectedScriptableRevision{};
  29. std::uint32_t activityRow{};
  30. std::uint32_t phase{};
  31. std::uint32_t intentAttempts{};
  32. std::uint32_t startAttempts{};
  33. std::size_t pendingIntents{};
  34. std::size_t pendingEvents{};
  35. bool missionStateBound{};
  36. bool missionStarted{};
  37. bool vmActive{};
  38. bool vmFaulted{};
  39. };
  40. /** One bounded, value-owned result from attaching Mission Lua to an exact Host generation. */
  41. struct AttachDiagnostics final {
  42. state::activity::SessionBinding binding{};
  43. /** Stable attach-result class, such as `ready`, `no_activity_link`, or `sdk_status`. */
  44. std::array<char, 32> result{};
  45. /** Exact refusal detail; SDK failures carry their stable SDK status name here. */
  46. std::array<char, 32> detail{};
  47. /** One-based SDK activity row when resolution reached an exact activity. */
  48. std::uint32_t activityRow{};
  49. bool hasActivityRow{};
  50. };
  51. /** One fixed-capacity copy of all attached mission-program diagnostics. */
  52. struct DiagnosticsSnapshot final {
  53. std::array<InstanceDiagnostics, state::activity::kSessionCapacity> instances{};
  54. /** One row per Host generation plus one possible runtime-capacity refusal. */
  55. std::array<AttachDiagnostics, state::activity::kSessionCapacity + 1> attaches{};
  56. std::size_t instanceCount{};
  57. std::size_t attachCount{};
  58. bool enabled{};
  59. bool pathReady{};
  60. };
  61. /** Generation-pinned actor command accepted by a gameplay policy provider. */
  62. struct ActorCommandPolicyRequest final {
  63. state::activity::SessionBinding binding{};
  64. std::array<std::byte, 32> sdkBuildSha256{};
  65. std::uint32_t squadRow{};
  66. std::uint32_t commandRow{};
  67. std::uint32_t commandSelector{};
  68. std::int32_t value{};
  69. };
  70. enum class ActorCommandPolicyStatus : std::uint8_t {
  71. queued,
  72. unavailable,
  73. refused,
  74. };
  75. using ActorCommandPolicy = ActorCommandPolicyStatus (*)(
  76. const void* context, const ActorCommandPolicyRequest& request) noexcept;
  77. /** Installs the gameplay-owned policy callback before mission service starts. */
  78. void install_actor_command_policy(const void* context, ActorCommandPolicy policy) noexcept;
  79. /** Publishes accepted gameplay damage only to the mission's matching source generation. */
  80. void report_squad_provoked(const state::activity::SessionBinding& binding,
  81. std::uint64_t sourceGeneration,
  82. std::uint32_t registryKey,
  83. std::uint16_t slotIndex) noexcept;
  84. /**
  85. * Publishes an authored actor's replicated damage levels as a damageState event when they change.
  86. * Levels are ten-bit fractions of full (1023).
  87. */
  88. void report_squad_damage(const state::activity::SessionBinding& binding,
  89. std::uint64_t sourceGeneration,
  90. std::uint32_t registryKey,
  91. std::uint8_t slotType,
  92. std::uint16_t slotIndex,
  93. std::uint16_t health,
  94. std::uint16_t shield) noexcept;
  95. /** Starts the server mission-script manager when its setting is enabled. */
  96. void initialize() noexcept;
  97. /** Writes the authored controller path, `<name>/<name>.lua`, for one 1-based SDK activity row. */
  98. [[nodiscard]] bool controller_file_name(std::uint32_t oneBasedActivityRow,
  99. std::span<char> output) noexcept;
  100. /** Runs one bounded event/reducer/output slice after Activity Host ingress. */
  101. void service(std::uint64_t now) noexcept;
  102. /** Copies mission-program state without invoking Lua or changing delivery state. */
  103. void snapshot(DiagnosticsSnapshot& output) noexcept;
  104. /** How one reload request ended. */
  105. enum class ReloadStatus : std::uint8_t {
  106. pending,
  107. ok,
  108. /** Mission scripting is off or its paths did not resolve. */
  109. disabled,
  110. /** A new controller does not compile; every old program keeps running. */
  111. compileError,
  112. /** Preparation or publication was refused; old programs remain in place. */
  113. failed,
  114. /** A newer request took the mailbox before this one was answered. */
  115. replaced,
  116. /** The requester left before publication started. */
  117. cancelled,
  118. };
  119. /** The answer to one reload request. */
  120. struct ReloadResult final {
  121. ReloadStatus status{ReloadStatus::pending};
  122. /** Programs that reopened and are running again. */
  123. std::uint32_t reopened{};
  124. std::array<char, 192> message{};
  125. };
  126. /** Checks requester lifetime before commit; it must not call any reload API. */
  127. using ReloadRequester = bool (*)(std::uint64_t ticket) noexcept;
  128. /**
  129. * Prepares replacements from disk and adopts them together at their next safe point.
  130. * Safe means no delivery, intent, input, timer or script event is in flight.
  131. * @param modId Reopens this mod's controllers and library users, including its dependents.
  132. * Empty means every program.
  133. * @return The ticket `reload_result` answers; a newer request replaces an unanswered one.
  134. */
  135. [[nodiscard]] std::uint64_t request_reload(std::string_view modId,
  136. ReloadRequester requester = nullptr) noexcept;
  137. /** Cancels only this pending ticket; a committed or newer request is untouched. */
  138. [[nodiscard]] bool cancel_reload(std::uint64_t ticket) noexcept;
  139. /** @return The answer for one ticket; `pending` until the server thread has answered it. */
  140. [[nodiscard]] ReloadResult reload_result(std::uint64_t ticket) noexcept;
  141. /** Closes every per-activity Lua state and clears its event cursor. */
  142. void shutdown() noexcept;
  143. } // namespace sunrise::server::activity::mission