#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 . Melin Software HB - software@melin.nu - www.melin.nu Eksoppsvägen 16, SE-75646 UPPSALA, Sweden ************************************************************************/ #include "oBase.h" #include "oRunner.h" #include 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 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 tPlace; TeamPlace &getTeamPlace(int leg) const; struct ComputedLegResult { int version = -1; int time = 0; RunnerStatus status = StatusUnknown; ComputedLegResult() {}; }; mutable vector 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 > > resultCalculationCache; struct RogainingResult { RogainingResult() { reset(); } int points; int reduction; int overtime; void reset() { points = 0; reduction = 0; overtime = 0; } }; mutable pair 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 inputData(int id, const wstring &input, int inputId, wstring &output, bool noUpdate); void fillInput(int id, vector< pair > &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 &classId2Linear, bool &hasRunner) const; void changedObject() final; public: bool matchAbstractRunner(const oAbstractRunner* target) const override; /** Deduce from computed runner times.*/ RunnerStatus deduceComputedStatus() const; int deduceComputedRunningTime() const; int deduceComputedPoints() const; const pair getRaceInfo() override; static const shared_ptr &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 > &getResultCache(ResultCalcCacheSymbol symb) const; void setResultCache(ResultCalcCacheSymbol symb, int leg, vector &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; } /** For legs with many parallel / extra runner, get the runner with the first finish time */ pRunner getRunnerBestTimePar(int linearLegInput) const; void decodeRunners(const string &rns, vector &rid); void importRunners(const vector &rns); void importRunners(const vector &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 &clsWithRef); static void convertClassWithReferenceToPatrol(oEvent &oe, const set &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; };