MeOS version 3.6.1089
This commit is contained in:
parent
a4e2689418
commit
06a6c4ff67
@ -7,7 +7,6 @@
|
||||
const wstring _EmptyWString=L"";
|
||||
const string _EmptyString="";
|
||||
const string _VacantName="Vakant";
|
||||
const string _UnkownName="N.N.";
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
|
||||
@ -1252,6 +1252,7 @@ X (Y deltagare, grupp Z, W) = X (Y závodníků, skupina Z, W)
|
||||
X har startat = X odstartovalo
|
||||
X kontroller = X kontrol
|
||||
X meter = X metrů
|
||||
X m = X m
|
||||
X poäng fattas = X bodů chybí
|
||||
X rader kunde inte raderas = X řádků nemůže být smazáno
|
||||
X senaste = X nejnovějších
|
||||
|
||||
@ -2303,6 +2303,7 @@ X har redan ett resultat. Vi du fortsätta? = X har allerede et resultat. Vil du
|
||||
X har startat = X er startet
|
||||
X kontroller = X poster
|
||||
X meter = X meter
|
||||
X m = X m
|
||||
X och Y[N by N] = X og Y
|
||||
X p = X p
|
||||
X platser. Startar Y = X pladser. Starter Y
|
||||
|
||||
@ -1252,7 +1252,8 @@ X (Saknar e-post) = X (Has no e-mail)
|
||||
X (Y deltagare, grupp Z, W) = X (Y competitors, group Z, W)
|
||||
X har startat = X started
|
||||
X kontroller = X controls
|
||||
X meter = X meter
|
||||
X meter = X meters
|
||||
X m = X m
|
||||
X poäng fattas = X points missing
|
||||
X rader kunde inte raderas = X row(s) could not be deleted
|
||||
X senaste = X latest
|
||||
@ -2432,3 +2433,6 @@ Kunde inte öppna databasen (X) = Could not connect to database (X)
|
||||
Kunde inte ladda upp löpardatabasen (X) = Could not upload runner database (X)
|
||||
Runner check time = Runner check time
|
||||
ClassNumEntries = Number of entries in class
|
||||
Flera lopp i valfri ordning = Several races in any order
|
||||
Knockout sammanställning = Knock-out summary
|
||||
X anmälda = X entries
|
||||
|
||||
@ -1254,6 +1254,7 @@ X (Y deltagare, grupp Z, W) = X (Y coureurs, groupe Z, W)
|
||||
X har startat = X est parti
|
||||
X kontroller = X postes
|
||||
X meter = X mètres
|
||||
X m = X m
|
||||
X poäng fattas = X points manquant
|
||||
X rader kunde inte raderas = X lignes ne peuvent être effacées
|
||||
X senaste = X derniers
|
||||
|
||||
@ -390,9 +390,9 @@ void MeosSQL::upgradeDB(const string &db, oDataContainer const * dc) {
|
||||
query.execute(sql);
|
||||
}
|
||||
}
|
||||
else if (db == "oRunner") {
|
||||
else if (db == "oRunner" || db == "oTeam") {
|
||||
if (!eCol.count("InputTime")) {
|
||||
string sql = "ALTER TABLE oRunner ";
|
||||
string sql = "ALTER TABLE " + db + " ";
|
||||
sql += "ADD COLUMN " + C_INT("InputTime");
|
||||
sql += "ADD COLUMN " + C_INT("InputStatus");
|
||||
sql += "ADD COLUMN " + C_INT("InputPoints");
|
||||
@ -522,7 +522,7 @@ bool MeosSQL::openDB(oEvent *oe)
|
||||
query << C_START("oCard")
|
||||
<< C_INT("CardNo")
|
||||
<< C_UINT("ReadId")
|
||||
<< C_STRING("Punches", 1024) << C_END();
|
||||
<< C_STRING("Punches", 16*190) << C_END();
|
||||
|
||||
query.execute();
|
||||
|
||||
@ -558,7 +558,6 @@ bool MeosSQL::openDB(oEvent *oe)
|
||||
// Ugrade oRunner
|
||||
upgradeDB("oControl", oe->oControlData);
|
||||
|
||||
|
||||
query.reset();
|
||||
query << C_START("oCourse")
|
||||
<< C_STRING("Name")
|
||||
@ -577,6 +576,7 @@ bool MeosSQL::openDB(oEvent *oe)
|
||||
<< C_INT("Club") << C_INT("Class")
|
||||
<< C_INT("StartTime") << C_INT("FinishTime")
|
||||
<< C_INT("Status") << C_INT("StartNo")
|
||||
<< C_INT("InputTime") << C_INT("InputStatus") << C_INT("InputPoints") << C_INT("InputPlace")
|
||||
<< oe->oTeamData->generateSQLDefinition() << C_END();
|
||||
query.execute();
|
||||
|
||||
@ -1165,7 +1165,7 @@ OpFailStatus MeosSQL::SyncRead(oEvent *oe) {
|
||||
while (row = res.fetch_row()) {
|
||||
oControl c(oe, row["Id"]);
|
||||
storeControl(row, c);
|
||||
oe->Controls.push_back(c);
|
||||
oe->addControl(c);
|
||||
|
||||
oe->sqlUpdateControls = max(c.sqlUpdated, oe->sqlUpdateControls);
|
||||
oe->sqlCounterControls = max(c.counter, oe->sqlCounterControls);
|
||||
@ -1191,7 +1191,7 @@ OpFailStatus MeosSQL::SyncRead(oEvent *oe) {
|
||||
set<int> tmp;
|
||||
while (row = res.fetch_row()) {
|
||||
oCourse c(oe, row["Id"]);
|
||||
storeCourse(row, c, tmp);
|
||||
storeCourse(row, c, tmp, false);
|
||||
oe->addCourse(c);
|
||||
|
||||
oe->sqlUpdateCourses = max(c.sqlUpdated, oe->sqlUpdateCourses);
|
||||
@ -1216,7 +1216,7 @@ OpFailStatus MeosSQL::SyncRead(oEvent *oe) {
|
||||
Row row;
|
||||
while (row = res.fetch_row()) {
|
||||
oClass c(oe, row["Id"]);
|
||||
storeClass(row, c, false);
|
||||
storeClass(row, c, false, false);
|
||||
|
||||
c.changed = false;
|
||||
c.reChanged = false;
|
||||
@ -1277,7 +1277,7 @@ OpFailStatus MeosSQL::SyncRead(oEvent *oe) {
|
||||
Row row;
|
||||
while (row = res.fetch_row()) {
|
||||
oRunner r(oe, row["Id"]);
|
||||
storeRunner(row, r, false, false, false);
|
||||
storeRunner(row, r, false, false, false, false);
|
||||
assert(!r.changed);
|
||||
oe->addRunner(r, false);
|
||||
|
||||
@ -1309,7 +1309,7 @@ OpFailStatus MeosSQL::SyncRead(oEvent *oe) {
|
||||
while (row = res.fetch_row()) {
|
||||
oTeam t(oe, row["Id"]);
|
||||
|
||||
storeTeam(row, t, false);
|
||||
storeTeam(row, t, false, false);
|
||||
|
||||
pTeam at = oe->addTeam(t, false);
|
||||
|
||||
@ -1427,6 +1427,7 @@ OpFailStatus MeosSQL::SyncRead(oEvent *oe) {
|
||||
}
|
||||
|
||||
oe->runnerDB->setDataDate(dateTime);
|
||||
processMissingObjects();
|
||||
|
||||
return retValue;
|
||||
}
|
||||
@ -1512,7 +1513,7 @@ void MeosSQL::storePunch(const Row &row, oFreePunch &p, bool rehash)
|
||||
}
|
||||
|
||||
OpFailStatus MeosSQL::storeClass(const Row &row, oClass &c,
|
||||
bool readCourses)
|
||||
bool readCourses, bool allowSubRead)
|
||||
{
|
||||
OpFailStatus success = opStatusOK;
|
||||
|
||||
@ -1523,11 +1524,13 @@ OpFailStatus MeosSQL::storeClass(const Row &row, oClass &c,
|
||||
c.importLegMethod(lm);
|
||||
|
||||
set<int> cid;
|
||||
vector< vector<int> > multip;
|
||||
vector<vector<int>> multip;
|
||||
oClass::parseCourses(multi, multip, cid);
|
||||
|
||||
int classCourse = row["Course"];
|
||||
if (classCourse != 0)
|
||||
cid.insert(classCourse);
|
||||
|
||||
if (!readCourses) {
|
||||
for (set<int>::iterator clsIt = cid.begin(); clsIt != cid.end(); ++clsIt) {
|
||||
if (!c.oe->getCourse(*clsIt))
|
||||
@ -1535,12 +1538,26 @@ OpFailStatus MeosSQL::storeClass(const Row &row, oClass &c,
|
||||
}
|
||||
}
|
||||
|
||||
if (readCourses)
|
||||
if (readCourses) {
|
||||
if (allowSubRead) {
|
||||
success = min(success, syncReadClassCourses(&c, cid, readCourses));
|
||||
}
|
||||
else {
|
||||
// Cannot read from database here. Add implicitly added courses
|
||||
for (int x : cid) {
|
||||
if (c.oe->getCourse(x) == nullptr) {
|
||||
oCourse oc(c.oe, x);
|
||||
oc.setImplicitlyCreated();
|
||||
addedFromDatabase(c.oe->addCourse(oc));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (classCourse != 0)
|
||||
c.Course = c.oe->getCourse(classCourse);
|
||||
else
|
||||
c.Course = 0;
|
||||
c.Course = nullptr;
|
||||
|
||||
c.importCourses(multip);
|
||||
|
||||
@ -1559,8 +1576,8 @@ OpFailStatus MeosSQL::storeClass(const Row &row, oClass &c,
|
||||
}
|
||||
|
||||
OpFailStatus MeosSQL::storeCourse(const Row &row, oCourse &c,
|
||||
set<int> &readControls)
|
||||
{
|
||||
set<int> &readControls,
|
||||
bool allowSubRead) {
|
||||
OpFailStatus success = opStatusOK;
|
||||
|
||||
c.Name = fromUTF((string)row["Name"]);
|
||||
@ -1573,12 +1590,16 @@ OpFailStatus MeosSQL::storeCourse(const Row &row, oCourse &c,
|
||||
// Might have been created during last call.
|
||||
// Then just read to update
|
||||
if (!c.Controls[i]->existInDB()) {
|
||||
c.Controls[i]->setImplicitlyCreated();
|
||||
if (allowSubRead) {
|
||||
c.Controls[i]->changed = false;
|
||||
success = min(success, syncRead(true, c.Controls[i]));
|
||||
}
|
||||
else
|
||||
addedFromDatabase(c.Controls[i]);
|
||||
}
|
||||
else {
|
||||
readControls.insert(c.Controls[i]->getId());
|
||||
//success = min(success, syncRead(false, c.Controls[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1598,7 +1619,8 @@ OpFailStatus MeosSQL::storeCourse(const Row &row, oCourse &c,
|
||||
OpFailStatus MeosSQL::storeRunner(const Row &row, oRunner &r,
|
||||
bool readCourseCard,
|
||||
bool readClassClub,
|
||||
bool readRunners)
|
||||
bool readRunners,
|
||||
bool allowSubRead)
|
||||
{
|
||||
OpFailStatus success = opStatusOK;
|
||||
oEvent *oe=r.oe;
|
||||
@ -1637,10 +1659,15 @@ OpFailStatus MeosSQL::storeRunner(const Row &row, oRunner &r,
|
||||
set<int> controlIds;
|
||||
if (!r.Course) {
|
||||
oCourse oc(oe, row["Course"]);
|
||||
oc.setImplicitlyCreated();
|
||||
if (allowSubRead)
|
||||
success = min(success, syncReadCourse(true, &oc, controlIds));
|
||||
if (!oc.isRemoved()) {
|
||||
r.Course = oe->addCourse(oc);
|
||||
addedFromDatabase(r.Course);
|
||||
}
|
||||
else if (readCourseCard)
|
||||
}
|
||||
else if (readCourseCard && allowSubRead)
|
||||
success = min(success, syncReadCourse(false, r.Course, controlIds));
|
||||
|
||||
if (readCourseCard)
|
||||
@ -1653,10 +1680,15 @@ OpFailStatus MeosSQL::storeRunner(const Row &row, oRunner &r,
|
||||
|
||||
if (!r.Class) {
|
||||
oClass oc(oe, row["Class"]);
|
||||
oc.setImplicitlyCreated();
|
||||
if (allowSubRead)
|
||||
success = min(success, syncRead(true, &oc, readClassClub));
|
||||
if (!oc.isRemoved()) {
|
||||
r.Class = oe->addClass(oc);
|
||||
addedFromDatabase(r.Class);
|
||||
}
|
||||
else if (readClassClub)
|
||||
}
|
||||
else if (readClassClub && allowSubRead)
|
||||
success = min(success, syncRead(false, r.Class, true));
|
||||
|
||||
if (r.tInTeam && r.tInTeam->Class!=r.Class)
|
||||
@ -1669,10 +1701,15 @@ OpFailStatus MeosSQL::storeRunner(const Row &row, oRunner &r,
|
||||
|
||||
if (!r.Club) {
|
||||
oClub oc(oe, row["Club"]);
|
||||
oc.setImplicitlyCreated();
|
||||
if (allowSubRead)
|
||||
success = min(success, syncRead(true, &oc));
|
||||
if (!oc.isRemoved()) {
|
||||
r.Club = oe->addClub(oc);
|
||||
addedFromDatabase(r.Club);
|
||||
}
|
||||
else if (readClassClub)
|
||||
}
|
||||
else if (readClassClub && allowSubRead)
|
||||
success = min(success, syncRead(false, r.Club));
|
||||
}
|
||||
else r.Club=0;
|
||||
@ -1684,12 +1721,18 @@ OpFailStatus MeosSQL::storeRunner(const Row &row, oRunner &r,
|
||||
|
||||
if (!r.Card){
|
||||
oCard oc(oe, row["Card"]);
|
||||
oe->Cards.push_back(oc);
|
||||
r.Card = &oe->Cards.back();
|
||||
oc.setImplicitlyCreated();
|
||||
if (allowSubRead)
|
||||
success = min(success, syncRead(true, &oc));
|
||||
if (!oc.isRemoved()) {
|
||||
r.Card = oe->addCard(oc);
|
||||
r.Card->changed = false;
|
||||
success = min(success, syncRead(true, r.Card));
|
||||
}
|
||||
else if (readCourseCard)
|
||||
else {
|
||||
addedFromDatabase(r.Card);
|
||||
}
|
||||
}
|
||||
else if (readCourseCard && allowSubRead)
|
||||
success = min(success, syncRead(false, r.Card));
|
||||
}
|
||||
else r.Card=0;
|
||||
@ -1713,10 +1756,18 @@ OpFailStatus MeosSQL::storeRunner(const Row &row, oRunner &r,
|
||||
pRunner pr = oe->getRunner(rid, 0);
|
||||
if (pr==0) {
|
||||
oRunner or(oe, rid);
|
||||
or.setImplicitlyCreated();
|
||||
if (allowSubRead)
|
||||
success = min(success, syncRead(true, &or, false, readCourseCard));
|
||||
pr = oe->addRunner(or, false);
|
||||
if (!or.isRemoved()) {
|
||||
pr = oe->addRunner(or , false);
|
||||
addedFromDatabase(pr);
|
||||
}
|
||||
else
|
||||
else {
|
||||
r.multiRunnerId[i] = 0;
|
||||
}
|
||||
}
|
||||
else if (allowSubRead)
|
||||
success = min(success, syncRead(false, pr, false, readCourseCard));
|
||||
}
|
||||
}
|
||||
@ -1732,7 +1783,7 @@ OpFailStatus MeosSQL::storeRunner(const Row &row, oRunner &r,
|
||||
}
|
||||
|
||||
OpFailStatus MeosSQL::storeTeam(const Row &row, oTeam &t,
|
||||
bool readRecursive)
|
||||
bool readRecursive, bool allowSubRead)
|
||||
{
|
||||
oEvent *oe=t.oe;
|
||||
OpFailStatus success = opStatusOK;
|
||||
@ -1747,8 +1798,14 @@ OpFailStatus MeosSQL::storeTeam(const Row &row, oTeam &t,
|
||||
t.sName=fromUTF((string)row["Name"]);
|
||||
t.StartNo=row["StartNo"];
|
||||
t.tStartTime = t.startTime = row["StartTime"];
|
||||
t.FinishTime=row["FinishTime"];
|
||||
t.FinishTime = row["FinishTime"];
|
||||
t.tStatus = t.status = RunnerStatus(int(row["Status"]));
|
||||
|
||||
t.inputTime = row["InputTime"];
|
||||
t.inputPoints = row["InputPoints"];
|
||||
t.inputStatus = RunnerStatus(int(row["InputStatus"]));
|
||||
t.inputPlace = row["InputPlace"];
|
||||
|
||||
storeData(t.getDI(), row, oe->dataRevision);
|
||||
|
||||
if (oldSno != t.StartNo || oldBib != t.getBib())
|
||||
@ -1768,10 +1825,15 @@ OpFailStatus MeosSQL::storeTeam(const Row &row, oTeam &t,
|
||||
|
||||
if (!t.Class) {
|
||||
oClass oc(oe, classId);
|
||||
oc.setImplicitlyCreated();
|
||||
if (allowSubRead)
|
||||
success = min(success, syncRead(true, &oc, readRecursive));
|
||||
if (!oc.isRemoved()) {
|
||||
t.Class = oe->addClass(oc);
|
||||
addedFromDatabase(t.Class);
|
||||
}
|
||||
else if (readRecursive)
|
||||
}
|
||||
else if (readRecursive && allowSubRead)
|
||||
success = min(success, syncRead(false, t.Class, readRecursive));
|
||||
}
|
||||
else t.Class=0;
|
||||
@ -1782,10 +1844,15 @@ OpFailStatus MeosSQL::storeTeam(const Row &row, oTeam &t,
|
||||
|
||||
if (!t.Club) {
|
||||
oClub oc(oe, clubId);
|
||||
oc.setImplicitlyCreated();
|
||||
if (allowSubRead)
|
||||
success = min(success, syncRead(true, &oc));
|
||||
if (!oc.isRemoved()) {
|
||||
t.Club = oe->addClub(oc);
|
||||
addedFromDatabase(t.Club);
|
||||
}
|
||||
else if (readRecursive)
|
||||
}
|
||||
else if (readRecursive && allowSubRead)
|
||||
success = min(success, syncRead(false, t.Club));
|
||||
}
|
||||
else t.Club = 0;
|
||||
@ -1798,19 +1865,24 @@ OpFailStatus MeosSQL::storeTeam(const Row &row, oTeam &t,
|
||||
for (size_t k=0;k<rns.size(); k++) {
|
||||
if (rns[k]>0) {
|
||||
pRns[k] = oe->getRunner(rns[k], 0);
|
||||
|
||||
if (!pRns[k]) {
|
||||
oRunner or(oe, rns[k]);
|
||||
or.setImplicitlyCreated();
|
||||
if (allowSubRead)
|
||||
success = min(success, syncRead(true, &or, readRecursive, readRecursive));
|
||||
|
||||
if (or.sName.empty()) {
|
||||
or.sName = L"@AutoCorrection";
|
||||
oRunner::getRealName(or.sName, or.tRealName);
|
||||
}
|
||||
pRns[k] = oe->addRunner(or, false);
|
||||
|
||||
if (!or.isRemoved()) {
|
||||
pRns[k] = oe->addRunner(or , false);
|
||||
addedFromDatabase(pRns[k]);
|
||||
assert(pRns[k] && !pRns[k]->changed);
|
||||
}
|
||||
else if (readRecursive)
|
||||
}
|
||||
else if (readRecursive && allowSubRead)
|
||||
success = min(success, syncRead(false, pRns[k]));
|
||||
}
|
||||
}
|
||||
@ -1936,6 +2008,9 @@ OpFailStatus MeosSQL::syncRead(bool forceRead, oRunner *r)
|
||||
}
|
||||
|
||||
string MeosSQL::andWhereOld(oBase *ob) {
|
||||
if (ob->sqlUpdated.empty())
|
||||
return " AND Counter!=" + itos(ob->counter);
|
||||
else
|
||||
return " AND (Counter!=" + itos(ob->counter) + " OR Modified!='" + ob->sqlUpdated + "')";
|
||||
}
|
||||
|
||||
@ -1967,7 +2042,7 @@ OpFailStatus MeosSQL::syncRead(bool forceRead, oRunner *r, bool readClassClub, b
|
||||
if (r->changed)
|
||||
success=opStatusWarning;
|
||||
|
||||
success = min (success, storeRunner(row, *r, readCourseCard, readClassClub, true));
|
||||
success = min (success, storeRunner(row, *r, readCourseCard, readClassClub, true, true));
|
||||
|
||||
r->oe->dataRevision++;
|
||||
r->Modified.update();
|
||||
@ -2105,7 +2180,11 @@ OpFailStatus MeosSQL::syncUpdate(oTeam *t, bool forceWriteAll) {
|
||||
<< " Class=" << t->getClassId(false) << ", "
|
||||
<< " Club=" << t->getClubId() << ", "
|
||||
<< " StartNo=" << t->getStartNo() << ", "
|
||||
<< " Status=" << t->status
|
||||
<< " Status=" << t->status << ", "
|
||||
<< " InputTime=" << t->inputTime << ", "
|
||||
<< " InputStatus=" << t->inputStatus << ", "
|
||||
<< " InputPoints=" << t->inputPoints << ", "
|
||||
<< " InputPlace=" << t->inputPlace
|
||||
<< t->getDI().generateSQLSet(forceWriteAll);
|
||||
|
||||
//wstring str = L"write team " + t->sName + L"\n";
|
||||
@ -2147,7 +2226,7 @@ OpFailStatus MeosSQL::syncRead(bool forceRead, oTeam *t, bool readRecursive)
|
||||
if (t->changed)
|
||||
success=opStatusWarning;
|
||||
|
||||
storeTeam(row, *t, readRecursive);
|
||||
storeTeam(row, *t, readRecursive, true);
|
||||
t->oe->dataRevision++;
|
||||
t->Modified.update();
|
||||
t->changed = false;
|
||||
@ -2236,7 +2315,7 @@ OpFailStatus MeosSQL::syncRead(bool forceRead, oClass *c, bool readCourses)
|
||||
if (c->changed)
|
||||
success=opStatusWarning;
|
||||
|
||||
storeClass(row, *c, readCourses);
|
||||
storeClass(row, *c, readCourses, true);
|
||||
c->oe->dataRevision++;
|
||||
c->Modified.update();
|
||||
c->changed = false;
|
||||
@ -2296,8 +2375,10 @@ OpFailStatus MeosSQL::syncReadClassCourses(oClass *c, const set<int> &courses,
|
||||
pCourse pc = oe->getCourse(id);
|
||||
if (!pc) {
|
||||
oCourse oc(oe, id);
|
||||
oc.setImplicitlyCreated();
|
||||
success = min(success, syncReadCourse(true, &oc, controlIds));
|
||||
oe->addCourse(oc);
|
||||
if (!oc.isRemoved())
|
||||
addedFromDatabase(oe->addCourse(oc));
|
||||
}
|
||||
else if (pc->changed || isOld(counter, modified, pc)) {
|
||||
success = min(success, syncReadCourse(false, pc, controlIds));
|
||||
@ -2576,7 +2657,7 @@ OpFailStatus MeosSQL::syncReadCourse(bool forceRead, oCourse *c, set<int> &readC
|
||||
if (c->changed)
|
||||
success = opStatusWarning;
|
||||
|
||||
storeCourse(row, *c, readControls);
|
||||
storeCourse(row, *c, readControls, true);
|
||||
c->oe->dataRevision++;
|
||||
c->Modified.update();
|
||||
c->changed=false;
|
||||
@ -2771,6 +2852,12 @@ OpFailStatus MeosSQL::syncUpdate(mysqlpp::Query &updateqry,
|
||||
Result res=query.store();
|
||||
if (res && res.num_rows()==0)
|
||||
setId = true;
|
||||
else if (ob->isImplicitlyCreated()) {
|
||||
return opStatusWarning;//XXX Should we read this object?
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(!ob->isImplicitlyCreated());
|
||||
}
|
||||
|
||||
query.reset();
|
||||
@ -3729,3 +3816,97 @@ int MeosSQL::getModifiedMask(oEvent &oe) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MeosSQL::addedFromDatabase(oBase *object) {
|
||||
assert(object);
|
||||
if (object && !object->existInDB()) {
|
||||
missingObjects.push_back(object);
|
||||
}
|
||||
}
|
||||
|
||||
void MeosSQL::processMissingObjects() {
|
||||
if (!missingObjects.empty()) {
|
||||
auto cpyMissing = missingObjects;
|
||||
missingObjects.clear();
|
||||
for (oBase *obj : cpyMissing) {
|
||||
obj->changed = true;
|
||||
syncRead(true, obj);
|
||||
obj->changed = false;
|
||||
assert(obj->existInDB());
|
||||
{
|
||||
oRunner *r = dynamic_cast<oRunner *>(obj);
|
||||
if (r && r->getName().empty()) {
|
||||
r->setName(L"@AutoCorrection", false);
|
||||
syncUpdate(r, false);
|
||||
}
|
||||
}
|
||||
{
|
||||
oTeam *t = dynamic_cast<oTeam *>(obj);
|
||||
if (t && t->getName().empty()) {
|
||||
t->setName(L"@AutoCorrection", false);
|
||||
syncUpdate(t, false);
|
||||
}
|
||||
}
|
||||
{
|
||||
oClass *cls = dynamic_cast<oClass *>(obj);
|
||||
if (cls && cls->getName().empty()) {
|
||||
cls->setName(L"@AutoCorrection");
|
||||
syncUpdate(cls, false);
|
||||
}
|
||||
}
|
||||
{
|
||||
oCourse *crs = dynamic_cast<oCourse *>(obj);
|
||||
if (crs && crs->getName().empty()) {
|
||||
crs->setName(L"@AutoCorrection");
|
||||
syncUpdate(crs, false);
|
||||
}
|
||||
}
|
||||
{
|
||||
oClub *clb = dynamic_cast<oClub *>(obj);
|
||||
if (clb && clb->getName().empty()) {
|
||||
clb->setName(L"@AutoCorrection");
|
||||
syncUpdate(clb, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
missingObjects.clear();
|
||||
}
|
||||
|
||||
OpFailStatus MeosSQL::syncRead(bool forceRead, oBase *obj) {
|
||||
OpFailStatus ret = OpFailStatus::opStatusFail;
|
||||
|
||||
if (typeid(*obj) == typeid(oRunner)) {
|
||||
ret = syncRead(forceRead, (oRunner *)obj);
|
||||
}
|
||||
else if (typeid(*obj) == typeid(oClass)) {
|
||||
ret = syncRead(forceRead, (oClass *)obj);
|
||||
}
|
||||
else if (typeid(*obj) == typeid(oCourse)) {
|
||||
ret = syncRead(forceRead, (oCourse *)obj);
|
||||
}
|
||||
else if (typeid(*obj) == typeid(oControl)) {
|
||||
ret = syncRead(forceRead, (oControl *)obj);
|
||||
}
|
||||
else if (typeid(*obj) == typeid(oClub)) {
|
||||
ret = syncRead(forceRead, (oClub *)obj);
|
||||
}
|
||||
else if (typeid(*obj) == typeid(oCard)) {
|
||||
ret = syncRead(forceRead, (oCard *)obj);
|
||||
}
|
||||
else if (typeid(*obj) == typeid(oFreePunch)) {
|
||||
ret = syncRead(forceRead, (oFreePunch *)obj, true);
|
||||
}
|
||||
else if (typeid(*obj) == typeid(oTeam)) {
|
||||
ret = syncRead(forceRead, (oTeam *)obj);
|
||||
}
|
||||
else if (typeid(*obj) == typeid(oEvent)) {
|
||||
ret = SyncRead((oEvent *)obj);
|
||||
}
|
||||
else
|
||||
throw std::exception("Database error");
|
||||
|
||||
processMissingObjects();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -58,6 +58,8 @@ protected:
|
||||
string CmpDataBase;
|
||||
void alert(const string &s);
|
||||
|
||||
vector<oBase *> missingObjects;
|
||||
|
||||
string errorMessage;
|
||||
|
||||
string serverName;
|
||||
@ -94,16 +96,19 @@ protected:
|
||||
void storePunch(const mysqlpp::Row &row, oFreePunch &p, bool rehash);
|
||||
|
||||
OpFailStatus storeTeam(const mysqlpp::Row &row, oTeam &t,
|
||||
bool readRecursive);
|
||||
bool readRecursive, bool allowSubRead);
|
||||
|
||||
OpFailStatus storeRunner(const mysqlpp::Row &row, oRunner &r,
|
||||
bool readCourseCard,
|
||||
bool readClassClub,
|
||||
bool readRunners);
|
||||
bool readRunners,
|
||||
bool allowSubRead);
|
||||
OpFailStatus storeCourse(const mysqlpp::Row &row, oCourse &c,
|
||||
set<int> &readControls);
|
||||
set<int> &readControls,
|
||||
bool allowSubRead);
|
||||
OpFailStatus storeClass(const mysqlpp::Row &row, oClass &c,
|
||||
bool readCourses);
|
||||
bool readCourses,
|
||||
bool allowSubRead);
|
||||
|
||||
void getColumns(const string &table, set<string> &output);
|
||||
|
||||
@ -120,9 +125,13 @@ protected:
|
||||
mysqlpp::ResNSel updateCounter(const char *oTable, int id, mysqlpp::Query *updateqry);
|
||||
string selectUpdated(const char *oTable, const string &updated, int counter);
|
||||
|
||||
void addedFromDatabase(oBase *object);
|
||||
|
||||
|
||||
public:
|
||||
bool dropDatabase(oEvent *oe);
|
||||
bool checkConnection(oEvent *oe);
|
||||
void processMissingObjects();
|
||||
|
||||
bool repairTables(const string &db, vector<string> &output);
|
||||
|
||||
@ -179,6 +188,10 @@ public:
|
||||
OpFailStatus syncUpdate(oTeam *t, bool forceWriteAll);
|
||||
OpFailStatus syncRead(bool forceRead, oTeam *t);
|
||||
|
||||
/** General interface. TypeId lookup */
|
||||
OpFailStatus syncRead(bool forceRead, oBase *c);
|
||||
|
||||
|
||||
int getModifiedMask(oEvent &oe);
|
||||
|
||||
MeosSQL(void);
|
||||
|
||||
@ -74,25 +74,36 @@ bool MEOSDB_API msSynchronizeList(oEvent *oe, oListId lid)
|
||||
nSynchList++;
|
||||
if (nSynchList % 100 == 99)
|
||||
OutputDebugString(L"Synchronized 100 lists\n");
|
||||
bool ret = false;
|
||||
switch (lid) {
|
||||
case oListId::oLRunnerId:
|
||||
ret = msql.syncListRunner(oe);
|
||||
break;
|
||||
case oListId::oLClassId:
|
||||
ret = msql.syncListClass(oe);
|
||||
break;
|
||||
case oListId::oLCourseId:
|
||||
ret = msql.syncListCourse(oe);
|
||||
break;
|
||||
case oListId::oLControlId:
|
||||
ret = msql.syncListControl(oe);
|
||||
break;
|
||||
case oListId::oLClubId:
|
||||
ret = msql.syncListClub(oe);
|
||||
break;
|
||||
case oListId::oLCardId:
|
||||
ret = msql.syncListCard(oe);
|
||||
break;
|
||||
case oListId::oLPunchId:
|
||||
ret = msql.syncListPunch(oe);
|
||||
break;
|
||||
case oListId::oLTeamId:
|
||||
ret = msql.syncListTeam(oe);
|
||||
break;
|
||||
}
|
||||
|
||||
if (lid == oListId::oLRunnerId)
|
||||
return msql.syncListRunner(oe);
|
||||
else if (lid == oListId::oLClassId)
|
||||
return msql.syncListClass(oe);
|
||||
else if (lid == oListId::oLCourseId)
|
||||
return msql.syncListCourse(oe);
|
||||
else if (lid == oListId::oLControlId)
|
||||
return msql.syncListControl(oe);
|
||||
else if (lid == oListId::oLClubId)
|
||||
return msql.syncListClub(oe);
|
||||
else if (lid == oListId::oLCardId)
|
||||
return msql.syncListCard(oe);
|
||||
else if (lid == oListId::oLPunchId)
|
||||
return msql.syncListPunch(oe);
|
||||
else if (lid == oListId::oLTeamId)
|
||||
return msql.syncListTeam(oe);
|
||||
|
||||
return false;
|
||||
msql.processMissingObjects();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MEOSDB_API msSynchronizeUpdate(oBase *obj)
|
||||
@ -134,34 +145,7 @@ int MEOSDB_API msSynchronizeRead(oBase *obj)
|
||||
if (nSynchEnt % 100 == 99)
|
||||
OutputDebugString(L"Synchronized 100 entities\n");
|
||||
|
||||
if (typeid(*obj)==typeid(oRunner)){
|
||||
return msql.syncRead(false, (oRunner *) obj );
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oClass)){
|
||||
return msql.syncRead(false, (oClass *) obj);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oCourse)){
|
||||
return msql.syncRead(false, (oCourse *) obj);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oControl)){
|
||||
return msql.syncRead(false, (oControl *) obj);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oClub)){
|
||||
return msql.syncRead(false, (oClub *) obj);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oCard)){
|
||||
return msql.syncRead(false, (oCard *) obj);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oFreePunch)){
|
||||
return msql.syncRead(false, (oFreePunch *) obj, true);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oTeam)){
|
||||
return msql.syncRead(false, (oTeam *) obj);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oEvent)){
|
||||
return msql.SyncRead((oEvent *) obj);
|
||||
}
|
||||
return 0;
|
||||
return msql.syncRead(false, obj);
|
||||
}
|
||||
|
||||
// Removes (marks it as removed) an entry from the database.
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//V35: abcdef
|
||||
//V36: abcdef
|
||||
int getMeosBuild() {
|
||||
string revision("$Rev: 912 $");
|
||||
string revision("$Rev: 915 $");
|
||||
return 174 + atoi(revision.substr(5, string::npos).c_str());
|
||||
}
|
||||
|
||||
@ -42,12 +42,12 @@ int getMeosBuild() {
|
||||
//V33: abcdefghij
|
||||
//V34: abcdfge
|
||||
wstring getMeosDate() {
|
||||
wstring date(L"$Date: 2019-06-16 10:37:59 +0200 (sö, 16 jun 2019) $");
|
||||
wstring date(L"$Date: 2019-07-30 07:05:51 +0200 (ti, 30 jul 2019) $");
|
||||
return date.substr(7,10);
|
||||
}
|
||||
|
||||
wstring getBuildType() {
|
||||
return L"Update 1"; // No parantheses (...)
|
||||
return L"Update 2"; // No parantheses (...)
|
||||
}
|
||||
|
||||
wstring getMajorVersion() {
|
||||
@ -60,7 +60,7 @@ wstring getMeosFullVersion() {
|
||||
if (getBuildType().empty())
|
||||
swprintf_s(bf, L"Version X#%s.%d, %s", maj.c_str(), getMeosBuild(), getMeosDate().c_str());
|
||||
else
|
||||
swprintf_s(bf, L"Version X#%s.%d, %s %s", maj.c_str(), getMeosBuild(), getBuildType().c_str(), getMeosDate().c_str());
|
||||
swprintf_s(bf, L"Version X#%s.%d, %s, %s", maj.c_str(), getMeosBuild(), getBuildType().c_str(), getMeosDate().c_str());
|
||||
return bf;
|
||||
}
|
||||
|
||||
@ -133,5 +133,8 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
||||
supp.emplace_back(L"Kexholm SK");
|
||||
supp.emplace_back(L"Utby IK");
|
||||
supp.emplace_back(L"JWOC 2019");
|
||||
developSupp.emplace_back(L"OK Nackhe");
|
||||
supp.emplace_back(L"OK Rodhen");
|
||||
|
||||
reverse(supp.begin(), supp.end());
|
||||
}
|
||||
|
||||
18
code/oBase.h
18
code/oBase.h
@ -101,17 +101,20 @@ protected:
|
||||
TimeStamp Modified;
|
||||
string sqlUpdated; //SQL TIMESTAMP
|
||||
int counter;
|
||||
oEvent *oe;
|
||||
bool Removed;
|
||||
|
||||
// True if the object is incorrect and needs correction
|
||||
// An example is if id changed as we wrote. Then owner
|
||||
// needs to be updated.
|
||||
bool correctionNeeded;
|
||||
bool correctionNeeded = false;
|
||||
|
||||
oEvent *oe;
|
||||
bool Removed;
|
||||
private:
|
||||
|
||||
//Used for selections, etc.
|
||||
int _objectmarker;
|
||||
bool implicitlyAdded = false;
|
||||
bool addedToEvent = false;
|
||||
|
||||
protected:
|
||||
|
||||
/// Mark the object as changed (on client) and that it needs synchronize to server
|
||||
virtual void updateChanged();
|
||||
@ -165,6 +168,11 @@ public:
|
||||
|
||||
bool existInDB() const { return !sqlUpdated.empty(); }
|
||||
|
||||
void setImplicitlyCreated() { implicitlyAdded = true; }
|
||||
bool isImplicitlyCreated() const { return implicitlyAdded; }
|
||||
bool isAddedToEvent() const { return addedToEvent; }
|
||||
void addToEvent() { addedToEvent = true; }
|
||||
|
||||
oDataInterface getDI();
|
||||
|
||||
oDataConstInterface getDCI() const;
|
||||
|
||||
@ -487,7 +487,7 @@ bool oCard::setPunchTime(const pPunch punch, const wstring &time)
|
||||
|
||||
|
||||
pCard oEvent::getCard(int Id) const
|
||||
{
|
||||
{ // Do allow removed cards
|
||||
if (Id < int(Cards.size() / 2)) {
|
||||
for (oCardList::const_iterator it = Cards.begin(); it != Cards.end(); ++it){
|
||||
if (it->Id==Id)
|
||||
@ -514,18 +514,17 @@ void oEvent::getCards(vector<pCard> &c) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pCard oEvent::addCard(const oCard &oc)
|
||||
{
|
||||
if (oc.Id<=0)
|
||||
return 0;
|
||||
|
||||
Cards.push_back(oc);
|
||||
Cards.back().addToEvent();
|
||||
|
||||
return &Cards.back();
|
||||
}
|
||||
|
||||
|
||||
pCard oEvent::getCardByNumber(int cno) const
|
||||
{
|
||||
oCardList::const_reverse_iterator it;
|
||||
|
||||
@ -716,6 +716,7 @@ pClass oEvent::addClass(const wstring &pname, int CourseId, int classId)
|
||||
c.Course=getCourse(CourseId);
|
||||
|
||||
Classes.push_back(c);
|
||||
Classes.back().addToEvent();
|
||||
Classes.back().synchronize();
|
||||
updateTabs();
|
||||
return &Classes.back();
|
||||
@ -732,8 +733,9 @@ pClass oEvent::addClass(oClass &c)
|
||||
}
|
||||
|
||||
Classes.push_back(c);
|
||||
Classes.back().addToEvent();
|
||||
|
||||
if (!Classes.back().existInDB()) {
|
||||
if (!Classes.back().existInDB() && !c.isImplicitlyCreated()) {
|
||||
Classes.back().changed = true;
|
||||
Classes.back().synchronize();
|
||||
}
|
||||
|
||||
@ -233,7 +233,7 @@ pClub oEvent::addClub(const wstring &pname, int createId) {
|
||||
oClub c(this, createId);
|
||||
c = *dbClub;
|
||||
c.Id = createId;
|
||||
Clubs.push_back(c);
|
||||
return addClub(c);
|
||||
}
|
||||
else {
|
||||
if (createId==0)
|
||||
@ -241,11 +241,8 @@ pClub oEvent::addClub(const wstring &pname, int createId) {
|
||||
|
||||
oClub c(this, createId);
|
||||
c.setName(pname);
|
||||
Clubs.push_back(c);
|
||||
return addClub(c);
|
||||
}
|
||||
Clubs.back().synchronize();
|
||||
clubIdIndex[Clubs.back().Id]=&Clubs.back();
|
||||
return &Clubs.back();
|
||||
}
|
||||
|
||||
pClub oEvent::addClub(const oClub &oc)
|
||||
@ -254,6 +251,8 @@ pClub oEvent::addClub(const oClub &oc)
|
||||
return clubIdIndex[oc.Id];
|
||||
|
||||
Clubs.push_back(oc);
|
||||
Clubs.back().addToEvent();
|
||||
|
||||
if (!oc.existInDB())
|
||||
Clubs.back().synchronize();
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
#include "Table.h"
|
||||
|
||||
//Version of database
|
||||
int oEvent::dbVersion = 82;
|
||||
int oEvent::dbVersion = 83;
|
||||
|
||||
class RelativeTimeFormatter : public oDataDefiner {
|
||||
string name;
|
||||
@ -610,7 +610,7 @@ pControl oEvent::addControl(int Id, int Number, const wstring &Name)
|
||||
|
||||
oControl c(this);
|
||||
c.set(Id, Number, Name);
|
||||
Controls.push_back(c);
|
||||
addControl(c);
|
||||
|
||||
oe->updateTabs();
|
||||
return &Controls.back();
|
||||
@ -636,6 +636,8 @@ pControl oEvent::addControl(const oControl &oc)
|
||||
qFreeControlId = max (qFreeControlId, Id);
|
||||
|
||||
Controls.push_back(oc);
|
||||
oe->Controls.back().addToEvent();
|
||||
|
||||
return &Controls.back();
|
||||
}
|
||||
|
||||
@ -1181,9 +1183,8 @@ bool oEvent::open(const xmlparser &xml) {
|
||||
oControl c(this);
|
||||
c.set(&*it);
|
||||
|
||||
if (c.Id>0 && knownControls.count(c.Id) == 0) {
|
||||
Controls.push_back(c);
|
||||
knownControls.insert(c.Id);
|
||||
if (c.Id>0 && knownControls.insert(c.Id).second) {
|
||||
addControl(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1227,6 +1228,7 @@ bool oEvent::open(const xmlparser &xml) {
|
||||
c.Set(&*it);
|
||||
if (c.Id>0 && knownClass.count(c.Id) == 0) {
|
||||
Classes.push_back(c);
|
||||
Classes.back().addToEvent();
|
||||
knownClass.insert(c.Id);
|
||||
}
|
||||
}
|
||||
@ -1249,7 +1251,7 @@ bool oEvent::open(const xmlparser &xml) {
|
||||
oClub c(this);
|
||||
c.set(*it);
|
||||
if (c.Id>0)
|
||||
addClub(c);//Clubs.push_back(c);
|
||||
addClub(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1341,7 +1343,7 @@ bool oEvent::open(const xmlparser &xml) {
|
||||
oCard c(this);
|
||||
c.Set(*it);
|
||||
assert(c.Id>=0);
|
||||
Cards.push_back(c);
|
||||
addCard(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1576,8 +1578,9 @@ pCourse oEvent::addCourse(const oCourse &oc)
|
||||
qFreeCourseId=max(qFreeCourseId, oc.getId());
|
||||
|
||||
pCourse pc = &Courses.back();
|
||||
pc->addToEvent();
|
||||
|
||||
if (!pc->existInDB()) {
|
||||
if (!pc->existInDB() && !pc->isImplicitlyCreated()) {
|
||||
pc->updateChanged();
|
||||
pc->synchronize();
|
||||
}
|
||||
@ -1609,7 +1612,7 @@ void oEvent::autoRemoveTeam(pRunner pr)
|
||||
if (pr->tInTeam) {
|
||||
// A team may have more than this runner -> do not remove
|
||||
bool canRemove = true;
|
||||
const vector<pRunner> &runners = pr->tInTeam->Runners;
|
||||
const auto &runners = pr->tInTeam->Runners;
|
||||
for (size_t k = 0; k<runners.size(); k++) {
|
||||
if (runners[k] && runners[k]->sName != pr->sName)
|
||||
canRemove = false;
|
||||
@ -1726,6 +1729,14 @@ pRunner oEvent::addRunner(const oRunner &r, bool updateStartNo) {
|
||||
|
||||
Runners.push_back(r);
|
||||
pRunner pr=&Runners.back();
|
||||
pr->addToEvent();
|
||||
|
||||
for (size_t i = 0; i < pr->multiRunner.size(); i++) {
|
||||
if (pr->multiRunner[i]) {
|
||||
assert(pr->multiRunner[i]->tParentRunner == nullptr || pr->multiRunner[i]->tParentRunner == &r);
|
||||
pr->multiRunner[i]->tParentRunner = pr;
|
||||
}
|
||||
}
|
||||
|
||||
//cardToRunnerHash.reset();
|
||||
if (cardToRunnerHash && r.getCardNo() != 0) {
|
||||
@ -1743,7 +1754,7 @@ pRunner oEvent::addRunner(const oRunner &r, bool updateStartNo) {
|
||||
pr->Card->tOwner = pr;
|
||||
|
||||
if (HasDBConnection) {
|
||||
if (!pr->existInDB())
|
||||
if (!pr->existInDB() && !pr->isImplicitlyCreated())
|
||||
pr->synchronize();
|
||||
}
|
||||
if (needUpdate)
|
||||
@ -2041,6 +2052,7 @@ pCard oEvent::allocateCard(pRunner owner)
|
||||
c.tOwner = owner;
|
||||
Cards.push_back(c);
|
||||
pCard newCard = &Cards.back();
|
||||
newCard->addToEvent();
|
||||
return newCard;
|
||||
}
|
||||
|
||||
@ -2152,7 +2164,7 @@ bool oEvent::sortTeams(SortOrder so, int leg, bool linearLeg) {
|
||||
// Count number of races with results
|
||||
int numResult = 0;
|
||||
int lastClassHeat = 0;
|
||||
for (pRunner r : it->Runners) {
|
||||
for (auto &r : it->Runners) {
|
||||
if (r && (r->prelStatusOK() ||
|
||||
(r->tStatus != StatusUnknown && r->tStatus != StatusDNS && r->tStatus != StatusCANCEL))) {
|
||||
|
||||
@ -2266,7 +2278,7 @@ bool oEvent::sortTeams(SortOrder so, int leg, bool linearLeg, vector<const oTeam
|
||||
// Count number of races with results
|
||||
int numResult = 0;
|
||||
int lastClassHeat = 0;
|
||||
for (pRunner r : it->Runners) {
|
||||
for (auto &r : it->Runners) {
|
||||
if (r && (r->prelStatusOK() ||
|
||||
(r->tStatus != StatusUnknown && r->tStatus != StatusDNS && r->tStatus != StatusCANCEL))) {
|
||||
|
||||
@ -2675,7 +2687,7 @@ void oEvent::removeRunner(const vector<int> &ids)
|
||||
// Reset team runner (this should not happen)
|
||||
if (it->tInTeam) {
|
||||
if (it->tInTeam->Runners[it->tLeg]==&*it)
|
||||
it->tInTeam->Runners[it->tLeg] = 0;
|
||||
it->tInTeam->Runners[it->tLeg] = nullptr;
|
||||
}
|
||||
|
||||
oRunnerList::iterator next = it;
|
||||
@ -4451,10 +4463,10 @@ void oEvent::addBib(int ClassId, int leg, const wstring &firstNumber) {
|
||||
|
||||
if (!firstNumber.empty()) {
|
||||
// Clear out start number temporarily, to not use it for sorting
|
||||
for (it=Teams.begin(); it != Teams.end(); ++it) {
|
||||
for (it = Teams.begin(); it != Teams.end(); ++it) {
|
||||
if (it->isRemoved())
|
||||
continue;
|
||||
if (ClassId==0 || it->getClassId(false)==ClassId) {
|
||||
if (ClassId == 0 || it->getClassId(false) == ClassId) {
|
||||
if (it->getClassRef(false) && it->getClassRef(false)->getBibMode() != BibFree) {
|
||||
for (size_t i = 0; i < it->Runners.size(); i++) {
|
||||
if (it->Runners[i]) {
|
||||
|
||||
@ -629,7 +629,7 @@ public:
|
||||
|
||||
enum PredefinedTypes {PNoSettings, PPool, PForking, PPoolDrawn, PHunting,
|
||||
PPatrol, PPatrolOptional, PPatrolOneSI, PRelay, PTwinRelay,
|
||||
PYouthRelay, PNoMulti};
|
||||
PYouthRelay, PTwoRacesNoOrder, PNoMulti};
|
||||
|
||||
void fillPredefinedCmp(gdioutput &gdi, const string &name) const;
|
||||
|
||||
|
||||
@ -651,7 +651,7 @@ bool oEvent::readSynchronize(const CompetitionInfo &ci)
|
||||
pRunner r = it->Runners[i];
|
||||
if (r != 0) {
|
||||
if (usedInTeam[r->Id]) {
|
||||
it->Runners[i] = 0; // Reset duplicate runners
|
||||
it->Runners[i] = nullptr; // Reset duplicate runners
|
||||
it->updateChanged();
|
||||
teamCorrected = true;
|
||||
if (r->tInTeam == &*it)
|
||||
|
||||
@ -442,7 +442,6 @@ bool oEvent::isInPunchHash(int card, int code, int time) {
|
||||
return readPunchHash.count(make_pair(p1, p2)) > 0;
|
||||
}
|
||||
|
||||
|
||||
pFreePunch oEvent::addFreePunch(int time, int type, int card, bool updateStartFinish) {
|
||||
if (time > 0 && isInPunchHash(card, type, time))
|
||||
return 0;
|
||||
@ -450,6 +449,7 @@ pFreePunch oEvent::addFreePunch(int time, int type, int card, bool updateStartFi
|
||||
|
||||
punches.push_back(ofp);
|
||||
pFreePunch fp=&punches.back();
|
||||
fp->addToEvent();
|
||||
oFreePunch::rehashPunches(*this, card, fp);
|
||||
insertIntoPunchHash(card, type, time);
|
||||
|
||||
@ -519,6 +519,7 @@ pFreePunch oEvent::addFreePunch(oFreePunch &fp) {
|
||||
insertIntoPunchHash(fp.CardNo, fp.Type, fp.Time);
|
||||
punches.push_back(fp);
|
||||
pFreePunch fpz=&punches.back();
|
||||
fpz->addToEvent();
|
||||
oFreePunch::rehashPunches(*this, fp.CardNo, fpz);
|
||||
|
||||
if (!fpz->existInDB() && HasDBConnection) {
|
||||
@ -618,43 +619,6 @@ void oEvent::getPunchesForRunner(int runnerId, bool doSort, vector<pFreePunch> &
|
||||
pRunner r = getRunner(runnerId, 0);
|
||||
if (r == 0)
|
||||
return;
|
||||
/*
|
||||
// Get times for when other runners used this card
|
||||
vector< pair<int, int> > times;
|
||||
int refCno = r->getCardNo();
|
||||
|
||||
for (auto it = Runners.begin(); it != Runners.end(); ++it) {
|
||||
if (it->Id == runnerId)
|
||||
continue;
|
||||
if (it->Card && it->getCardNo() == refCno) {
|
||||
pair<int, int> t = it->Card->getTimeRange();
|
||||
if (it->getStartTime() > 0)
|
||||
t.first = min(it->getStartTime(), t.first);
|
||||
|
||||
if (it->getFinishTime() > 0)
|
||||
t.second = max(it->getFinishTime(), t.second);
|
||||
|
||||
times.push_back(t);
|
||||
}
|
||||
}
|
||||
|
||||
for (oFreePunchList::const_iterator it = punches.begin(); it != punches.end(); ++it) {
|
||||
if (it->CardNo == refCno) {
|
||||
if (it->isRemoved() || it->isHiredCard())
|
||||
continue;
|
||||
|
||||
bool other = false;
|
||||
int t = it->Time;
|
||||
for (size_t k = 0; k<times.size(); k++) {
|
||||
if (t >= times[k].first && t <= times[k].second)
|
||||
other = true;
|
||||
}
|
||||
|
||||
if (!other)
|
||||
runnerPunches.push_back(pFreePunch(&*it));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//Lazy setup
|
||||
oFreePunch::rehashPunches(*oe, 0, 0);
|
||||
|
||||
@ -582,9 +582,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
||||
}
|
||||
}
|
||||
|
||||
// Clear markers
|
||||
for (r_it=Runners.begin(); r_it != Runners.end(); ++r_it)
|
||||
r_it->_objectmarker=0;
|
||||
map<int, int> objectMarkers;
|
||||
|
||||
//List all competitors not in a team.
|
||||
if (oe->hasTeam()) {
|
||||
@ -596,7 +594,9 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
||||
if (pc){
|
||||
for(unsigned i=0;i<pc->getNumStages();i++){
|
||||
pRunner r=t_it->getRunner(i);
|
||||
if (r) r->_objectmarker++;
|
||||
if (r) {
|
||||
++objectMarkers[r->getId()];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -605,7 +605,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
||||
gdi.addString("", 1, "Löpare som förekommer i mer än ett lag:");
|
||||
bool any = false;
|
||||
for (r_it=Runners.begin(); r_it != Runners.end(); ++r_it){
|
||||
if (r_it->_objectmarker>1) {
|
||||
if (objectMarkers[r_it->getId()] > 1) {
|
||||
wstring name = r_it->getClass(true) + L": " + r_it->getName();
|
||||
if (!r_it->getClub().empty())
|
||||
name += L" (" + r_it->getClub() + L")";
|
||||
@ -627,7 +627,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
||||
for (r_it=Runners.begin(); r_it != Runners.end(); ++r_it) {
|
||||
if (r_it->isRemoved())
|
||||
continue;
|
||||
if (r_it->_objectmarker==0){ //Only consider runners not in a team.
|
||||
if (objectMarkers.count(r_it->getId()) == 0){ //Only consider runners not in a team.
|
||||
gdi.addStringUT(y, x+tab[0], 0, r_it->getClass(true), tab[1]-tab[0]);
|
||||
wstring name = r_it->getName();
|
||||
if (!r_it->getClub().empty())
|
||||
|
||||
@ -191,21 +191,21 @@ oRunner::~oRunner()
|
||||
{
|
||||
if (tInTeam){
|
||||
for(unsigned i=0;i<tInTeam->Runners.size(); i++)
|
||||
if (tInTeam->Runners[i] && tInTeam->Runners[i]==this)
|
||||
tInTeam->Runners[i]=0;
|
||||
if (tInTeam->Runners[i] && tInTeam->Runners[i]->getId() == Id)
|
||||
tInTeam->Runners[i] = nullptr;
|
||||
|
||||
tInTeam=0;
|
||||
}
|
||||
|
||||
for (size_t k=0;k<multiRunner.size(); k++) {
|
||||
if (multiRunner[k])
|
||||
multiRunner[k]->tParentRunner=0;
|
||||
if (multiRunner[k] && multiRunner[k]->tParentRunner == this)
|
||||
multiRunner[k]->tParentRunner = nullptr;
|
||||
}
|
||||
|
||||
if (tParentRunner) {
|
||||
for (size_t k=0;k<tParentRunner->multiRunner.size(); k++)
|
||||
if (tParentRunner->multiRunner[k] == this)
|
||||
tParentRunner->multiRunner[k]=0;
|
||||
tParentRunner->multiRunner[k] = nullptr;
|
||||
}
|
||||
|
||||
delete tAdaptedCourse;
|
||||
@ -2200,6 +2200,7 @@ void oRunner::updateStartNo(int no) {
|
||||
|
||||
tInTeam->synchronize(true);
|
||||
for (pRunner r : tInTeam->Runners) {
|
||||
if (r)
|
||||
r->synchronize(true);
|
||||
}
|
||||
}
|
||||
@ -2302,12 +2303,14 @@ void oRunner::setCardNo(int cno, bool matchCard, bool updateFromDatabase)
|
||||
int oldNo = getCardNo();
|
||||
cardNumber = cno;
|
||||
|
||||
if (oe->cardToRunnerHash && cno != 0 && !isTemporaryObject) {
|
||||
if (oe->cardToRunnerHash && cno != 0 && isAddedToEvent() && !isTemporaryObject) {
|
||||
oe->cardToRunnerHash->emplace(cno, this);
|
||||
}
|
||||
|
||||
if (isAddedToEvent()) {
|
||||
oFreePunch::rehashPunches(*oe, oldNo, 0);
|
||||
oFreePunch::rehashPunches(*oe, cardNumber, 0);
|
||||
}
|
||||
|
||||
if (matchCard && !Card) {
|
||||
pCard c = oe->getCardByNumber(cno);
|
||||
@ -2862,21 +2865,23 @@ pRunner oEvent::getRunnerByBibOrStartNo(const wstring &bib, bool findWithoutCard
|
||||
if (t.getStartNo()==sno || stringMatch(t.getBib(), bib)) {
|
||||
if (!findWithoutCardNo) {
|
||||
for (int leg=0; leg<t.getNumRunners(); leg++) {
|
||||
if (t.Runners[leg] && t.Runners[leg]->getCardNo() > 0 && t.Runners[leg]->getStatus()==StatusUnknown)
|
||||
return t.Runners[leg];
|
||||
pRunner r = t.Runners[leg];
|
||||
if (r && r->getCardNo() > 0 && r->getStatus()==StatusUnknown)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int leg=0; leg<t.getNumRunners(); leg++) {
|
||||
if (t.Runners[leg] && t.Runners[leg]->getCardNo() == 0 && t.Runners[leg]->needNoCard() == false)
|
||||
return t.Runners[leg];
|
||||
pRunner r = t.Runners[leg];
|
||||
if (r && r->getCardNo() == 0 && r->needNoCard() == false)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pRunner oEvent::getRunnerByName(const wstring &pname, const wstring &pclub) const
|
||||
@ -3027,7 +3032,7 @@ void oRunner::createMultiRunner(bool createMaster, bool sync)
|
||||
{
|
||||
if (tDuplicateLeg)
|
||||
return; //Never allow chains.
|
||||
|
||||
bool allowCreate = true;
|
||||
if (multiRunnerId.size()>0) {
|
||||
multiRunner.resize(multiRunnerId.size() - 1);
|
||||
for (size_t k=0;k<multiRunner.size();k++) {
|
||||
@ -3044,8 +3049,10 @@ void oRunner::createMultiRunner(bool createMaster, bool sync)
|
||||
if (multiRunner[k]->Id != multiRunnerId[k])
|
||||
markForCorrection();
|
||||
}
|
||||
else if (multiRunnerId[k]>0)
|
||||
else if (multiRunnerId[k] > 0) {
|
||||
markForCorrection();
|
||||
allowCreate = false;
|
||||
}
|
||||
|
||||
assert(multiRunner[k]);
|
||||
}
|
||||
@ -3071,23 +3078,24 @@ void oRunner::createMultiRunner(bool createMaster, bool sync)
|
||||
toRemove.push_back(multiRunner[k]->getId());
|
||||
multiRunner[k]->tParentRunner = 0;
|
||||
if (multiRunner[k]->tInTeam && size_t(multiRunner[k]->tLeg)<multiRunner[k]->tInTeam->Runners.size()) {
|
||||
if (multiRunner[k]->tInTeam->Runners[multiRunner[k]->tLeg]==multiRunner[k])
|
||||
multiRunner[k]->tInTeam->Runners[multiRunner[k]->tLeg] = 0;
|
||||
if (multiRunner[k]->tInTeam->Runners[multiRunner[k]->tLeg] == multiRunner[k])
|
||||
multiRunner[k]->tInTeam->Runners[multiRunner[k]->tLeg] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
multiRunner.resize(ndup-1);
|
||||
for(int k=1;k<ndup; k++) {
|
||||
if (!multiRunner[k-1]) {
|
||||
for (int k = 1; k < ndup; k++) {
|
||||
if (!multiRunner[k - 1] && allowCreate) {
|
||||
update = true;
|
||||
multiRunner[k-1]=oe->addRunner(sName, getClubId(),
|
||||
multiRunner[k - 1] = oe->addRunner(sName, getClubId(),
|
||||
getClassId(false), 0, 0, false);
|
||||
multiRunner[k-1]->tDuplicateLeg=k;
|
||||
multiRunner[k-1]->tParentRunner=this;
|
||||
multiRunner[k - 1]->tDuplicateLeg = k;
|
||||
multiRunner[k - 1]->tParentRunner = this;
|
||||
multiRunner[k - 1]->cardNumber = 0;
|
||||
|
||||
if (sync)
|
||||
multiRunner[k-1]->synchronize();
|
||||
multiRunner[k - 1]->synchronize();
|
||||
}
|
||||
}
|
||||
if (update)
|
||||
@ -3111,6 +3119,13 @@ pRunner oRunner::getPredecessor() const
|
||||
}
|
||||
|
||||
bool oRunner::apply(bool sync, pRunner src, bool setTmpOnly) {
|
||||
for (size_t k = 0; k < multiRunner.size(); k++) {
|
||||
if (multiRunner[k] && multiRunner[k]->isRemoved()) {
|
||||
multiRunner[k]->tParentRunner = nullptr;
|
||||
multiRunner[k] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
createMultiRunner(false, sync);
|
||||
if (sync) {
|
||||
for (size_t k = 0; k < multiRunner.size(); k++) {
|
||||
|
||||
266
code/oTeam.cpp
266
code/oTeam.cpp
@ -159,7 +159,7 @@ string oTeam::getRunners() const
|
||||
|
||||
for(m=0;m<Runners.size();m++){
|
||||
if (Runners[m]){
|
||||
sprintf_s(bf, 16, "%d;", Runners[m]->Id);
|
||||
sprintf_s(bf, 16, "%d;", Runners[m]->getId());
|
||||
str+=bf;
|
||||
}
|
||||
else str+="0;";
|
||||
@ -185,40 +185,43 @@ void oTeam::decodeRunners(const string &rns, vector<int> &rid)
|
||||
}
|
||||
}
|
||||
|
||||
void oTeam::importRunners(const vector<int> &rns)
|
||||
{
|
||||
void oTeam::importRunners(const vector<int> &rns) {
|
||||
Runners.resize(rns.size());
|
||||
for (size_t n=0;n<rns.size(); n++) {
|
||||
if (rns[n]>0)
|
||||
if (rns[n] > 0)
|
||||
Runners[n] = oe->getRunner(rns[n], 0);
|
||||
else
|
||||
Runners[n] = 0;
|
||||
Runners[n] = nullptr;
|
||||
|
||||
pRunner r = Runners[n];
|
||||
if (r) {
|
||||
r->tInTeam = this;
|
||||
r->tLeg = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void oTeam::importRunners(const vector<pRunner> &rns)
|
||||
{
|
||||
// Unlink old runners
|
||||
for (size_t k = rns.size(); k<Runners.size(); k++) {
|
||||
if (Runners[k] && Runners[k]->tInTeam == this) {
|
||||
Runners[k]->tInTeam = 0;
|
||||
Runners[k]->tLeg = 0;
|
||||
for (size_t k = 0; k<Runners.size(); k++) {
|
||||
pRunner r = Runners[k];
|
||||
if (r && r->tInTeam == this) {
|
||||
r->tInTeam = 0;
|
||||
r->tLeg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Runners.resize(rns.size());
|
||||
for (size_t n=0;n<rns.size(); n++) {
|
||||
if (Runners[n] && rns[n] != Runners[n]) {
|
||||
if (Runners[n]->tInTeam == this) {
|
||||
Runners[n]->tInTeam = 0;
|
||||
Runners[n]->tLeg = 0;
|
||||
}
|
||||
}
|
||||
for (size_t n = 0; n < rns.size(); n++) {
|
||||
Runners[n] = rns[n];
|
||||
if (rns[n] && isAddedToEvent()) {
|
||||
rns[n]->tInTeam = this;
|
||||
rns[n]->tLeg = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void oEvent::removeTeam(int Id)
|
||||
{
|
||||
oTeamList::iterator it;
|
||||
@ -245,13 +248,14 @@ void oTeam::setRunner(unsigned i, pRunner r, bool sync)
|
||||
throw std::exception("Bad runner index");
|
||||
}
|
||||
|
||||
if (Runners[i]==r)
|
||||
if (Runners[i] == r)
|
||||
return;
|
||||
|
||||
int oldRaceId = 0;
|
||||
if (Runners[i]) {
|
||||
oldRaceId = Runners[i]->getDCI().getInt("RaceId");
|
||||
Runners[i]->getDI().setInt("RaceId", 0);
|
||||
pRunner tr = Runners[i];
|
||||
if (tr) {
|
||||
oldRaceId = tr->getDCI().getInt("RaceId");
|
||||
tr->getDI().setInt("RaceId", 0);
|
||||
}
|
||||
setRunnerInternal(i, r);
|
||||
|
||||
@ -285,7 +289,7 @@ void oTeam::setRunner(unsigned i, pRunner r, bool sync)
|
||||
|
||||
void oTeam::setRunnerInternal(int k, pRunner r)
|
||||
{
|
||||
if (r==Runners[k]) {
|
||||
if (r == Runners[k]) {
|
||||
if (r) {
|
||||
r->tInTeam = this;
|
||||
r->tLeg = k;
|
||||
@ -293,29 +297,30 @@ void oTeam::setRunnerInternal(int k, pRunner r)
|
||||
return;
|
||||
}
|
||||
|
||||
if (Runners[k]) {
|
||||
assert(Runners[k]->tInTeam == 0 || Runners[k]->tInTeam == this);
|
||||
Runners[k]->tInTeam = 0;
|
||||
Runners[k]->tLeg = 0;
|
||||
pRunner rOld = Runners[k];
|
||||
if (rOld) {
|
||||
assert(rOld->tInTeam == 0 || rOld->tInTeam == this);
|
||||
rOld->tInTeam = 0;
|
||||
rOld->tLeg = 0;
|
||||
}
|
||||
|
||||
// Reset old team
|
||||
if (r && r->tInTeam) {
|
||||
if (r->tInTeam->Runners[r->tLeg] != 0) {
|
||||
r->tInTeam->Runners[r->tLeg] = 0;
|
||||
if (r->tInTeam->Runners[r->tLeg]) {
|
||||
r->tInTeam->Runners[r->tLeg] = nullptr;
|
||||
r->tInTeam->updateChanged();
|
||||
if (r->tInTeam != this)
|
||||
r->tInTeam->synchronize(true);
|
||||
}
|
||||
}
|
||||
|
||||
Runners[k]=r;
|
||||
Runners[k] = r;
|
||||
|
||||
if (Runners[k]) {
|
||||
Runners[k]->tInTeam = this;
|
||||
Runners[k]->tLeg = k;
|
||||
if (Class && (Runners[k]->Class==nullptr || Class->getLegType(k) != LTGroup))
|
||||
Runners[k]->setClassId(getClassId(false), false);
|
||||
if (r) {
|
||||
r->tInTeam = this;
|
||||
r->tLeg = k;
|
||||
if (Class && (r->Class==nullptr || Class->getLegType(k) != LTGroup))
|
||||
r->setClassId(getClassId(false), false);
|
||||
}
|
||||
updateChanged();
|
||||
}
|
||||
@ -764,11 +769,9 @@ bool oTeam::compareSNO(const oTeam &a, const oTeam &b) {
|
||||
b.sName.c_str(), b.sName.length()) == CSTR_LESS_THAN;
|
||||
}
|
||||
|
||||
|
||||
bool oTeam::isRunnerUsed(int Id) const
|
||||
{
|
||||
bool oTeam::isRunnerUsed(int rId) const {
|
||||
for(unsigned i=0;i<Runners.size(); i++) {
|
||||
if (Runners[i] && Runners[i]->Id==Id)
|
||||
if (Runners[i] && Runners[i]->getId() == rId)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -830,13 +833,14 @@ void oTeam::quickApply() {
|
||||
|
||||
if (Class && Runners.size()!=size_t(Class->getNumStages())) {
|
||||
for (size_t k = Class->getNumStages(); k < Runners.size(); k++) {
|
||||
if (Runners[k] && Runners[k]->tInTeam) {
|
||||
Runners[k]->tInTeam = 0;
|
||||
Runners[k]->tLeg = 0;
|
||||
Runners[k]->tLegEquClass = 0;
|
||||
if (Runners[k]->Class == Class)
|
||||
Runners[k]->Class = 0;
|
||||
Runners[k]->updateChanged();
|
||||
pRunner tr = Runners[k];
|
||||
if (tr && tr->tInTeam) {
|
||||
tr->tInTeam = 0;
|
||||
tr->tLeg = 0;
|
||||
tr->tLegEquClass = 0;
|
||||
if (tr->Class == Class)
|
||||
tr->Class = 0;
|
||||
tr->updateChanged();
|
||||
}
|
||||
}
|
||||
Runners.resize(Class->getNumStages());
|
||||
@ -844,8 +848,16 @@ void oTeam::quickApply() {
|
||||
|
||||
for (size_t i = 0; i < Runners.size(); i++) {
|
||||
if (Runners[i]) {
|
||||
if (Runners[i]->tInTeam && Runners[i]->tInTeam!=this) {
|
||||
Runners[i]->tInTeam->correctRemove(Runners[i]);
|
||||
if (Runners[i]->isRemoved()) {
|
||||
// Could happen for database not in sync / invalid manual modification
|
||||
Runners[i]->tInTeam = nullptr;
|
||||
Runners[i]->tLeg = 0;
|
||||
Runners[i] = nullptr;
|
||||
}
|
||||
|
||||
auto tit = Runners[i]->tInTeam;
|
||||
if (tit && tit!=this) {
|
||||
tit->correctRemove(Runners[i]);
|
||||
}
|
||||
Runners[i]->tInTeam=this;
|
||||
Runners[i]->tLeg=i;
|
||||
@ -853,8 +865,6 @@ void oTeam::quickApply() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
if (unsigned(status) >= 100)
|
||||
status = StatusUnknown; // Enforce correct status
|
||||
@ -866,13 +876,14 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
|
||||
if (Class && Runners.size()!=size_t(Class->getNumStages())) {
|
||||
for (size_t k = Class->getNumStages(); k < Runners.size(); k++) {
|
||||
if (Runners[k] && Runners[k]->tInTeam) {
|
||||
Runners[k]->tInTeam = 0;
|
||||
Runners[k]->tLeg = 0;
|
||||
Runners[k]->tLegEquClass = 0;
|
||||
if (Runners[k]->Class == Class)
|
||||
Runners[k]->Class = 0;
|
||||
Runners[k]->updateChanged();
|
||||
auto tr = Runners[k];
|
||||
if (tr && tr->tInTeam) {
|
||||
tr->tInTeam = nullptr;
|
||||
tr->tLeg = 0;
|
||||
tr->tLegEquClass = 0;
|
||||
if (tr->Class == Class)
|
||||
tr->Class = 0;
|
||||
tr->updateChanged();
|
||||
}
|
||||
}
|
||||
Runners.resize(Class->getNumStages());
|
||||
@ -881,7 +892,15 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
BibMode bibMode = (BibMode)-1;
|
||||
tNumRestarts = 0;
|
||||
vector<int> availableStartTimes;
|
||||
for (size_t i=0;i<Runners.size(); i++) {
|
||||
for (size_t i_c=0;i_c<Runners.size(); i_c++) {
|
||||
const size_t i = i_c;
|
||||
if (Runners[i] && Runners[i]->isRemoved()) {
|
||||
// Could happen for database not in sync / invalid manual modification
|
||||
Runners[i]->tInTeam = nullptr;
|
||||
Runners[i]->tLeg = 0;
|
||||
Runners[i] = nullptr;
|
||||
}
|
||||
|
||||
if (!sync && i>0 && source!=0 && Runners[i-1] == source)
|
||||
return true;
|
||||
if (!Runners[i] && Class) {
|
||||
@ -890,7 +909,7 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
if (lr<i && Runners[lr]) {
|
||||
Runners[lr]->createMultiRunner(false, sync);
|
||||
int dup=Class->getLegRunnerIndex(i);
|
||||
Runners[i]=Runners[lr]->getMultiRunner(dup);
|
||||
Runners[i] = Runners[lr]->getMultiRunner(dup);
|
||||
}
|
||||
}
|
||||
|
||||
@ -899,14 +918,15 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
if (lr == i && Runners[i]->tParentRunner) {
|
||||
pRunner parent = Runners[i]->tParentRunner;
|
||||
for (size_t kk = 0; kk<parent->multiRunner.size(); ++kk) {
|
||||
if (parent->multiRunner[kk] == Runners[i]) {
|
||||
if (Runners[i] == parent->multiRunner[kk]) {
|
||||
pRunner tr = Runners[i];
|
||||
parent->multiRunner.erase(parent->multiRunner.begin() + kk);
|
||||
Runners[i]->tParentRunner = 0;
|
||||
Runners[i]->tDuplicateLeg = 0;
|
||||
tr->tParentRunner = 0;
|
||||
tr->tDuplicateLeg = 0;
|
||||
parent->markForCorrection();
|
||||
parent->updateChanged();
|
||||
Runners[i]->markForCorrection();
|
||||
Runners[i]->updateChanged();
|
||||
tr->markForCorrection();
|
||||
tr->updateChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -918,65 +938,66 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
if (Runners[i]) {
|
||||
for (size_t k=0;k<i; k++)
|
||||
if (Runners[i] == Runners[k])
|
||||
Runners[i] = 0;
|
||||
Runners[i] = nullptr;
|
||||
}
|
||||
|
||||
if (Runners[i]) {
|
||||
pClass actualClass = Runners[i]->getClassRef(true);
|
||||
pRunner tr = Runners[i];
|
||||
pClass actualClass = tr->getClassRef(true);
|
||||
if (actualClass == nullptr)
|
||||
actualClass = Class;
|
||||
if (Runners[i]->tInTeam && Runners[i]->tInTeam!=this) {
|
||||
Runners[i]->tInTeam->correctRemove(Runners[i]);
|
||||
if (tr->tInTeam && tr->tInTeam!=this) {
|
||||
tr->tInTeam->correctRemove(tr);
|
||||
}
|
||||
//assert(Runners[i]->tInTeam==0 || Runners[i]->tInTeam==this);
|
||||
Runners[i]->tInTeam = this;
|
||||
Runners[i]->tLeg = i;
|
||||
tr->tInTeam = this;
|
||||
tr->tLeg = i;
|
||||
if (Class) {
|
||||
int unused;
|
||||
Class->splitLegNumberParallel(i, Runners[i]->tLegEquClass, unused);
|
||||
Class->splitLegNumberParallel(i, tr->tLegEquClass, unused);
|
||||
}
|
||||
else {
|
||||
Runners[i]->tLegEquClass = i;
|
||||
tr->tLegEquClass = i;
|
||||
}
|
||||
|
||||
if (actualClass == Class)
|
||||
Runners[i]->setStartNo(StartNo, setTmpOnly);
|
||||
if (!bib.empty() && Runners[i]->isChanged()) {
|
||||
tr->setStartNo(StartNo, setTmpOnly);
|
||||
if (!bib.empty() && tr->isChanged()) {
|
||||
if (bibMode == -1 && Class)
|
||||
bibMode = Class->getBibMode();
|
||||
if (bibMode == BibSame)
|
||||
Runners[i]->setBib(bib, 0, false, setTmpOnly);
|
||||
tr->setBib(bib, 0, false, setTmpOnly);
|
||||
else if (bibMode == BibAdd) {
|
||||
wchar_t pattern[32], bf[32];
|
||||
int ibib = oClass::extractBibPattern(bib, pattern) + i;
|
||||
swprintf_s(bf, pattern, ibib);
|
||||
Runners[i]->setBib(bf, 0, false, setTmpOnly);
|
||||
tr->setBib(bf, 0, false, setTmpOnly);
|
||||
}
|
||||
else if (bibMode == BibLeg) {
|
||||
wstring rbib = bib + L"-" + Class->getLegNumber(i);
|
||||
Runners[i]->setBib(rbib, 0, false, setTmpOnly);
|
||||
tr->setBib(rbib, 0, false, setTmpOnly);
|
||||
}
|
||||
}
|
||||
LegTypes legType = Class ? Class->getLegType(i) : LTIgnore;
|
||||
|
||||
if (Runners[i]->Class!=Class && legType != LTGroup) {
|
||||
Runners[i]->Class=Class;
|
||||
Runners[i]->updateChanged();
|
||||
if (tr->Class!=Class && legType != LTGroup) {
|
||||
tr->Class=Class;
|
||||
tr->updateChanged();
|
||||
}
|
||||
|
||||
Runners[i]->tNeedNoCard=false;
|
||||
tr->tNeedNoCard=false;
|
||||
if (Class) {
|
||||
pClass pc=Class;
|
||||
|
||||
//Ignored runners need no SI-card (used by SI assign function)
|
||||
if (legType == LTIgnore) {
|
||||
Runners[i]->tNeedNoCard=true;
|
||||
tr->tNeedNoCard=true;
|
||||
if (lastStatus != StatusUnknown) {
|
||||
Runners[i]->setStatus(max(Runners[i]->tStatus, lastStatus), false, setTmpOnly);
|
||||
tr->setStatus(max(tr->tStatus, lastStatus), false, setTmpOnly);
|
||||
}
|
||||
}
|
||||
else
|
||||
lastStatus = Runners[i]->getStatus();
|
||||
lastStatus = tr->getStatus();
|
||||
|
||||
StartTypes st = actualClass == pc ? pc->getStartType(i) : actualClass->getStartType(0);
|
||||
LegTypes lt = legType;
|
||||
@ -987,27 +1008,27 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
}
|
||||
if (lt==LTIgnore || lt==LTExtra) {
|
||||
if (st != STDrawn)
|
||||
Runners[i]->setStartTime(lastStartTime, false, setTmpOnly);
|
||||
Runners[i]->tUseStartPunch = (st == STDrawn);
|
||||
tr->setStartTime(lastStartTime, false, setTmpOnly);
|
||||
tr->tUseStartPunch = (st == STDrawn);
|
||||
}
|
||||
else { //Calculate start time.
|
||||
switch (st) {
|
||||
case STDrawn: //Do nothing
|
||||
if (lt==LTParallel || lt==LTParallelOptional) {
|
||||
Runners[i]->setStartTime(lastStartTime, false, setTmpOnly);
|
||||
Runners[i]->tUseStartPunch=false;
|
||||
tr->setStartTime(lastStartTime, false, setTmpOnly);
|
||||
tr->tUseStartPunch=false;
|
||||
}
|
||||
else
|
||||
lastStartTime = Runners[i]->getStartTime();
|
||||
lastStartTime = tr->getStartTime();
|
||||
|
||||
break;
|
||||
|
||||
case STTime: {
|
||||
bool prs = false;
|
||||
if (Runners[i] && Runners[i]->Card && freeStart) {
|
||||
pCourse crs = Runners[i]->getCourse(false);
|
||||
if (tr && tr->Card && freeStart) {
|
||||
pCourse crs = tr->getCourse(false);
|
||||
int startType = crs ? crs->getStartPunchType() : oPunch::PunchStart;
|
||||
oPunch *pnc = Runners[i]->Card->getPunchByType(startType);
|
||||
oPunch *pnc = tr->Card->getPunchByType(startType);
|
||||
if (pnc && pnc->getAdjustedTime() > 0) {
|
||||
prs = true;
|
||||
lastStartTime = pnc->getAdjustedTime();
|
||||
@ -1020,8 +1041,8 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
else
|
||||
lastStartTime = actualClass->getStartData(0); // Qualification/final classes
|
||||
}
|
||||
Runners[i]->setStartTime(lastStartTime, false, setTmpOnly);
|
||||
Runners[i]->tUseStartPunch=false;
|
||||
tr->setStartTime(lastStartTime, false, setTmpOnly);
|
||||
tr->tUseStartPunch=false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1080,19 +1101,19 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
int rope=pc->getRopeTime(i);
|
||||
|
||||
if (((restart > 0 && rope > 0 && (ft == 0 || ft > rope)) || (ft == 0 && restart > 0)) &&
|
||||
!preventRestart() && !Runners[i]->preventRestart()) {
|
||||
!preventRestart() && !tr->preventRestart()) {
|
||||
ft = restart; //Runner in restart
|
||||
tNumRestarts++;
|
||||
}
|
||||
|
||||
if (ft > 0)
|
||||
Runners[i]->setStartTime(ft, false, setTmpOnly);
|
||||
Runners[i]->tUseStartPunch=false;
|
||||
tr->setStartTime(ft, false, setTmpOnly);
|
||||
tr->tUseStartPunch=false;
|
||||
lastStartTime=ft;
|
||||
}
|
||||
else {//The else below should only be run by mistake (for an incomplete team)
|
||||
Runners[i]->setStartTime(Class->getRestartTime(i), false, setTmpOnly);
|
||||
Runners[i]->tUseStartPunch=false;
|
||||
tr->setStartTime(Class->getRestartTime(i), false, setTmpOnly);
|
||||
tr->tUseStartPunch=false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1121,7 +1142,7 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
}
|
||||
|
||||
if (restart > 0 && rope > 0 && (lastStartTime > rope) &&
|
||||
!preventRestart() && !Runners[i]->preventRestart()) {
|
||||
!preventRestart() && !tr->preventRestart()) {
|
||||
lastStartTime = restart; //Runner in restart
|
||||
tNumRestarts++;
|
||||
}
|
||||
@ -1140,7 +1161,7 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
setStart = true;
|
||||
}
|
||||
|
||||
if (Runners[i]->getFinishTime()>0) {
|
||||
if (tr->getFinishTime()>0) {
|
||||
setStart = true;
|
||||
if (lastStartTime == 0)
|
||||
lastStartTime = pc->getRestartTime(i);
|
||||
@ -1151,15 +1172,15 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
else
|
||||
lastStartTime=0;
|
||||
|
||||
Runners[i]->tUseStartPunch=false;
|
||||
Runners[i]->setStartTime(lastStartTime, false, setTmpOnly);
|
||||
tr->tUseStartPunch=false;
|
||||
tr->setStartTime(lastStartTime, false, setTmpOnly);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t nextNonPar = i+1;
|
||||
while (nextNonPar < Runners.size() && pc->isOptional(nextNonPar) && Runners[nextNonPar] == 0)
|
||||
while (nextNonPar < Runners.size() && pc->isOptional(nextNonPar) && !Runners[nextNonPar])
|
||||
nextNonPar++;
|
||||
|
||||
int nextBaseLeg = nextNonPar;
|
||||
@ -1168,11 +1189,11 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
|
||||
// Extra finish time is used to split extra legs to parallel legs
|
||||
if (lt == LTExtra || pc->getLegType(i+1) == LTExtra) {
|
||||
if (Runners[i]->getFinishTime()>0) {
|
||||
if (tr->getFinishTime()>0) {
|
||||
if (extraFinishTime <= 0)
|
||||
extraFinishTime = Runners[i]->getFinishTime();
|
||||
extraFinishTime = tr->getFinishTime();
|
||||
else
|
||||
extraFinishTime = min(extraFinishTime, Runners[i]->getFinishTime());
|
||||
extraFinishTime = min(extraFinishTime, tr->getFinishTime());
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1181,7 +1202,7 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
//Add available start times for parallel
|
||||
if (nextNonPar < Runners.size()) {
|
||||
st=pc->getStartType(nextNonPar);
|
||||
int finishTime = Runners[i]->getFinishTime();
|
||||
int finishTime = tr->getFinishTime();
|
||||
if (lt == LTExtra)
|
||||
finishTime = extraFinishTime;
|
||||
|
||||
@ -1207,7 +1228,7 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
||||
}
|
||||
}
|
||||
if (sync)
|
||||
Runners[i]->synchronize(true);
|
||||
tr->synchronize(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1258,9 +1279,9 @@ void oTeam::evaluate(bool sync)
|
||||
|
||||
void oTeam::correctRemove(pRunner r) {
|
||||
for(unsigned i=0;i<Runners.size(); i++)
|
||||
if (r!=0 && Runners[i]==r) {
|
||||
Runners[i] = 0;
|
||||
r->tInTeam = 0;
|
||||
if (r != 0 && Runners[i] == r) {
|
||||
Runners[i] = nullptr;
|
||||
r->tInTeam = nullptr;
|
||||
r->tLeg = 0;
|
||||
r->tLegEquClass = 0;
|
||||
correctionNeeded = true;
|
||||
@ -1454,11 +1475,11 @@ void oTeam::fillSpeakerObject(int leg, int courseControlId, int previousControlC
|
||||
}
|
||||
}
|
||||
|
||||
map<int, int>::iterator mapit=Runners[leg]->priority.find(courseControlId);
|
||||
if (mapit!=Runners[leg]->priority.end())
|
||||
spk.priority=mapit->second;
|
||||
auto mapit = Runners[leg]->priority.find(courseControlId);
|
||||
if (mapit != Runners[leg]->priority.end())
|
||||
spk.priority = mapit->second;
|
||||
else
|
||||
spk.priority=0;
|
||||
spk.priority = 0;
|
||||
|
||||
spk.runningTimeLeg.preliminary = 0;
|
||||
for (int i = leg; i <= requestedLeg; i++) {
|
||||
@ -1502,10 +1523,9 @@ void oTeam::fillSpeakerObject(int leg, int courseControlId, int previousControlC
|
||||
spk.status = spk.finishStatus;
|
||||
}
|
||||
|
||||
int oTeam::getTimeAfter(int leg) const
|
||||
{
|
||||
if (leg==-1)
|
||||
leg=Runners.size()-1;
|
||||
int oTeam::getTimeAfter(int leg) const {
|
||||
if (leg == -1)
|
||||
leg = Runners.size() - 1;
|
||||
|
||||
if (!Class || Class->tLeaderTime.size()<=unsigned(leg))
|
||||
return -1;
|
||||
@ -1576,12 +1596,11 @@ oDataContainer &oTeam::getDataBuffers(pvoid &data, pvoid &olddata, pvectorstr &s
|
||||
return *oe->oTeamData;
|
||||
}
|
||||
|
||||
pRunner oTeam::getRunner(unsigned leg) const
|
||||
{
|
||||
pRunner oTeam::getRunner(unsigned leg) const {
|
||||
if (leg==-1)
|
||||
leg=Runners.size()-1;
|
||||
|
||||
return leg<Runners.size() ? Runners[leg]: 0;
|
||||
return leg<Runners.size() ? Runners[leg] : 0;
|
||||
}
|
||||
|
||||
int oTeam::getRogainingPoints(bool multidayTotal) const {
|
||||
@ -1927,7 +1946,6 @@ bool oTeam::inputData(int id, const wstring &input,
|
||||
setRunner(ix, r, true);
|
||||
output = r->getName();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2138,7 +2156,7 @@ bool oTeam::checkValdParSetup() {
|
||||
// Move to where a runner is needed
|
||||
Runners[k] = Runners[k+m];
|
||||
Runners[k]->tLeg = k;
|
||||
Runners[k+m] = 0;
|
||||
Runners[k+m] = nullptr;
|
||||
updateChanged();
|
||||
cor = true;
|
||||
k+=m;
|
||||
|
||||
@ -54,7 +54,7 @@ private:
|
||||
void propagateClub();
|
||||
|
||||
protected:
|
||||
//pRunner Runners[maxRunnersTeam];
|
||||
|
||||
vector<pRunner> Runners;
|
||||
void setRunnerInternal(int k, pRunner r);
|
||||
|
||||
|
||||
@ -160,15 +160,17 @@ pTeam oEvent::addTeam(const wstring &pname, int ClubId, int ClassId)
|
||||
|
||||
bibStartNoToRunnerTeam.clear();
|
||||
Teams.push_back(t);
|
||||
teamById[t.Id] = &Teams.back();
|
||||
pTeam pt = &Teams.back();
|
||||
pt->addToEvent();
|
||||
teamById[t.Id] = pt;
|
||||
|
||||
oe->updateTabs();
|
||||
|
||||
Teams.back().StartNo = ++nextFreeStartNo; // Need not be unique
|
||||
Teams.back().getEntryDate(false);// Store entry time
|
||||
Teams.back().apply(false, 0, false);
|
||||
Teams.back().updateChanged();
|
||||
return &Teams.back();
|
||||
pt->StartNo = ++nextFreeStartNo; // Need not be unique
|
||||
pt->getEntryDate(false);// Store entry time
|
||||
pt->apply(false, 0, false);
|
||||
pt->updateChanged();
|
||||
return pt;
|
||||
}
|
||||
|
||||
pTeam oEvent::addTeam(const oTeam &t, bool autoAssignStartNo) {
|
||||
@ -181,6 +183,15 @@ pTeam oEvent::addTeam(const oTeam &t, bool autoAssignStartNo) {
|
||||
Teams.push_back(t);
|
||||
|
||||
pTeam pt = &Teams.back();
|
||||
pt->addToEvent();
|
||||
|
||||
for (size_t i = 0; i < pt->Runners.size(); i++) {
|
||||
if (pt->Runners[i]) {
|
||||
assert(pt->Runners[i]->tInTeam == nullptr || pt->Runners[i]->tInTeam == &t);
|
||||
pt->Runners[i]->tInTeam = pt;
|
||||
}
|
||||
}
|
||||
|
||||
teamById[pt->Id] = pt;
|
||||
|
||||
if (pt->StartNo == 0 && autoAssignStartNo) {
|
||||
@ -306,10 +317,10 @@ bool oTeam::matchTeam(int number, const wchar_t *s_lc) const
|
||||
|
||||
void oEvent::fillPredefinedCmp(gdioutput &gdi, const string &name) const
|
||||
{
|
||||
bool hasPatrol = getMeOSFeatures().hasFeature(MeOSFeatures::Patrol);
|
||||
bool hasMulti = getMeOSFeatures().hasFeature(MeOSFeatures::MultipleRaces);
|
||||
bool hasRelay = getMeOSFeatures().hasFeature(MeOSFeatures::Relay);
|
||||
bool hasForked = getMeOSFeatures().hasFeature(MeOSFeatures::ForkedIndividual);
|
||||
bool hasPatrol = true;// getMeOSFeatures().hasFeature(MeOSFeatures::Patrol);
|
||||
bool hasMulti = true;//getMeOSFeatures().hasFeature(MeOSFeatures::MultipleRaces);
|
||||
bool hasRelay = true;//getMeOSFeatures().hasFeature(MeOSFeatures::Relay);
|
||||
bool hasForked = true;//getMeOSFeatures().hasFeature(MeOSFeatures::ForkedIndividual);
|
||||
|
||||
gdi.clearList(name);
|
||||
gdi.addItem(name, lang.tl("Endast en bana"), PNoMulti);
|
||||
@ -328,8 +339,10 @@ void oEvent::fillPredefinedCmp(gdioutput &gdi, const string &name) const
|
||||
}
|
||||
if (hasRelay)
|
||||
gdi.addItem(name, lang.tl("Stafett"), PRelay);
|
||||
if (hasMulti)
|
||||
if (hasMulti) {
|
||||
gdi.addItem(name, lang.tl("Tvåmannastafett"), PTwinRelay);
|
||||
gdi.addItem(name, lang.tl("Flera lopp i valfri ordning"), PTwoRacesNoOrder);
|
||||
}
|
||||
if (hasRelay)
|
||||
gdi.addItem(name, lang.tl("Extralöparstafett"), PYouthRelay);
|
||||
}
|
||||
@ -386,6 +399,11 @@ void oEvent::setupRelayInfo(PredefinedTypes type, bool &useNLeg, bool &useStart)
|
||||
useStart = true;
|
||||
break;
|
||||
|
||||
case PTwoRacesNoOrder:
|
||||
useStart = false;
|
||||
useNLeg = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::exception("Bad setup number");
|
||||
}
|
||||
@ -424,7 +442,8 @@ void oEvent::setupRelay(oClass &cls, PredefinedTypes type, int nleg, const wstri
|
||||
if (crs) {
|
||||
cls.addStageCourse(0, crsId, -1);
|
||||
}
|
||||
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::ForkedIndividual, true, *this);
|
||||
oe->synchronize(true);
|
||||
break;
|
||||
|
||||
case PPoolDrawn:
|
||||
@ -439,6 +458,9 @@ void oEvent::setupRelay(oClass &cls, PredefinedTypes type, int nleg, const wstri
|
||||
if (crs) {
|
||||
cls.addStageCourse(0, crsId, -1);
|
||||
}
|
||||
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::ForkedIndividual, true, *this);
|
||||
oe->synchronize(true);
|
||||
break;
|
||||
|
||||
case PPatrol:
|
||||
@ -460,6 +482,8 @@ void oEvent::setupRelay(oClass &cls, PredefinedTypes type, int nleg, const wstri
|
||||
cls.addStageCourse(1, crsId, -1);
|
||||
}
|
||||
cls.setCoursePool(false);
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::Patrol, true, *this);
|
||||
oe->synchronize(true);
|
||||
break;
|
||||
|
||||
case PPatrolOptional:
|
||||
@ -481,6 +505,8 @@ void oEvent::setupRelay(oClass &cls, PredefinedTypes type, int nleg, const wstri
|
||||
cls.addStageCourse(1, crsId, -1);
|
||||
}
|
||||
cls.setCoursePool(false);
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::Patrol, true, *this);
|
||||
oe->synchronize(true);
|
||||
break;
|
||||
|
||||
case PPatrolOneSI:
|
||||
@ -503,6 +529,8 @@ void oEvent::setupRelay(oClass &cls, PredefinedTypes type, int nleg, const wstri
|
||||
}
|
||||
|
||||
cls.setCoursePool(false);
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::Patrol, true, *this);
|
||||
oe->synchronize(true);
|
||||
break;
|
||||
|
||||
case PRelay:
|
||||
@ -521,6 +549,8 @@ void oEvent::setupRelay(oClass &cls, PredefinedTypes type, int nleg, const wstri
|
||||
cls.setRopeTime(k, L"-");
|
||||
}
|
||||
cls.setCoursePool(false);
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::Relay, true, *this);
|
||||
oe->synchronize(true);
|
||||
break;
|
||||
|
||||
case PTwinRelay:
|
||||
@ -543,6 +573,27 @@ void oEvent::setupRelay(oClass &cls, PredefinedTypes type, int nleg, const wstri
|
||||
}
|
||||
|
||||
cls.setCoursePool(false);
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::Relay, true, *this);
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::MultipleRaces, true, *this);
|
||||
oe->synchronize(true);
|
||||
oe->synchronize(true);
|
||||
break;
|
||||
|
||||
case PTwoRacesNoOrder:
|
||||
cls.setNumStages(nleg);
|
||||
|
||||
for (int k = 0; k<nleg; k++) {
|
||||
cls.setLegType(k, LTSum);
|
||||
cls.setStartType(k, STDrawn, false);
|
||||
cls.setStartData(k, L"-");
|
||||
cls.setRestartTime(k, L"-");
|
||||
cls.setRopeTime(k, L"-");
|
||||
if (k > 0)
|
||||
cls.setLegRunner(k, 0);
|
||||
}
|
||||
cls.setCoursePool(false);
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::MultipleRaces, true, *this);
|
||||
oe->synchronize(true);
|
||||
break;
|
||||
|
||||
case PYouthRelay:
|
||||
@ -577,6 +628,8 @@ void oEvent::setupRelay(oClass &cls, PredefinedTypes type, int nleg, const wstri
|
||||
}
|
||||
}
|
||||
cls.setCoursePool(false);
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::Relay, true, *this);
|
||||
oe->synchronize(true);
|
||||
break;
|
||||
|
||||
case PHunting: {
|
||||
@ -595,6 +648,8 @@ void oEvent::setupRelay(oClass &cls, PredefinedTypes type, int nleg, const wstri
|
||||
cls.setRopeTime(1, formatTimeHMS(t+1800));
|
||||
cls.setLegRunner(1, 0);
|
||||
cls.setCoursePool(false);
|
||||
getMeOSFeatures().useFeature(MeOSFeatures::Relay, true, *this);
|
||||
oe->synchronize(true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -653,7 +708,7 @@ bool oTeam::adjustMultiRunners(bool sync)
|
||||
if (!Class)
|
||||
return false;
|
||||
|
||||
for (size_t k = Class->getNumStages(); k<Runners.size(); k++) {
|
||||
for (size_t k = Class->getNumStages(); k < Runners.size(); k++) {
|
||||
setRunnerInternal(k, 0);
|
||||
}
|
||||
|
||||
@ -663,14 +718,14 @@ bool oTeam::adjustMultiRunners(bool sync)
|
||||
}
|
||||
|
||||
// Create multi runners.
|
||||
for (size_t i=0;i<Runners.size(); i++) {
|
||||
for (size_t i = 0; i < Runners.size(); i++) {
|
||||
if (!Runners[i] && Class) {
|
||||
unsigned lr = Class->getLegRunner(i);
|
||||
|
||||
if (lr<i && Runners[lr]) {
|
||||
if (lr < i && Runners[lr]) {
|
||||
Runners[lr]->createMultiRunner(true, sync);
|
||||
int dup=Class->getLegRunnerIndex(i);
|
||||
Runners[i]=Runners[lr]->getMultiRunner(dup);
|
||||
int dup = Class->getLegRunnerIndex(i);
|
||||
Runners[i] = Runners[lr]->getMultiRunner(dup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1248,6 +1248,7 @@ X (Y deltagare, grupp Z, W) = X (Y deltagare, grupp Z, W)
|
||||
X har startat = X har startat
|
||||
X kontroller = X kontroller
|
||||
X meter = X meter
|
||||
X m = X m
|
||||
X poäng fattas = X poäng fattas
|
||||
X rader kunde inte raderas = X rad(er) kunde inte raderas
|
||||
X senaste = X senaste
|
||||
@ -2440,3 +2441,6 @@ Kunde inte öppna databasen (X) = Kunde inte öppna databasen (X)
|
||||
Kunde inte ladda upp löpardatabasen (X) = Kunde inte ladda upp löpardatabasen (X)
|
||||
Runner check time = Checktid
|
||||
ClassNumEntries = Antal anmälda i klassen
|
||||
Flera lopp i valfri ordning = Flera lopp i valfri ordning
|
||||
Knockout sammanställning = Knockout sammanställning
|
||||
X anmälda = X anmälda
|
||||
|
||||
Loading…
Reference in New Issue
Block a user