]> git.sesse.net Git - pkanalytics/blobdiff - stats.cpp
Add some offense events, now working-ish.
[pkanalytics] / stats.cpp
index b0ba4b3881ee5230206f9508ce23aeb04d4eaba5..9d621249cdafdb873b627bb20bb8f3fcfea4f823 100644 (file)
--- a/stats.cpp
+++ b/stats.cpp
@@ -4,6 +4,7 @@
 #include <QGridLayout>
 #include <QVideoWidget>
 #include <QShortcut>
+#include <algorithm>
 #include <string>
 #include <map>
 #include <vector>
 #include <sqlite3.h>
 #include "mainwindow.h"
 #include "ui_mainwindow.h"
+#include "events.h"
 
 using namespace std;
 
-std::string format_timestamp(uint64_t pos)
+string format_timestamp(uint64_t pos)
 {
        int ms = pos % 1000;
        pos /= 1000;
@@ -28,150 +30,6 @@ std::string format_timestamp(uint64_t pos)
        return buf;
 }
 
-class EventsModel : public QAbstractTableModel
-{
-public:
-       EventsModel(sqlite3 *db) : db(db) {}
-
-       int rowCount(const QModelIndex &parent) const override
-       {
-               refresh_if_needed();
-               return events.size();
-       }
-       int columnCount(const QModelIndex &column) const override
-       {
-               return 3;
-       }
-       QVariant headerData(int section, Qt::Orientation orientation, int role) const override
-       {
-               if (role != Qt::DisplayRole) {
-                       return QVariant();
-               }
-               if (orientation == Qt::Horizontal) {
-                       if (section == 0) {
-                               return "Time";
-                       } else if (section == 1) {
-                               return "Player";
-                       } else {
-                               return "Type";
-                       }
-               } else {
-                       return "";
-               }
-       }
-
-       QVariant data(const QModelIndex &index, int role) const override
-       {
-               if (role != Qt::DisplayRole) {
-                       return QVariant();
-               }
-               refresh_if_needed();
-               if (index.column() == 0) {
-                       return QString::fromUtf8(format_timestamp(events[index.row()].t));
-               } else if (index.column() == 1) {
-                       optional<int> player_id = events[index.row()].player_id;
-                       if (player_id) {
-                               const Player &p = players[*player_id];
-                               return QString::fromUtf8(p.name + " (" + p.number + ")");
-                       } else {
-                               return QVariant();
-                       }
-               } else if (index.column() == 2) {
-                       return QString::fromUtf8(events[index.row()].type);
-               }
-               return QVariant();
-       }
-
-private:
-       struct Player {
-               int player_id;
-               string number;
-               string name;
-       };
-       mutable map<int, Player> players;
-
-       struct Event {
-               uint64_t t;
-               optional<int> player_id;
-               string type;
-       };
-       mutable vector<Event> events;
-       mutable bool stale = true;
-
-       sqlite3 *db;
-
-       void refresh_if_needed() const;
-};
-
-void EventsModel::refresh_if_needed() const
-{
-       if (!stale) {
-               return;
-       }
-
-       players.clear();
-       events.clear();
-       stale = false;
-
-       // Read the players.
-       sqlite3_stmt *stmt;
-       int ret = sqlite3_prepare_v2(db, "SELECT player, number, name FROM player", -1, &stmt, 0);
-       if (ret != SQLITE_OK) {
-               fprintf(stderr, "SELECT prepare: %s\n", sqlite3_errmsg(db));
-               abort();
-       }
-       for ( ;; ) {
-               ret = sqlite3_step(stmt);
-               if (ret == SQLITE_ROW) {
-                       Player p;
-                       p.player_id = sqlite3_column_int(stmt, 0);
-                       p.number = (const char *)sqlite3_column_text(stmt, 1);
-                       p.name = (const char *) sqlite3_column_text(stmt, 2);
-                       players[p.player_id] = move(p);
-               } else if (ret == SQLITE_DONE) {
-                       break;
-               } else {
-                       fprintf(stderr, "SELECT step: %s\n", sqlite3_errmsg(db));
-                       abort();
-               }
-       }
-       ret = sqlite3_finalize(stmt);
-       if (ret != SQLITE_OK) {
-               fprintf(stderr, "SELECT finalize: %s\n", sqlite3_errmsg(db));
-               abort();
-       }
-
-       // Read the events.
-       ret = sqlite3_prepare_v2(db, "SELECT t, player, type FROM event", -1, &stmt, 0);
-       if (ret != SQLITE_OK) {
-               fprintf(stderr, "SELECT prepare: %s\n", sqlite3_errmsg(db));
-               abort();
-       }
-       for ( ;; ) {
-               ret = sqlite3_step(stmt);
-               if (ret == SQLITE_ROW) {
-                       Event e;
-                       e.t = sqlite3_column_int(stmt, 0);
-                       e.player_id = sqlite3_column_int(stmt, 1);
-                       e.type = (const char *)sqlite3_column_text(stmt, 2);
-                       events.push_back(move(e));
-               } else if (ret == SQLITE_DONE) {
-                       break;
-               } else {
-                       fprintf(stderr, "SELECT step: %s\n", sqlite3_errmsg(db));
-                       abort();
-               }
-       }
-       ret = sqlite3_finalize(stmt);
-       if (ret != SQLITE_OK) {
-               fprintf(stderr, "SELECT finalize: %s\n", sqlite3_errmsg(db));
-               abort();
-       }
-
-       // TODO what if data changes externally?
-       //emit dataChanged(QModelIndex(
-}
-
 MainWindow::MainWindow()
 {
        player = new QMediaPlayer;
@@ -219,17 +77,50 @@ MainWindow::MainWindow()
                // Needs to be set anew when we modify setText(), evidently.
                ui->play_pause->setShortcut(QCoreApplication::translate("MainWindow", "Space", nullptr));
        });
