#include <map>
#include <vector>
#include <optional>
+#include <set>
+
+enum class EventType {
+ CATCH,
+ DEFENSE,
+ DEFENSIVE_SOFT_MINUS,
+ DEFENSIVE_SOFT_PLUS,
+ FORMATION_DEFENSE,
+ FORMATION_OFFENSE,
+ DROP,
+ GOAL,
+ IN,
+ INTERCEPTION,
+ OFFENSIVE_SOFT_MINUS,
+ OFFENSIVE_SOFT_PLUS,
+ OUT,
+ PULL,
+ PULL_LANDED,
+ PULL_OOB,
+ RESTART,
+ SET_DEFENSE,
+ SET_OFFENSE,
+ STALLOUT,
+ STOPPAGE,
+ THEIR_GOAL,
+ THEIR_PULL,
+ THEIR_THROWAWAY,
+ THROWAWAY,
+ UNKNOWN,
+ WAS_D,
+};
class EventsModel : public QAbstractTableModel
{
public:
- EventsModel(sqlite3 *db) : db(db) {}
+ EventsModel(sqlite3 *db, int match_id);
int rowCount(const QModelIndex &parent) const override
{
- refresh_if_needed();
return events.size();
}
int columnCount(const QModelIndex &column) const override
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
QVariant data(const QModelIndex &index, int role) const override;
- int insert_event(uint64_t t, int player_id);
+ unsigned insert_event(uint64_t t, std::optional<int> player_id, std::optional<int> formation_id, const std::string &type = "unknown"); // Returns the row.
+ void delete_event(unsigned row);
+ EventType get_event_type(unsigned row) { return events[row].type; }
+ void set_event_type(unsigned row, const std::string &type);
+ void set_event_formation(unsigned row, int formation_id);
+ uint64_t get_time(unsigned row) { return events[row].t; }
+ unsigned get_last_event_pos(uint64_t t) const; // Last event that happened at or before t.
+ QModelIndex get_last_event_qt(uint64_t t) const {
+ return createIndex(get_last_event_pos(t), 0);
+ }
+ std::optional<int> get_player_id(unsigned row) { return events[row].player_id; }
+
+ struct Status {
+ unsigned our_score, their_score;
+ enum { NOT_STARTED, OFFENSE, DEFENSE } attack_state;
+ unsigned offensive_formation, defensive_formation;
+ bool stoppage;
+ enum { NOT_PULLING, SHOULD_PULL, PULL_IN_AIR } pull_state;
+ unsigned num_passes;
+ unsigned possession_sec;
+ unsigned stoppage_sec;
+ };
+ 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);
+ std::vector<int> sort_team(const std::set<int> &team) const; // Ordered first by gender, then by number.
+ void set_formation_at(uint64_t t, bool offense, unsigned formation);
+
+ // Used to notify when we've inserted a new one into the database.
+ void inserted_new_formation(int formation_id, const std::string &name) {
+ formations[formation_id] = Formation{ formation_id, name };
+ }
private:
struct Player {
std::string number;
std::string name;
};
- mutable std::map<int, Player> players;
+ std::map<int, Player> players;
+ std::map<int, int> player_ordering; // From id to position.
+
+ struct Formation {
+ int formation_id;
+ std::string name;
+ };
+ std::map<int, Formation> formations;
struct Event {
+ int event_id;
uint64_t t;
std::optional<int> player_id;
- std::string type;
+ std::optional<int> formation_id;
+ EventType type;
};
- mutable std::vector<Event> events;
- mutable bool stale = true;
+ std::vector<Event> events;
sqlite3 *db;
+ int match_id;
- void refresh_if_needed() const;
+ void load_data();
};
#endif // !defined(_EVENTS_H)