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

298 lines
9.7 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 "oRunner.h"
#include <set>
class oTeam;//:public oBase {};
typedef oTeam* pTeam;
typedef const oTeam* cTeam;
const unsigned int maxRunnersTeam=32;
class oTeam final : public oAbstractRunner {
public:
enum ResultCalcCacheSymbol {
RCCCourse,
RCCSplitTime,
RCCCardTimes,
RCCCardPunches,
RCCCardControls,
RCCLast
};
private:
int getLegRunningTimeUnadjusted(int leg, bool multidayTotal, bool useComputedRunnerTime) const;
/** Return the total time the team has been resting (pursuit start etc.) up to the specified leg */
int getLegRestingTime(int leg, bool useComputedRunnerTime) const;
void speakerLegInfo(int leg, int specifiedLeg, int courseControlId,
int &missingLeg, int &totalLeg,
RunnerStatus &status, int &runningTime) const;
void propagateClub();
protected:
vector<pRunner> Runners;
void setRunnerInternal(int k, pRunner r);
static const int dataSize = 160;
int getDISize() const {return dataSize;}
BYTE oData[dataSize];
BYTE oDataOld[dataSize];
// Remove runner r by force and mark as need correction
void correctRemove(pRunner r);
// Update hash
void changeId(int newId);
struct TeamPlace {
DynamicValue p; // Day result
DynamicValue totalP; // Total result
};
mutable vector<TeamPlace> tPlace;
TeamPlace &getTeamPlace(int leg) const;
struct ComputedLegResult {
int version = -1;
int time = 0;
RunnerStatus status = StatusUnknown;
ComputedLegResult() {};
};
mutable vector<ComputedLegResult> tComputedResults;
void setTmpTime(int t) const { tmpSortTime = tmpDefinedTime = t; }
mutable int tmpSortTime;
mutable int tmpDefinedTime;
mutable int tmpSortStatus;
mutable RunnerStatus tmpCachedStatus;
mutable vector< vector< vector<int> > > resultCalculationCache;
struct RogainingResult {
RogainingResult() { reset(); }
int points;
int reduction;
int overtime;
void reset() {
points = 0;
reduction = 0;
overtime = 0;
}
};
mutable pair<int, RogainingResult> tTeamPatrolRogainingAndVersion;
const ComputedLegResult &getComputedResult(int leg) const;
void setComputedResult(int leg, ComputedLegResult &comp) const;
string getRunners() const;
bool matchTeam(int number, const wchar_t *s_lc) const;
int tNumRestarts; //Number of restarts for team
int getLegToUse(int leg) const; // Get the number of the actual
// runner to consider for a given leg
// Maps -1 to last runner
void addTableRow(Table &table) const;
pair<int, bool> inputData(int id, const wstring &input,
int inputId, wstring &output, bool noUpdate);
void fillInput(int id, vector< pair<wstring, size_t> > &out, size_t &selected) override;
/** Get internal data buffers for DI */
oDataContainer &getDataBuffers(pvoid &data, pvoid &olddata, pvectorstr &strData) const;
void fillInSortData(SortOrder so,
int leg,
bool linearLeg,
map<int, int> &classId2Linear,
bool &hasRunner) const;
void changedObject() final;
public:
/** Deduce from computed runner times.*/
RunnerStatus deduceComputedStatus() const;
int deduceComputedRunningTime() const;
int deduceComputedPoints() const;
const pair<wstring, int> getRaceInfo() override;
static const shared_ptr<Table> &getTable(oEvent *oe);
/** Check the the main leg is set if any parallel is set. Returns true if corrections where made.*/
bool checkValdParSetup();
int getRanking() const;
int classInstance() const override {
return 0; // Not supported
}
void resetResultCalcCache() const;
vector< vector<int> > &getResultCache(ResultCalcCacheSymbol symb) const;
void setResultCache(ResultCalcCacheSymbol symb, int leg, vector<int> &data) const;
void markClassChanged(int controlId);
void setClub(const wstring &name) override;
pClub setClubId(int clubId) override;
/// Returns team fee (including participating runners fees)
int getTeamFee() const;
/** Remove runner from team (and from competition)
@param askRemoveRunner ask if runner should be removed from cmp. Otherwise just do it.
*/
void removeRunner(gdioutput &gdi, bool askRemoveRunner, int runnerIx);
// Get entry date of team
wstring getEntryDate(bool dummy) const;
// Get the team itself
cTeam getTeam() const {return this;}
pTeam getTeam() {return this;}
int getRunningTime(bool computedTime) const override;
/// Input data for multiday event
void setInputData(const oTeam &t);
void remove();
bool canRemove() const;
void prepareRemove();
bool skip() const {return isRemoved();}
void setTeamMemberStatus(RunnerStatus memberStatus); // Set DNS or CANCEL, NotCompeting etc to team and its members
// If apply is triggered by a runner, don't go further than that runner.
void apply(ChangeType ct, pRunner source) override;
// Set bibs on team members
void applyBibs();
void quickApply();
// Evaluate card and times. Synchronize to server if changeType is update.
void evaluate(ChangeType changeType);
void adjustMultiRunners();
int getRogainingPoints(bool computed, bool multidayTotal) const override;
int getRogainingReduction(bool computed) const override;
int getRogainingOvertime(bool computed) const override;
int getRogainingPointsGross(bool computed) const override;
int getRogainingPatrolPoints(bool multidayTotal) const;
int getRogainingPatrolReduction() const;
int getRogainingPatrolOvertime() const;
void fillSpeakerObject(int leg, int courseControlId, int previousControlCourseId,
bool totalResult, oSpeakerObject &spk) const;
bool isRunnerUsed(int Id) const;
void setRunner(unsigned i, pRunner r, bool syncRunner);
pRunner getRunner(unsigned leg) const;
int getNumRunners() const {return Runners.size();}
int getNumAssignedRunners() const {
int cnt = 0;
for (auto &r : Runners) if (r) cnt++;
return cnt;
}
void decodeRunners(const string &rns, vector<int> &rid);
void importRunners(const vector<int> &rns);
void importRunners(const vector<pRunner> &rns);
RunnerStatus getStatusComputed(bool allowUpdate) const final;
int getPlace(bool allowUpdate = true) const override {return getLegPlace(-1, false, allowUpdate);}
int getTotalPlace(bool allowUpdate = true) const override {return getLegPlace(-1, true, allowUpdate);}
int getNumShortening() const;
// Number of shortenings up to and including a leg
int getNumShortening(int leg) const;
wstring getDisplayName() const;
wstring getDisplayClub() const;
void setBib(const wstring &bib, int numericalBib, bool updateStartNo) override;
int getLegStartTime(int leg) const;
wstring getLegStartTimeS(int leg) const;
wstring getLegStartTimeCompact(int leg) const;
wstring getLegFinishTimeS(int leg, SubSecond mode) const;
int getLegFinishTime(int leg) const;
int getTimeAfter(int leg, bool allowUpdate) const override;
//Get total running time after leg
wstring getLegRunningTimeS(int leg, bool computed, bool multidayTotal, SubSecond mode) const;
int getLegRunningTime(int leg, bool computed, bool multidayTotal) const;
RunnerStatus getLegStatus(int leg, bool computed, bool multidayTotal) const;
const wstring &getLegStatusS(int leg, bool computed, bool multidayTotal) const;
wstring getLegPlaceS(int leg, bool multidayTotal) const;
wstring getLegPrintPlaceS(int leg, bool multidayTotal, bool withDot) const;
int getLegPlace(int leg, bool multidayTotal, bool allowUpdate = true) const;
bool isResultUpdated(bool totalResult) const override;
static bool compareSNO(const oTeam &a, const oTeam &b);
static bool compareName(const oTeam &a, const oTeam &b) {return a.sName<b.sName;}
static bool compareResult(const oTeam &a, const oTeam &b);
static bool compareResultNoSno(const oTeam &a, const oTeam &b);
static bool compareResultClub(const oTeam& a, const oTeam& b);
static void checkClassesWithReferences(oEvent &oe, set<int> &clsWithRef);
static void convertClassWithReferenceToPatrol(oEvent &oe, const set<int> &clsWithRef);
void set(const xmlobject &xo);
bool write(xmlparser &xml);
void merge(const oBase &input, const oBase *base) final;
oTeam(oEvent *poe, int id);
oTeam(oEvent *poe);
virtual ~oTeam(void);
friend class oClass;
friend class oRunner;
friend class MeosSQL;
friend class oEvent;
};