meos-2024/code/speakermonitor.h
2024-03-19 08:51:20 +01:00

150 lines
4.5 KiB
C++

#pragma once
/************************************************************************
MeOS - Orienteering Software
Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Melin Software HB - software@melin.nu - www.melin.nu
Eksoppsvägen 16, SE-75646 UPPSALA, Sweden
************************************************************************/
#include "oListInfo.h"
#include <deque>
class gdioutput;
class SpeakerMonitor : public GuiHandler {
private:
struct ResultKey {
int classId;
int radio;
int leg;
ResultKey(int classId, int radio, int leg) :
classId(classId), radio(radio), leg(leg) {}
bool operator<(const ResultKey &key) const {
if (classId != key.classId)
return classId < key.classId;
else if (radio != key.radio)
return radio < key.radio;
else
return leg < key.leg;
}
bool operator==(const ResultKey &key) const {
return radio == key.radio && classId == key.classId && leg == key.leg;
}
};
struct ResultInfo : public ResultKey {
int time;
int totTime;
ResultInfo(const ResultKey &key, int time, int totalTime) :
ResultKey(key), time(time), totTime(totalTime) {}
ResultInfo(int classId, int radio, int leg, int time, int totalTime) :
ResultKey(classId, radio, leg), time(time), totTime(totalTime) {}
};
struct SimpleResult {
SimpleResult() : r(0), eventIx(-1) {}
int totalTime;
pRunner r;
int eventIx;
bool isValid() const {return r != 0;}
};
oEvent &oe;
SpeakerMonitor &operator=(const SpeakerMonitor&); // Not used
set<int> classFilter;
set<int> controlIdFilter;
vector<oEvent::ResultEvent> results;
bool totalResults;
int placeLimit;
int numLimit;
int maxClassNameWidth;
int classWidth;
int timeWidth;
int totWidth;
int extraWidth;
wstring dash;
void renderResult(gdioutput &gdi,
const oEvent::ResultEvent *ahead,
const oEvent::ResultEvent &res,
const oEvent::ResultEvent *behind,
int &order, bool firstResults);
static bool sameResultPoint(const oEvent::ResultEvent &a,
const oEvent::ResultEvent &b);
void getSharedResult(const oEvent::ResultEvent &res, vector<pRunner> &shared) const;
void getSharedResult(const oEvent::ResultEvent &res, wstring &detail) const;
void splitAnalysis(gdioutput &gdi, int xp, int yp, pRunner r);
void getMessage(const oEvent::ResultEvent &res,
wstring &message, deque<wstring> &details);
map<ResultKey, int> firstTimes;
map<ResultKey, int> totalLeaderTimes;
map<ResultKey, map<int, int> > dynamicTotalLeaderTimes;
multimap<int, int> timeToResultIx;
int getResultIx(const ResultInfo &rinfo);
map<int, vector<ResultInfo> > runnerToTimeKey;
vector<SimpleResult> orderedResults;
static bool timeSort(ResultInfo &a, ResultInfo &b) {
return a.time < b.time;
}
const oEvent::ResultEvent *getAdjacentResult(const oEvent::ResultEvent &res, int delta) const;
int getLeaderTime(const oEvent::ResultEvent &res);
int getDynamicLeaderTime(const oEvent::ResultEvent &res, int time);
int getDynamicLeaderTime(const ResultKey &res, int time);
public:
void handle(gdioutput &gdi, BaseInfo &info, GuiEventType type);
SpeakerMonitor(oEvent &oe);
virtual ~SpeakerMonitor();
void setClassFilter(const set<int> &filter, const set<int> &controlIdFilter);
void useTotalResults(bool total) {
totalResults = total;
}
bool useTotalResults() const {
return totalResults;
}
void setLimits(int placeLimit, int numLimit);
void show(gdioutput &gdi);
void calculateResults();
};