295 lines
9.5 KiB
C++
295 lines
9.5 KiB
C++
#pragma once
|
|
|
|
/************************************************************************
|
|
MeOS - Orienteering Software
|
|
Copyright (C) 2009-2020 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 : 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 &oTeam::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);
|
|
|
|
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) const;
|
|
int getLegFinishTime(int leg) const;
|
|
|
|
int getTimeAfter(int leg) const;
|
|
|
|
//Get total running time after leg
|
|
wstring getLegRunningTimeS(int leg, bool computed, bool multidayTotal) 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 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;
|
|
};
|