+
+       connect(ui->player_1, &QPushButton::clicked, [this]() {
+               ui->event_view->selectRow(model->insert_event(player->position(), 1));
+       });
+       connect(ui->player_2, &QPushButton::clicked, [this]() {
+               ui->event_view->selectRow(model->insert_event(player->position(), 2));
+       });
+       connect(ui->player_3, &QPushButton::clicked, [this]() {
+               ui->event_view->selectRow(model->insert_event(player->position(), 3));
+       });
+       connect(ui->player_4, &QPushButton::clicked, [this]() {
+               ui->event_view->selectRow(model->insert_event(player->position(), 4));
+       });
+       connect(ui->player_5, &QPushButton::clicked, [this]() {
+               ui->event_view->selectRow(model->insert_event(player->position(), 5));
+       });
+       connect(ui->player_6, &QPushButton::clicked, [this]() {
+               ui->event_view->selectRow(model->insert_event(player->position(), 6));
+       });
+       connect(ui->player_7, &QPushButton::clicked, [this]() {
+               ui->event_view->selectRow(model->insert_event(player->position(), 7));
+       });
+
+       // TODO: disable if nothing is selected
+       connect(ui->catch_, &QPushButton::clicked, [this]() { set_current_event_type("catch"); });
+       connect(ui->throwaway, &QPushButton::clicked, [this]() { set_current_event_type("throwaway"); });
+       connect(ui->drop, &QPushButton::clicked, [this]() { set_current_event_type("drop"); });
+       connect(ui->goal, &QPushButton::clicked, [this]() { set_current_event_type("goal"); });
+       connect(ui->offensive_soft_plus, &QPushButton::clicked, [this]() { set_current_event_type("offensive_soft_plus"); });
+       connect(ui->offensive_soft_minus, &QPushButton::clicked, [this]() { set_current_event_type("offensive_soft_minus"); });
+       connect(ui->pull, &QPushButton::clicked, [this]() { set_current_event_type("pull"); });
+       connect(ui->pull_landed, &QPushButton::clicked, [this]() { set_current_event_type("pull_landed"); });
 }
 
-void MainWindow::setModel(QAbstractItemModel *model)
+void MainWindow::setModel(EventsModel *model)
 {
        ui->event_view->setModel(model);
+       this->model = model;
 }
 
 void MainWindow::seek(int64_t delta_ms)
 {
        int64_t current_pos = buffered_seek ? *buffered_seek : player->position();
-       uint64_t pos = std::max<int64_t>(current_pos + delta_ms, 0);
+       uint64_t pos = max<int64_t>(current_pos + delta_ms, 0);
        buffered_seek = pos;
        if (!playing) {
                player->setPlaybackRate(0.01);
@@ -237,6 +128,16 @@ void MainWindow::seek(int64_t delta_ms)
        }
 }
 
+void MainWindow::set_current_event_type(const string &type)
+{
+       QItemSelectionModel *select = ui->event_view->selectionModel();
+       if (!select->hasSelection()) {
+               return;
+       }
+       int row = select->selectedRows().front().row();  // Should only be one, due to our selection behavior.
+       model->set_event_type(row, type);
+}
+
 sqlite3 *open_db(const char *filename)
 {
        sqlite3 *db;