orbit_rules.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. #pragma once
  2. #include <cstdint>
  3. namespace sunrise::client::hooks::ember_movies {
  4. enum class OrbitAction { none, select, cleanup, orbitSetup, canceled, timedOut };
  5. enum class OrbitStage { idle, completion, selection, leaving, finished };
  6. struct OrbitObservation {
  7. bool exactOwner{}, emberSelected{}, orbitSelected{}, complete{}, ready{};
  8. int region{-1}, step{-1}, pendingStep{-1};
  9. bool sameWorld{};
  10. };
  11. struct OrbitReturn {
  12. OrbitStage stage{OrbitStage::idle};
  13. std::uint64_t began{};
  14. void arm(std::uint64_t now) { stage=OrbitStage::completion; began=now; }
  15. bool active() const { return stage!=OrbitStage::idle && stage!=OrbitStage::finished; }
  16. OrbitAction observe(std::uint64_t now, const OrbitObservation& s) {
  17. if (!active()) return OrbitAction::none;
  18. auto end=[this](OrbitAction a) { stage=OrbitStage::finished; return a; };
  19. if (now-began>90000) return end(OrbitAction::timedOut);
  20. if (stage==OrbitStage::completion) {
  21. if (!s.exactOwner || !s.emberSelected || s.region!=0 || s.step!=38)
  22. return end(OrbitAction::canceled);
  23. // Return on the first ready frame after completion, with no banner delay.
  24. if (!s.complete || !s.ready || s.pendingStep!=38) return OrbitAction::none;
  25. stage=OrbitStage::selection;
  26. return OrbitAction::select;
  27. }
  28. if (s.step==29 && s.orbitSelected) return end(OrbitAction::orbitSetup);
  29. if (stage==OrbitStage::selection) {
  30. // Native selection/commit can initiate cleanup itself. Never override it.
  31. if (s.step!=38) { stage=OrbitStage::leaving; return OrbitAction::none; }
  32. if (!s.sameWorld || (!s.emberSelected && !s.orbitSelected))
  33. return end(OrbitAction::canceled);
  34. if (s.orbitSelected && s.ready && s.pendingStep==38) {
  35. stage=OrbitStage::leaving;
  36. return OrbitAction::cleanup;
  37. }
  38. } else if (s.step==38 && !s.sameWorld) return end(OrbitAction::canceled);
  39. // Cleanup can temporarily have neither an ActivityClient nor a selected activity.
  40. // Keep observing that native transition; absence is not an arrival or a failure.
  41. return OrbitAction::none;
  42. }
  43. };
  44. }