@@ -31,7 +31,9 @@ Replay::Replay(QString route, QStringList allow, QStringList block, SubMaster *s
3131 events_ = std::make_unique<std::vector<Event *>>();
3232 new_events_ = std::make_unique<std::vector<Event *>>();
3333
34+ qRegisterMetaType<FindFlag>(" FindFlag" );
3435 connect (this , &Replay::seekTo, this , &Replay::doSeek);
36+ connect (this , &Replay::seekToFlag, this , &Replay::doSeekToFlag);
3537 connect (this , &Replay::segmentChanged, this , &Replay::queueSegment);
3638}
3739
@@ -109,6 +111,55 @@ void Replay::doSeek(int seconds, bool relative) {
109111 queueSegment ();
110112}
111113
114+ void Replay::doSeekToFlag (FindFlag flag) {
115+ if (flag == FindFlag::nextEngagement) {
116+ qInfo () << " seeking to the next engagement..." ;
117+ } else if (flag == FindFlag::nextDisEngagement) {
118+ qInfo () << " seeking to the disengagement..." ;
119+ }
120+
121+ updateEvents ([&]() {
122+ if (auto next = find (flag)) {
123+ uint64_t tm = *next - 2 * 1e9 ; // seek to 2 seconds before next
124+ if (tm <= cur_mono_time_) {
125+ return true ;
126+ }
127+
128+ cur_mono_time_ = tm;
129+ current_segment_ = currentSeconds () / 60 ;
130+ return isSegmentMerged (current_segment_);
131+ } else {
132+ qWarning () << " seeking failed" ;
133+ return true ;
134+ }
135+ });
136+
137+ queueSegment ();
138+ }
139+
140+ std::optional<uint64_t > Replay::find (FindFlag flag) {
141+ // Search in all segments
142+ for (const auto &[n, _] : segments_) {
143+ if (n < current_segment_) continue ;
144+
145+ LogReader log;
146+ bool cache_to_local = true ; // cache qlog to local for fast seek
147+ if (!log.load (route_->at (n).qlog .toStdString (), nullptr , cache_to_local, 0 , 3 )) continue ;
148+
149+ for (const Event *e : log.events ) {
150+ if (e->mono_time > cur_mono_time_ && e->which == cereal::Event::Which::CONTROLS_STATE) {
151+ const auto cs = e->event .getControlsState ();
152+ if (flag == FindFlag::nextEngagement && cs.getEnabled ()) {
153+ return e->mono_time ;
154+ } else if (flag == FindFlag::nextDisEngagement && !cs.getEnabled ()) {
155+ return e->mono_time ;
156+ }
157+ }
158+ }
159+ }
160+ return std::nullopt ;
161+ }
162+
112163void Replay::pause (bool pause) {
113164 updateEvents ([=]() {
114165 qInfo () << (pause ? " paused..." : " resuming" );
0 commit comments