meos-2024/code/generalresult.h
2023-02-09 08:15:40 +01:00

354 lines
12 KiB
C++

#pragma once
/************************************************************************
MeOS - Orienteering Software
Copyright (C) 2009-2023 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 "oBase.h"
#include "parser.h"
#include "oListInfo.h"
class oAbstractRunner;
class oTeam;
class oRunner;
struct oListParam;
class xmlparser;
class xmlobject;
class GeneralResult
{
private:
const oListParam *context;
mutable bool lockPrepare = false;
protected:
enum PrincipalSort {None, ClassWise, CourseWise};
virtual pair<int, int> score(oTeam &team, RunnerStatus st, int time, int points) const;
virtual RunnerStatus deduceStatus(oTeam &team) const;
virtual int deduceTime(oTeam &team) const;
virtual int deducePoints(oTeam &team) const;
virtual pair<int, int> score(oRunner &runner, RunnerStatus st, int time, int points, bool asTeamMember) const;
virtual RunnerStatus deduceStatus(oRunner &runner) const;
virtual int deduceTime(oRunner &runner, int startTime) const;
virtual int deducePoints(oRunner &runner) const;
virtual void prepareCalculations(oEvent &oe, bool classResult, const set<int> &clsSelection, vector<pRunner> &runners, vector<pTeam> &teams, int inputNumber) const;
virtual void prepareCalculations(oTeam &team, bool classResult) const;
virtual void prepareCalculations(oRunner &runner, bool classResult) const;
virtual void storeOutput(vector<int> &times, vector<int> &numbers) const;
int getListParamTimeToControl() const;
int getListParamTimeFromControl() const;
public:
virtual const string &getTimeStamp() const;
virtual bool isRogaining() const;
struct BaseResultContext {
private:
int leg;
bool useModule;
pair<int,int> controlId; // Start - finish
bool totalResults;
mutable map<int, pair<int, int> > resIntervalCache;
friend class GeneralResult;
};
struct GeneralResultInfo {
oAbstractRunner *src;
int time;
RunnerStatus status;
int score;
int place;
int getNumSubresult(const BaseResultContext &context) const;
bool getSubResult(const BaseResultContext &context, int ix, GeneralResultInfo &out) const;
inline bool compareResult(const GeneralResultInfo &o) const {
if (status != o.status)
return RunnerStatusOrderMap[status] < RunnerStatusOrderMap[o.status];
if (place != o.place)
return place < o.place;
const wstring &name = src->getName();
const wstring &oname = o.src->getName();
return CompareString(LOCALE_USER_DEFAULT, 0,
name.c_str(), name.length(),
oname.c_str(), oname.length()) == CSTR_LESS_THAN;
}
bool operator<(const GeneralResultInfo &o) const {
pClass cls = src->getClassRef(true);
pClass ocls = o.src->getClassRef(true);
if (cls != ocls) {
int so = cls ? cls->getSortIndex() : 0;
int oso = ocls ? ocls->getSortIndex() : 0;
if (so != oso)
return so < oso;
// Use id as fallback
so = cls ? cls->getId() : 0;
oso = ocls ? ocls->getId() : 0;
if (so != oso)
return so < oso;
}
return compareResult(o);
}
};
static void calculateIndividualResults(vector<pRunner> &runners,
const pair<int, int> &controlId,
bool totalResults,
bool inclForestRunners,
bool inclPreliminary,
const string &resTag,
oListInfo::ResultType resType,
int inputNumber,
oEvent &oe,
vector<GeneralResultInfo> &results);
static shared_ptr<BaseResultContext> calculateTeamResults(vector<pTeam> &teams,
int leg,
const pair<int, int> &controlId,
bool totalResults,
const string &resTag,
oListInfo::ResultType resType,
int inputNumber,
oEvent &oe,
vector<GeneralResultInfo> &results);
void setContext(const oListParam *context);
void clearContext();
void calculateTeamResults(vector<oTeam *> &teams,
bool classResult,
oListInfo::ResultType resType,
bool sortTeams,
int inputNumber) const;
void calculateIndividualResults(vector<oRunner *> &runners,
bool classResult,
oListInfo::ResultType resType,
bool sortRunners,
int inputNumber) const;
void sortTeamMembers(vector<oRunner *> &runners) const;
virtual bool isDynamic() const {
return false;
}
template<class T> void sort(vector<T*> &rt, SortOrder so) const;
GeneralResult(void);
virtual ~GeneralResult(void);
};
class ResultAtControl : public GeneralResult {
protected:
pair<int, int> score(oTeam &team, RunnerStatus st, int time, int points) const override;
RunnerStatus deduceStatus(oTeam &team) const override;
int deduceTime(oTeam &team) const override;
int deducePoints(oTeam &team) const override;
pair<int, int> score(oRunner &runner, RunnerStatus st, int time, int points, bool asTeamMember) const override;
RunnerStatus deduceStatus(oRunner &runner) const override;
int deduceTime(oRunner &runner, int startTime) const override;
int deducePoints(oRunner &runner) const override;
};
class TotalResultAtControl : public ResultAtControl {
protected:
int deduceTime(oRunner &runner, int startTime) const override;
RunnerStatus deduceStatus(oRunner &runner) const override;
pair<int, int> score(oRunner &runner, RunnerStatus st, int time, int points, bool asTeamMember) const override;
};
class DynamicResult : public GeneralResult {
public:
enum DynamicMethods {
MTScore,
MDeduceTStatus,
MDeduceTTime,
MDeduceTPoints,
MRScore,
MDeduceRStatus,
MDeduceRTime,
MDeduceRPoints,
_Mlast
};
private:
bool allowRetag = true;
static map<string, DynamicMethods> symb2Method;
static map<DynamicMethods, pair<string, string> > method2SymbName;
static int instanceCount;
mutable int lowAgeLimit = -1;
mutable int highAgeLimit = 1000;
class MethodInfo {
string source;
mutable ParseNode *pn;
string description;
public:
friend class DynamicResult;
MethodInfo();
~MethodInfo();
};
vector<MethodInfo> methods;
mutable bool isCompiled;
mutable Parser parser;
wstring name;
string tag;
wstring description;
wstring annotation;
mutable wstring origin;
string timeStamp;
bool builtIn;
mutable bool readOnly;
const ParseNode *getMethod(DynamicMethods method) const;
void addSymbol(DynamicMethods method, const char *symb, const char *name);
RunnerStatus toStatus(int status) const;
void prepareCommon(oAbstractRunner &runner, bool classResult) const;
public:
bool isDynamic() const override {
return true;
}
bool retaggable() const { return allowRetag; }
void retaggable(bool r) { allowRetag = r; }
void setReadOnly() const {readOnly = true;}
bool isReadOnly() const {return readOnly;}
const string &getTimeStamp() const override {return timeStamp;}
bool isRogaining() const override;
static string undecorateTag(const string &inputTag);
long long getHashCode() const;
void getSymbols(vector< pair<wstring, size_t> > &symb) const;
void getSymbolInfo(int ix, wstring &name, wstring &desc) const;
void declareSymbols(DynamicMethods m, bool clear) const;
void prepareCalculations(oEvent &oe,
bool classResult,
const set<int> &clsSelection,
vector<pRunner> &runners,
vector<pTeam> &teams,
int inputNumber) const override;
void prepareCalculations(oTeam &team, bool classResult) const override;
void prepareCalculations(oRunner &runner, bool classResult) const override;
void storeOutput(vector<int> &times, vector<int> &numbers) const;
pair<int, int> score(oTeam &team, RunnerStatus st, int time, int points) const override;
RunnerStatus deduceStatus(oTeam &team) const override;
int deduceTime(oTeam &team) const override;
int deducePoints(oTeam &team) const override;
pair<int, int> score(oRunner &runner, RunnerStatus st, int time, int points, bool asTeamMember) const override;
RunnerStatus deduceStatus(oRunner &runner) const override;
int deduceTime(oRunner &runner, int startTime) const override;
int deducePoints(oRunner &runner) const override;
DynamicResult();
DynamicResult(const DynamicResult &resIn);
void operator=(const DynamicResult &ctr);
~DynamicResult();
bool hasMethod(DynamicMethods method) const {return getMethod(method) != 0;}
const string &getMethodSource(DynamicMethods method) const;
void setMethodSource(DynamicMethods method, const string &source);
void getMethodTypes(vector< pair<DynamicMethods, string> > &mt) const;
//const string &getMethodName(DynamicMethods method) const;
const string &getTag() const {return tag;}
void setTag(const string &t) {tag = t;}
void setBuiltIn() {builtIn = true;}
bool isBuiltIn() const {return builtIn;}
wstring getName(bool withAnnotation) const;
void setName(const wstring &n) {name = n;}
void setAnnotation(const wstring &a) {annotation = a;}
const wstring &getDescription() const {return description;}
void setDescription(const wstring &n) {description = n;}
void save(const wstring &file) const;
void save(xmlparser &xml) const;
void load(const wstring &file);
void load(const xmlobject &xDef);
void compile(bool forceRecompile) const;
void debugDumpVariables(gdioutput &gdi, bool includeSymbols) const;
void clear();
};
struct GeneralResultCtr {
wstring name;
string tag;
wstring fileSource;
bool isDynamic() const;
bool operator<(const GeneralResultCtr &c) const;
shared_ptr<GeneralResult> ptr;
// True if implicitly loaded (form list or by class results)
bool isImplicit() const {
return fileSource == L"*";
}
GeneralResultCtr(const char *tag, const wstring &name, const shared_ptr<GeneralResult> &ptr);
GeneralResultCtr(const wstring &file, const shared_ptr<DynamicResult> &ptr);
GeneralResultCtr() {}
~GeneralResultCtr();
GeneralResultCtr(const GeneralResultCtr &ctr);
void operator=(const GeneralResultCtr &ctr);
};