#pragma once #include #include #include #include #include "tools/replay/route.h" enum class TimelineType { None, Engaged, AlertInfo, AlertWarning, AlertCritical, UserFlag }; enum class FindFlag { nextEngagement, nextDisEngagement, nextUserFlag, nextInfo, nextWarning, nextCritical }; class Timeline { public: struct Entry { double start_time; double end_time; TimelineType type; std::string text1; std::string text2; }; Timeline() : timeline_entries_(std::make_shared>()) {} ~Timeline(); void initialize(const Route &route, uint64_t route_start_ts, bool local_cache, std::function)> callback); std::optional find(double cur_ts, FindFlag flag) const; std::optional findAlertAtTime(double target_time) const; const std::shared_ptr> getEntries() const { return std::atomic_load(&timeline_entries_); } private: void buildTimeline(const Route &route, uint64_t route_start_ts, bool local_cache, std::function)> callback); void updateEngagementStatus(const cereal::SelfdriveState::Reader &cs, std::optional &idx, double seconds); void updateAlertStatus(const cereal::SelfdriveState::Reader &cs, std::optional &idx, double seconds); std::thread thread_; std::atomic should_exit_ = false; // Temporarily holds entries before they are sorted and finalized std::vector staging_entries_; // Final sorted timeline entries std::shared_ptr> timeline_entries_; };