#pragma once
/************************************************************************
MeOS - Orienteering Software
Copyright (C) 2009-2022 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 .
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 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 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 &clsSelection, vector &runners, vector &teams, int inputNumber) const;
virtual void prepareCalculations(oTeam &team, bool classResult) const;
virtual void prepareCalculations(oRunner &runner, bool classResult) const;
virtual void storeOutput(vector ×, vector &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 controlId; // Start - finish
bool totalResults;
mutable map > 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 &runners,
const pair &controlId,
bool totalResults,
bool inclForestRunners,
bool inclPreliminary,
const string &resTag,
oListInfo::ResultType resType,
int inputNumber,
oEvent &oe,
vector &results);
static shared_ptr calculateTeamResults(vector &teams,
int leg,
const pair &controlId,
bool totalResults,
const string &resTag,
oListInfo::ResultType resType,
int inputNumber,
oEvent &oe,
vector &results);
void setContext(const oListParam *context);
void clearContext();
void calculateTeamResults(vector &teams,
bool classResult,
oListInfo::ResultType resType,
bool sortTeams,
int inputNumber) const;
void calculateIndividualResults(vector &runners,
bool classResult,
oListInfo::ResultType resType,
bool sortRunners,
int inputNumber) const;
void sortTeamMembers(vector &runners) const;
virtual bool isDynamic() const {
return false;
}
template void sort(vector &rt, SortOrder so) const;
GeneralResult(void);
virtual ~GeneralResult(void);
};
class ResultAtControl : public GeneralResult {
protected:
pair 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 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 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 symb2Method;
static map > 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 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 > &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 &clsSelection,
vector &runners,
vector &teams,
int inputNumber) const override;
void prepareCalculations(oTeam &team, bool classResult) const override;
void prepareCalculations(oRunner &runner, bool classResult) const override;
void storeOutput(vector ×, vector &numbers) const;
pair 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 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 > &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 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 &ptr);
GeneralResultCtr(const wstring &file, const shared_ptr &ptr);
GeneralResultCtr() {}
~GeneralResultCtr();
GeneralResultCtr(const GeneralResultCtr &ctr);
void operator=(const GeneralResultCtr &ctr);
};