]> git.sesse.net Git - pkanalytics/commitdiff
Backdate substitutions so that they're a bit easier to deal with.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 1 May 2023 22:25:06 +0000 (00:25 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 1 May 2023 22:25:06 +0000 (00:25 +0200)
events.cpp
events.h
main.cpp

index bf16202289f650913f49a1f1470149193966f33f..bce262555feda49dbd9718e0d4caa751750158f5 100644 (file)
@@ -320,3 +320,48 @@ set<int> EventsModel::get_team_at(uint64_t t)
        }
        return team;
 }
+
+void EventsModel::set_team_at(uint64_t t, const set<int> &new_team)
+{
+       // Backdate to the last goal or stoppage, _or_ the last time someone
+       // going out is mentioned. (We don't really track injuries yet;
+       // do we want an explicit injury type? If we had one, it would probably
+       // be the simplest.)
+       uint64_t backdate_point = 0;
+       for (const Event &e : events) {
+               if (e.t > t) {
+                       break;
+               }
+               if (e.type == "goal" || e.type == "their_goal" || e.type == "stoppage" || e.type == "reset") {
+                       backdate_point = e.t + 1;
+               }
+               if (e.player_id.has_value() && !new_team.count(*e.player_id)) {
+                       backdate_point = e.t + 1;
+               }
+       }
+
+       // Delete all in/outs already at the backdate point.
+       for (unsigned i = 0; i < events.size(); ) {
+               if (events[i].t > backdate_point) {
+                       break;
+               }
+               if (events[i].t == backdate_point && (events[i].type == "in" || events[i].type == "out")) {
+                       delete_event(i);
+               } else {
+                       ++i;
+               }
+       }
+
+       // Finally make the subs we need.
+       set<int> old_team = get_team_at(backdate_point);
+       for (int player_id : old_team) {
+               if (!new_team.count(player_id)) {
+                       insert_event(backdate_point, player_id, "out");
+               }
+       }
+       for (int player_id : new_team) {
+               if (!old_team.count(player_id)) {
+                       insert_event(backdate_point, player_id, "in");
+               }
+       }
+}
index c1255578a50710de618e1b61ecdf6e938e54a4cd..62f1f7e772d68611bd7020f4aa37223d129a5784 100644 (file)
--- a/events.h
+++ b/events.h
@@ -42,6 +42,7 @@ public:
        };
        Status get_status_at(uint64_t t);
        std::set<int> get_team_at(uint64_t t);
+       void set_team_at(uint64_t, const std::set<int> &new_team);
 
 private:
        struct Player {
index f6d289d201d97616bf7d2501eb176a29796210e7..46a0d1c666a02aa401e40dc25784ab486cf2c36f 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -208,32 +208,11 @@ void MainWindow::delete_current_event()
 void MainWindow::make_substitution()
 {
        QItemSelectionModel *select = ui->player_view->selectionModel();
-
-       // FIXME: we should backdate t to start of point (last goal, or 0) if:
-       // - no players we're removing have had actions yet
-       // - there have been no other in/out events
-       //
-       // ...but if so, we might need to modify in/out events that are already there
-       // (perhaps just overwrite them all?)
-       uint64_t t = video->position();
-
-       set<int> old_team = events->get_team_at(t);
        set<int> new_team;
-
        for (QModelIndex row : select->selectedRows()) {
                new_team.insert(players->get_player_id(row.row()));
        }
-
-       for (int player_id : old_team) {
-               if (!new_team.count(player_id)) {
-                       events->insert_event(t, player_id, "out");
-               }
-       }
-       for (int player_id : new_team) {
-               if (!old_team.count(player_id)) {
-                       events->insert_event(t, player_id, "in");
-               }
-       }
+       events->set_team_at(video->position(), new_team);
 }
 
 void MainWindow::update_ui_from_time(uint64_t t)