MeOS version 3.7SD.1221
This commit is contained in:
parent
5e242c81c0
commit
035fec52ec
@ -368,7 +368,7 @@ protected:
|
|||||||
int getDISize() const {return 0;}
|
int getDISize() const {return 0;}
|
||||||
void changedObject() {}
|
void changedObject() {}
|
||||||
public:
|
public:
|
||||||
void merge(const oBase &input) final {}
|
void merge(const oBase &input, const oBase * base) final {}
|
||||||
|
|
||||||
int getIndex() const {return index;}
|
int getIndex() const {return index;}
|
||||||
void init(RunnerDB *db_, int index_) {db=db_, index=index_; Id = index;}
|
void init(RunnerDB *db_, int index_) {db=db_, index=index_; Id = index;}
|
||||||
|
|||||||
@ -3477,7 +3477,7 @@ bool TabClass::loadPage(gdioutput &gdi)
|
|||||||
if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::MultipleRaces))
|
if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::MultipleRaces))
|
||||||
func.push_back(ButtonData("QualificationFinal", "Kval/final-schema", false));
|
func.push_back(ButtonData("QualificationFinal", "Kval/final-schema", false));
|
||||||
|
|
||||||
if (showAdvanced)
|
if (showAdvanced || oe->getStartGroups(true).size() > 0)
|
||||||
func.push_back(ButtonData("StartGroups", "Startgrupper", true));
|
func.push_back(ButtonData("StartGroups", "Startgrupper", true));
|
||||||
|
|
||||||
RECT funRect;
|
RECT funRect;
|
||||||
|
|||||||
@ -166,6 +166,12 @@ bool TabCompetition::importFile(HWND hWnd, gdioutput &gdi)
|
|||||||
if (oe->open(fileName, true, false)) {
|
if (oe->open(fileName, true, false)) {
|
||||||
gdi.setWindowTitle(oe->getTitleName());
|
gdi.setWindowTitle(oe->getTitleName());
|
||||||
resetSaveTimer();
|
resetSaveTimer();
|
||||||
|
|
||||||
|
// Save base copy
|
||||||
|
wstring base = constructBase(L"base", L"");
|
||||||
|
wchar_t newBase[_MAX_PATH];
|
||||||
|
getUserFile(newBase, base.c_str());
|
||||||
|
oe->save(newBase);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -763,6 +769,13 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
|||||||
oe->getDirectSocket().startUDPSocketThread(gdi.getHWNDMain());
|
oe->getDirectSocket().startUDPSocketThread(gdi.getHWNDMain());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save base copy
|
||||||
|
wstring base = constructBase(L"base", L"");
|
||||||
|
wchar_t newBase[_MAX_PATH];
|
||||||
|
getUserFile(newBase, base.c_str());
|
||||||
|
if (!fileExist(newBase))
|
||||||
|
oe->save(newBase);
|
||||||
|
|
||||||
loadConnectionPage(gdi);
|
loadConnectionPage(gdi);
|
||||||
}
|
}
|
||||||
else if (bi.id == "MultiEvent") {
|
else if (bi.id == "MultiEvent") {
|
||||||
@ -4167,10 +4180,23 @@ void TabCompetition::checkReadyForResultExport(gdioutput &gdi, const set<int> &c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wstring TabCompetition::constructBase(const wstring &r, const wstring &mt) const {
|
||||||
|
wstring ret = oe->getNameId(0) + L"-";
|
||||||
|
if (!mt.empty())
|
||||||
|
ret += mt + L"-";
|
||||||
|
ret += r + L".meosdiff";
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
||||||
|
|
||||||
class MergeHandler : public GuiHandler {
|
class MergeHandler : public GuiHandler {
|
||||||
TabCompetition *tc;
|
TabCompetition *tc;
|
||||||
|
shared_ptr<oEvent> mergeEvent;
|
||||||
|
shared_ptr<oEvent> baseEvent;
|
||||||
|
wstring thisFile;
|
||||||
|
wstring baseFile;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MergeHandler(TabCompetition *tc) : tc(tc) {}
|
MergeHandler(TabCompetition *tc) : tc(tc) {}
|
||||||
@ -4180,19 +4206,29 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
|||||||
ButtonInfo bi = dynamic_cast<ButtonInfo &>(info);
|
ButtonInfo bi = dynamic_cast<ButtonInfo &>(info);
|
||||||
|
|
||||||
if (bi.id == "Cancel") {
|
if (bi.id == "Cancel") {
|
||||||
if (tc->mergeEvent)
|
if (mergeEvent)
|
||||||
tc->mergeEvent->clear();
|
mergeEvent->clear();
|
||||||
tc->loadPage(gdi);
|
tc->loadPage(gdi);
|
||||||
}
|
}
|
||||||
else if (bi.id == "Merge") {
|
else if (bi.id == "Merge") {
|
||||||
if (!tc->mergeEvent)
|
if (!mergeEvent)
|
||||||
return;
|
return;
|
||||||
int numAdd, numRemove, numUpdate;
|
int numAdd, numRemove, numUpdate;
|
||||||
|
bool allowRemove = true;
|
||||||
|
|
||||||
wstring anno = lang.tl(L"Kopia (X)#MRG " + wstring(getLocalTime()));
|
if (gdi.hasWidget("AllowRemove"))
|
||||||
tc->oe->duplicate(anno);
|
allowRemove = gdi.isChecked("AllowRemove");
|
||||||
|
|
||||||
tc->oe->merge(*tc->mergeEvent, numAdd, numRemove, numUpdate);
|
wstring anno = lang.tl(L"Kopia (X)#MRG " + getLocalTime());
|
||||||
|
tc->oe->duplicate(anno, true);
|
||||||
|
|
||||||
|
if (!thisFile.empty()) {
|
||||||
|
wchar_t newBase[_MAX_PATH];
|
||||||
|
getUserFile(newBase, thisFile.c_str());
|
||||||
|
mergeEvent->save(newBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
tc->oe->merge(*mergeEvent, baseEvent.get(), allowRemove, numAdd, numRemove, numUpdate);
|
||||||
|
|
||||||
|
|
||||||
gdi.clearPage(true);
|
gdi.clearPage(true);
|
||||||
@ -4207,7 +4243,7 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
|||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
gdi.addString("", 0, L"Skapade lokal säkerhetskopia (X) innan sammanslagning#" + anno);
|
gdi.addString("", 0, L"Skapade lokal säkerhetskopia (X) innan sammanslagning#" + anno);
|
||||||
|
|
||||||
tc->mergeEvent->clear();
|
mergeEvent->clear();
|
||||||
|
|
||||||
gdi.dropLine(3);
|
gdi.dropLine(3);
|
||||||
gdi.addButton("Cancel", "Återgå").setHandler(this);
|
gdi.addButton("Cancel", "Återgå").setHandler(this);
|
||||||
@ -4223,29 +4259,33 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
|||||||
gdi.enableInput("Read");
|
gdi.enableInput("Read");
|
||||||
}
|
}
|
||||||
else if (bi.id == "Read") {
|
else if (bi.id == "Read") {
|
||||||
tc->mergeEvent = make_shared<oEvent>(gdi);
|
mergeEvent = make_shared<oEvent>(gdi);
|
||||||
|
|
||||||
if (!tc->mergeEvent->open(tc->mergeFile, true, true))
|
if (!mergeEvent->open(tc->mergeFile, true, true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gdi.restore("merge", false);
|
gdi.restore("merge", false);
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
gdi.addStringUT(1, tc->mergeEvent->getName());
|
gdi.addStringUT(1, mergeEvent->getName());
|
||||||
|
|
||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
bool error = false;
|
bool error = false;
|
||||||
if (tc->mergeEvent->getNameId(0) == tc->oe->getNameId(0)) {
|
bool sameBase = false;
|
||||||
if (tc->mergeEvent->getMergeTag() == tc->oe->getMergeTag()) {
|
if (mergeEvent->getNameId(0) == tc->oe->getNameId(0)) {
|
||||||
|
if (mergeEvent->getMergeTag() == tc->oe->getMergeTag()) {
|
||||||
gdi.addString("", 1, "Fel: En tävling kan inte slås ihop med sig själv.").setColor(colorRed);
|
gdi.addString("", 1, "Fel: En tävling kan inte slås ihop med sig själv.").setColor(colorRed);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
sameBase = true;
|
||||||
gdi.addString("", 1, "Samma bastävling").setColor(colorDarkGreen);
|
gdi.addString("", 1, "Samma bastävling").setColor(colorDarkGreen);
|
||||||
wstring info = tc->oe->getMergeInfo(tc->mergeEvent->getMergeTag());
|
wstring info = tc->oe->getMergeInfo(mergeEvent->getMergeTag());
|
||||||
string mod = tc->mergeEvent->getLastModified();
|
string mod = mergeEvent->getLastModified();
|
||||||
|
|
||||||
|
|
||||||
if (info.empty()) {
|
if (info.empty()) {
|
||||||
gdi.addString("", 0, "Denna datakälla är aldrig tidigare infogad");
|
gdi.addString("", 0, "Denna datakälla är aldrig tidigare infogad");
|
||||||
|
baseFile = tc->constructBase(L"base", L"");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
string merged = gdi.narrow(info);
|
string merged = gdi.narrow(info);
|
||||||
@ -4258,6 +4298,7 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
|||||||
TimeStamp ts;
|
TimeStamp ts;
|
||||||
ts.setStamp(merged);
|
ts.setStamp(merged);
|
||||||
gdi.addString("", 0, "Tidigare infogad version: X#" + ts.getStampStringN());
|
gdi.addString("", 0, "Tidigare infogad version: X#" + ts.getStampStringN());
|
||||||
|
baseFile = tc->constructBase(info, mergeEvent->getMergeTag());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4265,6 +4306,7 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
|||||||
TimeStamp ts;
|
TimeStamp ts;
|
||||||
ts.setStamp(mod);
|
ts.setStamp(mod);
|
||||||
gdi.addString("", 0, "Infoga version: X#" + ts.getStampStringN());
|
gdi.addString("", 0, "Infoga version: X#" + ts.getStampStringN());
|
||||||
|
thisFile = tc->constructBase(gdi.widen(mod), mergeEvent->getMergeTag());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4281,7 +4323,7 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
|||||||
gdi.addString("", 1, "Klasser: ");
|
gdi.addString("", 1, "Klasser: ");
|
||||||
|
|
||||||
vector<pClass> cls;
|
vector<pClass> cls;
|
||||||
tc->mergeEvent->getClasses(cls, false);
|
mergeEvent->getClasses(cls, false);
|
||||||
int xw, yw;
|
int xw, yw;
|
||||||
gdi.getTargetDimension(xw, yw);
|
gdi.getTargetDimension(xw, yw);
|
||||||
int limit = (xw * 2) / 3;
|
int limit = (xw * 2) / 3;
|
||||||
@ -4298,14 +4340,39 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
|||||||
gdi.popX();
|
gdi.popX();
|
||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
|
|
||||||
gdi.addString("", 1, "Antal deltagare: X#" + itos(tc->mergeEvent->getNumRunners()));
|
gdi.addString("", 1, "Antal deltagare: X#" + itos(mergeEvent->getNumRunners()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!baseFile.empty()) {
|
||||||
|
wchar_t base[_MAX_PATH];
|
||||||
|
getUserFile(base, baseFile.c_str());
|
||||||
|
baseEvent = make_shared<oEvent>(gdi);
|
||||||
|
bool ok = false;
|
||||||
|
try {
|
||||||
|
ok = baseEvent->open(base, true, true);
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
baseEvent.reset();
|
||||||
|
gdi.dropLine();
|
||||||
|
gdi.addString("", 0, L"Varning: Kunde inte hitta föregående version av tävlingen (X).#" + baseFile).setColor(GDICOLOR::colorRed);
|
||||||
|
gdi.addString("", 0, L"Använd om möjligt samma dator som användes vid senaste importen.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sameBase) {
|
||||||
|
gdi.dropLine();
|
||||||
|
gdi.addCheckbox("AllowRemove", "Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen");
|
||||||
}
|
}
|
||||||
|
|
||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
if (!error)
|
if (!error)
|
||||||
gdi.addButton("Merge", "Slå ihop").setHandler(tc->mergeHandler.get());
|
gdi.addButton("Merge", "Slå ihop").setHandler(this);
|
||||||
gdi.addButton("Cancel", "Avbryt").setHandler(tc->mergeHandler.get());
|
gdi.addButton("Cancel", "Avbryt").setHandler(this);
|
||||||
|
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -135,9 +135,11 @@ class TabCompetition :
|
|||||||
void listBackups(gdioutput &gdi);
|
void listBackups(gdioutput &gdi);
|
||||||
|
|
||||||
shared_ptr<GuiHandler> mergeHandler;
|
shared_ptr<GuiHandler> mergeHandler;
|
||||||
shared_ptr<oEvent> mergeEvent;
|
|
||||||
void mergeCompetition(gdioutput &gdi);
|
void mergeCompetition(gdioutput &gdi);
|
||||||
wstring mergeFile;
|
wstring mergeFile;
|
||||||
|
|
||||||
|
wstring constructBase(const wstring &r, const wstring &mt) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void clearCompetitionData();
|
void clearCompetitionData();
|
||||||
|
|
||||||
|
|||||||
@ -2520,3 +2520,7 @@ Tjänstebeställningar (IOF XML) = Service Requests (IOF XML)
|
|||||||
Tjänster (IOF XML) = Services (IOF XML)
|
Tjänster (IOF XML) = Services (IOF XML)
|
||||||
Flytta deltagare från överfulla grupper = Move competitors from full groups
|
Flytta deltagare från överfulla grupper = Move competitors from full groups
|
||||||
Lotta med startgrupper = Draw with Starting Groups
|
Lotta med startgrupper = Draw with Starting Groups
|
||||||
|
Startgrupp med id X tilldelad Y finns inte = Starting group with ID X defined for Y does not exist
|
||||||
|
Använd om möjligt samma dator som användes vid senaste importen = If possible, use the same computer that was used to import the last time
|
||||||
|
Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen = Allow removal of competitors (etc) that has was deleted in the imported version.
|
||||||
|
Varning: Kunde inte hitta föregående version av tävlingen (X) = Warning: Could not find the previous version of the competition (X)
|
||||||
|
|||||||
@ -1413,7 +1413,7 @@ void IOF30Interface::readEvent(gdioutput &gdi, const xmlobject &xo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool anySG = false;
|
||||||
// This is a "hack" to interpret services of the from "XXXX 14:00 - 15:00 XXXX" as a start group.
|
// This is a "hack" to interpret services of the from "XXXX 14:00 - 15:00 XXXX" as a start group.
|
||||||
for (auto &srv : services) {
|
for (auto &srv : services) {
|
||||||
vector<wstring> parts;
|
vector<wstring> parts;
|
||||||
@ -1428,10 +1428,15 @@ void IOF30Interface::readEvent(gdioutput &gdi, const xmlobject &xo,
|
|||||||
if (t > 0)
|
if (t > 0)
|
||||||
times.push_back(t);
|
times.push_back(t);
|
||||||
}
|
}
|
||||||
if (times.size() == 2 && times[0] < times[1])
|
int ts = times.size();
|
||||||
oe.setStartGroup(srv.id, times[0], times[1]);
|
if (ts >= 2 && times[ts - 2] < times[ts - 1]) {
|
||||||
|
oe.setStartGroup(srv.id, times[ts - 2], times[ts - 1]);
|
||||||
|
anySG = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
oe.updateStartGroups();
|
|
||||||
|
if (anySG)
|
||||||
|
oe.updateStartGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IOF30Interface::setupClassConfig(int classId, const xmlobject &xTeam, map<int, vector<LegInfo> > &teamClassConfig) {
|
void IOF30Interface::setupClassConfig(int classId, const xmlobject &xTeam, map<int, vector<LegInfo> > &teamClassConfig) {
|
||||||
@ -2950,7 +2955,7 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
|||||||
xml.write("StartTime", oe.getAbsDateTimeISO(r.getStartTime(), true, useGMT));
|
xml.write("StartTime", oe.getAbsDateTimeISO(r.getStartTime(), true, useGMT));
|
||||||
|
|
||||||
bool hasTiming = (!r.getClassRef(false) || r.getClassRef(true)->getNoTiming() == false) &&
|
bool hasTiming = (!r.getClassRef(false) || r.getClassRef(true)->getNoTiming() == false) &&
|
||||||
r.getStatusComputed() != RunnerStatus::StatusNoTiming;
|
r.getStatusComputed() != RunnerStatus::StatusNoTiming && !r.noTiming();
|
||||||
|
|
||||||
int finishTime, runningTime, place, after;
|
int finishTime, runningTime, place, after;
|
||||||
RunnerStatus status;
|
RunnerStatus status;
|
||||||
|
|||||||
@ -30,18 +30,18 @@
|
|||||||
//V35: abcdef
|
//V35: abcdef
|
||||||
//V36: abcdef
|
//V36: abcdef
|
||||||
int getMeosBuild() {
|
int getMeosBuild() {
|
||||||
string revision("$Rev: 1031 $");
|
string revision("$Rev: 1047 $");
|
||||||
return 174 + atoi(revision.substr(5, string::npos).c_str());
|
return 174 + atoi(revision.substr(5, string::npos).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
//V37: ab
|
//V37: ab
|
||||||
wstring getMeosDate() {
|
wstring getMeosDate() {
|
||||||
wstring date(L"$Date: 2020-08-01 10:38:11 +0200 (lö, 01 aug 2020) $");
|
wstring date(L"$Date: 2020-09-06 08:57:56 +0200 (sö, 06 sep 2020) $");
|
||||||
return date.substr(7,10);
|
return date.substr(7,10);
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring getBuildType() {
|
wstring getBuildType() {
|
||||||
return L"RC1"; // No parantheses (...)
|
return L""; // No parantheses (...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring getMajorVersion() {
|
wstring getMajorVersion() {
|
||||||
@ -67,29 +67,13 @@ wstring getMeosCompectVersion() {
|
|||||||
|
|
||||||
void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
||||||
{
|
{
|
||||||
supp.emplace_back(L"Sergio Yañez, ABC TRAIL");
|
supp.emplace_back(L"Tjalve IF");
|
||||||
supp.emplace_back(L"Western Race Services");
|
supp.emplace_back(L"Nyköpings Orienteringsklubb");
|
||||||
supp.emplace_back(L"IK Gandvik, Skara");
|
|
||||||
supp.emplace_back(L"IK Stern");
|
|
||||||
supp.emplace_back(L"OK Roslagen");
|
|
||||||
supp.emplace_back(L"TSV Malente");
|
|
||||||
supp.emplace_back(L"Emmaboda Verda OK");
|
|
||||||
supp.emplace_back(L"KOB ATU Košice");
|
|
||||||
supp.emplace_back(L"Gävle OK");
|
|
||||||
supp.emplace_back(L"Kenneth Gattmalm, Jönköpings OK");
|
|
||||||
supp.emplace_back(L"Søllerød OK");
|
|
||||||
supp.emplace_back(L"Bengt Bengtsson");
|
|
||||||
supp.emplace_back(L"OK Landehof");
|
|
||||||
supp.emplace_back(L"OK Orinto");
|
|
||||||
supp.emplace_back(L"Bredaryds SOK");
|
|
||||||
supp.emplace_back(L"Thore Nilsson, Uddevalla OK");
|
|
||||||
supp.emplace_back(L"Timrå SOK");
|
|
||||||
supp.emplace_back(L"Åke Larsson, OK Hedströmmen");
|
|
||||||
supp.emplace_back(L"Avesta OK");
|
|
||||||
supp.emplace_back(L"Motionsorientering Göteborg");
|
supp.emplace_back(L"Motionsorientering Göteborg");
|
||||||
supp.emplace_back(L"OK Måsen");
|
supp.emplace_back(L"OK Måsen");
|
||||||
supp.emplace_back(L"IF Thor");
|
supp.emplace_back(L"IF Thor");
|
||||||
supp.emplace_back(L"SOS Jindřichův Hradec");
|
supp.emplace_back(L"SOS Jindřichův Hradec");
|
||||||
|
supp.emplace_back(L"KOB ATU Košice");
|
||||||
supp.emplace_back(L"Mats Holmberg, OK Gränsen");
|
supp.emplace_back(L"Mats Holmberg, OK Gränsen");
|
||||||
supp.emplace_back(L"Christoffer Ohlsson, Uddevalla OK");
|
supp.emplace_back(L"Christoffer Ohlsson, Uddevalla OK");
|
||||||
supp.emplace_back(L"KOB ATU Košice");
|
supp.emplace_back(L"KOB ATU Košice");
|
||||||
@ -114,6 +98,7 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
|||||||
supp.emplace_back(L"Tolereds AIK");
|
supp.emplace_back(L"Tolereds AIK");
|
||||||
supp.emplace_back(L"OK Snab");
|
supp.emplace_back(L"OK Snab");
|
||||||
supp.emplace_back(L"OK 73");
|
supp.emplace_back(L"OK 73");
|
||||||
|
supp.emplace_back(L"Herlufsholm OK");
|
||||||
supp.emplace_back(L"Helsingborgs SOK");
|
supp.emplace_back(L"Helsingborgs SOK");
|
||||||
supp.emplace_back(L"Sala OK");
|
supp.emplace_back(L"Sala OK");
|
||||||
supp.emplace_back(L"OK Roskilde");
|
supp.emplace_back(L"OK Roskilde");
|
||||||
@ -139,14 +124,19 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
|||||||
supp.emplace_back(L"Nässjö OK");
|
supp.emplace_back(L"Nässjö OK");
|
||||||
supp.emplace_back(L"Ringsjö OK");
|
supp.emplace_back(L"Ringsjö OK");
|
||||||
supp.emplace_back(L"Big Foot Orienteers");
|
supp.emplace_back(L"Big Foot Orienteers");
|
||||||
|
supp.emplace_back(L"Erik Hulthen, Mölndal Outdoor IF");
|
||||||
supp.emplace_back(L"Bay Area Orienteering Club");
|
supp.emplace_back(L"Bay Area Orienteering Club");
|
||||||
supp.emplace_back(L"Finspångs SOK");
|
supp.emplace_back(L"Finspångs SOK");
|
||||||
supp.emplace_back(L"OK Gorm, Denmark");
|
supp.emplace_back(L"OK Gorm, Denmark");
|
||||||
supp.emplace_back(L"Nyköpings OK");
|
supp.emplace_back(L"Nyköpings OK");
|
||||||
supp.emplace_back(L"Thomas Engberg, VK Uvarna");
|
supp.emplace_back(L"Thomas Engberg, VK Uvarna");
|
||||||
supp.emplace_back(L"LG Axmalm, Sävedalens AIK");
|
supp.emplace_back(L"LG Axmalm, Sävedalens AIK");
|
||||||
|
supp.emplace_back(L"Martin Ivarsson");
|
||||||
supp.emplace_back(L"Falköpings AIK OK");
|
supp.emplace_back(L"Falköpings AIK OK");
|
||||||
developSupp.push_back(L"Karlskrona SOK");
|
developSupp.push_back(L"Karlskrona SOK");
|
||||||
|
supp.emplace_back(L"Kristian Toustrup, OK Syd");
|
||||||
|
supp.emplace_back(L"Patrick NG, HKAYP");
|
||||||
|
supp.emplace_back(L"Lars Ove Karlsson, Västerås SOK");
|
||||||
|
supp.emplace_back(L"OK Milan");
|
||||||
reverse(supp.begin(), supp.end());
|
reverse(supp.begin(), supp.end());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,7 +115,7 @@ protected:
|
|||||||
void setLocalObject() { localObject = true; }
|
void setLocalObject() { localObject = true; }
|
||||||
|
|
||||||
// Merge into this entity
|
// Merge into this entity
|
||||||
virtual void merge(const oBase &input) = 0;
|
virtual void merge(const oBase &input, const oBase *base) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@ -130,7 +130,7 @@ public:
|
|||||||
void importPunches(const string &s);
|
void importPunches(const string &s);
|
||||||
const string &getPunchString() const;
|
const string &getPunchString() const;
|
||||||
|
|
||||||
void merge(const oBase &input) final;
|
void merge(const oBase &input, const oBase *base) final;
|
||||||
pair<int, int> getCardHash() const;
|
pair<int, int> getCardHash() const;
|
||||||
|
|
||||||
void Set(const xmlobject &xo);
|
void Set(const xmlobject &xo);
|
||||||
|
|||||||
@ -707,7 +707,7 @@ public:
|
|||||||
void setResultModule(const string &tag);
|
void setResultModule(const string &tag);
|
||||||
const string &getResultModuleTag() const;
|
const string &getResultModuleTag() const;
|
||||||
|
|
||||||
void merge(const oBase &input) final;
|
void merge(const oBase &input, const oBase *base) final;
|
||||||
|
|
||||||
oClass(oEvent *poe);
|
oClass(oEvent *poe);
|
||||||
oClass(oEvent *poe, int id);
|
oClass(oEvent *poe, int id);
|
||||||
|
|||||||
@ -177,7 +177,7 @@ public:
|
|||||||
|
|
||||||
void setName(const wstring &n);
|
void setName(const wstring &n);
|
||||||
|
|
||||||
void merge(const oBase &input) final;
|
void merge(const oBase &input, const oBase *base) final;
|
||||||
|
|
||||||
void set(const xmlobject &xo);
|
void set(const xmlobject &xo);
|
||||||
bool write(xmlparser &xml);
|
bool write(xmlparser &xml);
|
||||||
|
|||||||
@ -219,7 +219,7 @@ public:
|
|||||||
int getFirstNumber() const;
|
int getFirstNumber() const;
|
||||||
void getNumbers(vector<int> &numbers) const;
|
void getNumbers(vector<int> &numbers) const;
|
||||||
|
|
||||||
void merge(const oBase &input) final;
|
void merge(const oBase &input, const oBase *base) final;
|
||||||
|
|
||||||
void set(const xmlobject *xo);
|
void set(const xmlobject *xo);
|
||||||
void set(int pId, int pNumber, wstring pName);
|
void set(int pId, int pNumber, wstring pName);
|
||||||
|
|||||||
@ -239,7 +239,7 @@ public:
|
|||||||
wstring getStart() const;
|
wstring getStart() const;
|
||||||
void setStart(const wstring &start, bool sync);
|
void setStart(const wstring &start, bool sync);
|
||||||
|
|
||||||
void merge(const oBase &input) final;
|
void merge(const oBase &input, const oBase *base) final;
|
||||||
|
|
||||||
bool Write(xmlparser &xml);
|
bool Write(xmlparser &xml);
|
||||||
|
|
||||||
|
|||||||
@ -845,6 +845,7 @@ namespace {
|
|||||||
return &bfData[0];
|
return &bfData[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string oDataContainer::generateSQLSet(const oBase *ob, bool forceSetAll) const {
|
string oDataContainer::generateSQLSet(const oBase *ob, bool forceSetAll) const {
|
||||||
void *data, *oldData;
|
void *data, *oldData;
|
||||||
vector< vector<wstring> > *strptr;
|
vector< vector<wstring> > *strptr;
|
||||||
@ -914,6 +915,73 @@ string oDataContainer::generateSQLSet(const oBase *ob, bool forceSetAll) const {
|
|||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool oDataContainer::merge(oBase &destination, const oBase &source, const oBase *base) const {
|
||||||
|
bool modified = false;
|
||||||
|
void *destdata, *oldDataDmy;
|
||||||
|
vector< vector<wstring> > *deststrptr;
|
||||||
|
destination.getDataBuffers(destdata, oldDataDmy, deststrptr);
|
||||||
|
|
||||||
|
void *srcdata;
|
||||||
|
vector< vector<wstring> > *srcstrptr;
|
||||||
|
source.getDataBuffers(srcdata, oldDataDmy, srcstrptr);
|
||||||
|
|
||||||
|
void *basedata = nullptr;
|
||||||
|
vector< vector<wstring> > *basestrptr = nullptr;
|
||||||
|
if (base)
|
||||||
|
base->getDataBuffers(basedata, oldDataDmy, basestrptr);
|
||||||
|
|
||||||
|
auto setData = [](void *d, void *s, void *b, int off, int size) {
|
||||||
|
LPBYTE vd = LPBYTE(d) + off;
|
||||||
|
LPBYTE vs = LPBYTE(s) + off;
|
||||||
|
if (memcmp(vd, vs, size) != 0) {
|
||||||
|
if (b == nullptr || memcmp(LPBYTE(b) + off, vs, size) != 0) {
|
||||||
|
memcpy(vd, vs, size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t kk = 0; kk < ordered.size(); kk++) {
|
||||||
|
const oDataInfo &di = ordered[kk];
|
||||||
|
if (di.Type == oDTInt) {
|
||||||
|
if (di.SubType != oIS64) {
|
||||||
|
if (setData(destdata, srcdata, basedata, di.Index, sizeof(int)))
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (setData(destdata, srcdata, basedata, di.Index, sizeof(int64_t)))
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (di.Type == oDTString) {
|
||||||
|
if (setData(destdata, srcdata, basedata, di.Index, di.Size))
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
else if (di.Type == oDTStringDynamic) {
|
||||||
|
const wstring &s = (*srcstrptr)[0][di.Index];
|
||||||
|
wstring &d = (*deststrptr)[0][di.Index];
|
||||||
|
if (s != d) {
|
||||||
|
if (basestrptr == nullptr || (*basestrptr)[0][di.Index] != s) {
|
||||||
|
d = s;
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (di.Type == oDTStringArray) {
|
||||||
|
const auto &s = (*srcstrptr)[di.Index];
|
||||||
|
auto &d = (*deststrptr)[di.Index];
|
||||||
|
if (s != d) {
|
||||||
|
if (basestrptr == nullptr || (*basestrptr)[di.Index] != s) {
|
||||||
|
d = s;
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
void oDataContainer::getVariableInt(const void *data,
|
void oDataContainer::getVariableInt(const void *data,
|
||||||
list<oVariableInt> &var) const {
|
list<oVariableInt> &var) const {
|
||||||
|
|||||||
@ -104,8 +104,6 @@ protected:
|
|||||||
size_t stringIndexPointer;
|
size_t stringIndexPointer;
|
||||||
size_t stringArrayIndexPointer;
|
size_t stringArrayIndexPointer;
|
||||||
|
|
||||||
//map<string, oDataInfo> index;
|
|
||||||
//vector<string> ordered;
|
|
||||||
inthashmap index;
|
inthashmap index;
|
||||||
vector<oDataInfo> ordered;
|
vector<oDataInfo> ordered;
|
||||||
|
|
||||||
@ -140,6 +138,8 @@ public:
|
|||||||
return generateSQLDefinition(std::set<string>());
|
return generateSQLDefinition(std::set<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool merge(oBase &destination, const oBase &source, const oBase *base) const;
|
||||||
|
|
||||||
string generateSQLSet(const oBase *ob, bool forceSetAll) const;
|
string generateSQLSet(const oBase *ob, bool forceSetAll) const;
|
||||||
|
|
||||||
void allDataStored(const oBase *ob);
|
void allDataStored(const oBase *ob);
|
||||||
@ -210,6 +210,10 @@ private:
|
|||||||
oDataContainer *oDC;
|
oDataContainer *oDC;
|
||||||
oBase *oB;
|
oBase *oB;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
bool merge(const oBase &source, const oBase *base) {
|
||||||
|
return oDC->merge(*oB, source, base);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool setInt(const char *Name, int Value)
|
inline bool setInt(const char *Name, int Value)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -824,7 +824,7 @@ bool oEvent::writeCards(xmlparser &xml)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void oEvent::duplicate(const wstring &annotationIn) {
|
void oEvent::duplicate(const wstring &annotationIn, bool keepTags) {
|
||||||
wchar_t file[260];
|
wchar_t file[260];
|
||||||
wchar_t filename[64];
|
wchar_t filename[64];
|
||||||
wchar_t nameid[64];
|
wchar_t nameid[64];
|
||||||
@ -854,7 +854,8 @@ void oEvent::duplicate(const wstring &annotationIn) {
|
|||||||
wstring oldAnno = getAnnotation();
|
wstring oldAnno = getAnnotation();
|
||||||
|
|
||||||
wcscpy_s(CurrentFile, file);
|
wcscpy_s(CurrentFile, file);
|
||||||
currentNameId = nameid;
|
if (!keepTags)
|
||||||
|
currentNameId = nameid;
|
||||||
|
|
||||||
swprintf_s(filename, L"%d/%d %d:%02d",
|
swprintf_s(filename, L"%d/%d %d:%02d",
|
||||||
st.wDay, st.wMonth, st.wHour, st.wMinute);
|
st.wDay, st.wMonth, st.wHour, st.wMinute);
|
||||||
@ -869,7 +870,8 @@ void oEvent::duplicate(const wstring &annotationIn) {
|
|||||||
}
|
}
|
||||||
wstring oldTag = getMergeTag();
|
wstring oldTag = getMergeTag();
|
||||||
try {
|
try {
|
||||||
getMergeTag(true);
|
if (!keepTags)
|
||||||
|
getMergeTag(true);
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
catch(...) {
|
catch(...) {
|
||||||
|
|||||||
@ -963,7 +963,7 @@ public:
|
|||||||
|
|
||||||
bool exportOECSV(const wchar_t *file, int LanguageTypeIndex, bool includeSplits);
|
bool exportOECSV(const wchar_t *file, int LanguageTypeIndex, bool includeSplits);
|
||||||
bool save();
|
bool save();
|
||||||
void duplicate(const wstring &annotation);
|
void duplicate(const wstring &annotation, bool keepTags = false);
|
||||||
void newCompetition(const wstring &Name);
|
void newCompetition(const wstring &Name);
|
||||||
void clearListedCmp();
|
void clearListedCmp();
|
||||||
bool enumerateCompetitions(const wchar_t *path, const wchar_t *extension);
|
bool enumerateCompetitions(const wchar_t *path, const wchar_t *extension);
|
||||||
@ -1301,7 +1301,7 @@ protected:
|
|||||||
/** type: 0 control, 1 start, 2 finish*/
|
/** type: 0 control, 1 start, 2 finish*/
|
||||||
bool addXMLControl(const xmlobject &xcontrol, int type);
|
bool addXMLControl(const xmlobject &xcontrol, int type);
|
||||||
|
|
||||||
void merge(const oBase &src) final;
|
void merge(const oBase &src, const oBase *base) final;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -1313,7 +1313,7 @@ public:
|
|||||||
|
|
||||||
void getPredefinedClassTypes(map<wstring, ClassMetaType> &types) const;
|
void getPredefinedClassTypes(map<wstring, ClassMetaType> &types) const;
|
||||||
|
|
||||||
void merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate);
|
void merge(oEvent &src, oEvent *base, bool allowRemove, int &numAdd, int &numRemove, int &numUpdate);
|
||||||
string getLastModified() const;
|
string getLastModified() const;
|
||||||
|
|
||||||
wstring cloneCompetition(bool cloneRunners, bool cloneTimes,
|
wstring cloneCompetition(bool cloneRunners, bool cloneTimes,
|
||||||
|
|||||||
@ -1169,9 +1169,7 @@ void oEvent::drawListStartGroups(const vector<ClassDrawSpecification> &spec,
|
|||||||
int nParallel = -1;
|
int nParallel = -1;
|
||||||
if (diIn)
|
if (diIn)
|
||||||
nParallel = diIn->nFields;
|
nParallel = diIn->nFields;
|
||||||
|
|
||||||
pRunner alice = getRunner(155227, 0);
|
|
||||||
|
|
||||||
constexpr bool logOutput = false;
|
constexpr bool logOutput = false;
|
||||||
auto &sgMap = getStartGroups(true);
|
auto &sgMap = getStartGroups(true);
|
||||||
if (sgMap.empty())
|
if (sgMap.empty())
|
||||||
@ -1218,6 +1216,8 @@ void oEvent::drawListStartGroups(const vector<ClassDrawSpecification> &spec,
|
|||||||
++rPerGroupTotal[idRes->second].first;
|
++rPerGroupTotal[idRes->second].first;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (id > 0)
|
||||||
|
throw meosException(L"Startgrupp med id X tilldelad Y finns inte.#" + itow(id) + L"#" + r.getCompleteIdentification());
|
||||||
++res->second.unassigned;
|
++res->second.unassigned;
|
||||||
unassigned.push_back(&r);
|
unassigned.push_back(&r);
|
||||||
}
|
}
|
||||||
@ -1591,8 +1591,9 @@ void oEvent::drawListStartGroups(const vector<ClassDrawSpecification> &spec,
|
|||||||
ClassInfo &ci = di.classes[spec[k].classID];
|
ClassInfo &ci = di.classes[spec[k].classID];
|
||||||
ci.startGroupId = groupId;
|
ci.startGroupId = groupId;
|
||||||
if (gi.firstStart > firstStart) {
|
if (gi.firstStart > firstStart) {
|
||||||
ci.firstStart = (gi.firstStart - firstStart) / di.baseInterval;
|
// Handled by distributor
|
||||||
ci.hasFixedTime = true;
|
// ci.firstStart = (gi.firstStart - firstStart) / di.baseInterval;
|
||||||
|
// ci.hasFixedTime = true;
|
||||||
}
|
}
|
||||||
ci.nVacant = gi.vacantPerGroup[j];
|
ci.nVacant = gi.vacantPerGroup[j];
|
||||||
ci.nVacantSpecified = true;
|
ci.nVacantSpecified = true;
|
||||||
|
|||||||
@ -86,7 +86,7 @@ public:
|
|||||||
static void rehashPunches(oEvent &oe, int cardNo, pFreePunch newPunch);
|
static void rehashPunches(oEvent &oe, int cardNo, pFreePunch newPunch);
|
||||||
static bool disableHashing;
|
static bool disableHashing;
|
||||||
|
|
||||||
void merge(const oBase &input) final;
|
void merge(const oBase &input, const oBase *base) final;
|
||||||
|
|
||||||
oFreePunch(oEvent *poe, int card, int time, int type);
|
oFreePunch(oEvent *poe, int card, int time, int type);
|
||||||
oFreePunch(oEvent *poe, int id);
|
oFreePunch(oEvent *poe, int id);
|
||||||
|
|||||||
@ -1009,10 +1009,10 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
|
|||||||
wbf[0]=0;
|
wbf[0]=0;
|
||||||
|
|
||||||
auto noTimingRunner = [&]() {
|
auto noTimingRunner = [&]() {
|
||||||
return (pc ? pc->getNoTiming() : false) || (r ? r->getStatusComputed() == StatusNoTiming : false);
|
return (pc ? pc->getNoTiming() : false) || (r ? (r->getStatusComputed() == StatusNoTiming || r->noTiming()) : false);
|
||||||
};
|
};
|
||||||
auto noTimingTeam = [&]() {
|
auto noTimingTeam = [&]() {
|
||||||
return (pc ? pc->getNoTiming() : false) || (t ? t->getStatusComputed() == StatusNoTiming : false);
|
return (pc ? pc->getNoTiming() : false) || (t ? (t->getStatusComputed() == StatusNoTiming || t->noTiming()): false);
|
||||||
};
|
};
|
||||||
bool invalidClass = pc && pc->getClassStatus() != oClass::ClassStatus::Normal;
|
bool invalidClass = pc && pc->getClassStatus() != oClass::ClassStatus::Normal;
|
||||||
int legIndex = pp.legIndex;
|
int legIndex = pp.legIndex;
|
||||||
@ -2459,7 +2459,7 @@ void oEvent::listGeneratePunches(const oListInfo &listInfo, gdioutput &gdi,
|
|||||||
|
|
||||||
if (cls && cls->getNoTiming())
|
if (cls && cls->getNoTiming())
|
||||||
return;
|
return;
|
||||||
if (r && r->getStatusComputed() == StatusNoTiming)
|
if (r && (r->getStatusComputed() == StatusNoTiming || r->noTiming()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int h = gdi.getLineHeight();
|
int h = gdi.getLineHeight();
|
||||||
|
|||||||
@ -99,7 +99,7 @@ public:
|
|||||||
void appendCodeString(string &dst) const;
|
void appendCodeString(string &dst) const;
|
||||||
|
|
||||||
|
|
||||||
void merge(const oBase &input) override;
|
void merge(const oBase &input, const oBase *base) override;
|
||||||
|
|
||||||
oPunch(oEvent *poe);
|
oPunch(oEvent *poe);
|
||||||
virtual ~oPunch();
|
virtual ~oPunch();
|
||||||
|
|||||||
@ -201,7 +201,7 @@ public:
|
|||||||
bool preventRestart() const;
|
bool preventRestart() const;
|
||||||
void preventRestart(bool state);
|
void preventRestart(bool state);
|
||||||
|
|
||||||
void merge(const oBase &input) override;
|
void merge(const oBase &input, const oBase *base) override;
|
||||||
|
|
||||||
/** Call this method after doing something to just this
|
/** Call this method after doing something to just this
|
||||||
runner/team that changed the time/status etc, that effects
|
runner/team that changed the time/status etc, that effects
|
||||||
@ -244,6 +244,9 @@ public:
|
|||||||
bool hasFlag(TransferFlags flag) const;
|
bool hasFlag(TransferFlags flag) const;
|
||||||
void setFlag(TransferFlags flag, bool state);
|
void setFlag(TransferFlags flag, bool state);
|
||||||
|
|
||||||
|
/** Return true if no timing is requested. */
|
||||||
|
bool noTiming() const { return hasFlag(FlagNoTiming); }
|
||||||
|
|
||||||
// Get the runners team or the team itself
|
// Get the runners team or the team itself
|
||||||
virtual cTeam getTeam() const = 0;
|
virtual cTeam getTeam() const = 0;
|
||||||
virtual pTeam getTeam() = 0;
|
virtual pTeam getTeam() = 0;
|
||||||
@ -958,7 +961,7 @@ public:
|
|||||||
/** Formats extra line for runner []-syntax, or if r is null, checks validity and throws on error.*/
|
/** Formats extra line for runner []-syntax, or if r is null, checks validity and throws on error.*/
|
||||||
static wstring formatExtraLine(pRunner r, const wstring &input);
|
static wstring formatExtraLine(pRunner r, const wstring &input);
|
||||||
|
|
||||||
void merge(const oBase &input) final;
|
void merge(const oBase &input, const oBase *base) final;
|
||||||
|
|
||||||
virtual ~oRunner();
|
virtual ~oRunner();
|
||||||
|
|
||||||
|
|||||||
@ -279,7 +279,7 @@ public:
|
|||||||
void set(const xmlobject &xo);
|
void set(const xmlobject &xo);
|
||||||
bool write(xmlparser &xml);
|
bool write(xmlparser &xml);
|
||||||
|
|
||||||
void merge(const oBase &input) final;
|
void merge(const oBase &input, const oBase *base) final;
|
||||||
|
|
||||||
oTeam(oEvent *poe, int id);
|
oTeam(oEvent *poe, int id);
|
||||||
oTeam(oEvent *poe);
|
oTeam(oEvent *poe);
|
||||||
|
|||||||
@ -43,7 +43,7 @@ Eksoppsv
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
void oEvent::merge(oEvent &src, oEvent *base, bool allowRemove, int &numAdd, int &numRemove, int &numUpdate) {
|
||||||
numAdd = 0;
|
numAdd = 0;
|
||||||
numRemove = 0;
|
numRemove = 0;
|
||||||
numUpdate = 0;
|
numUpdate = 0;
|
||||||
@ -76,27 +76,62 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
auto updateNewItem = [&addMinTime, &numAdd](oBase *pNew, const oBase &src) {
|
auto updateNewItem = [&addMinTime, &numAdd](oBase *pNew, const oBase &src) {
|
||||||
if (pNew) {
|
if (pNew) {
|
||||||
numAdd++;
|
numAdd++;
|
||||||
pNew->merge(src);
|
pNew->merge(src, nullptr);
|
||||||
pNew->synchronize();
|
pNew->synchronize();
|
||||||
if (pNew->Modified.getStamp() < addMinTime)
|
if (pNew->Modified.getStamp() < addMinTime)
|
||||||
pNew->Modified.setStamp(addMinTime);
|
pNew->Modified.setStamp(addMinTime);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto mergeItem = [&numUpdate](oBase *pExisting, const oBase &src) {
|
auto mergeItem = [&numUpdate](oBase *pExisting, const oBase &src, const oBase *baseItem) {
|
||||||
numUpdate++;
|
numUpdate++;
|
||||||
string oldStamp = pExisting->Modified.getStamp();
|
string oldStamp = pExisting->Modified.getStamp();
|
||||||
pExisting->merge(src);
|
pExisting->merge(src, baseItem);
|
||||||
if (pExisting->Modified.getStamp() < oldStamp)
|
if (pExisting->Modified.getStamp() < oldStamp)
|
||||||
pExisting->Modified.setStamp(oldStamp);
|
pExisting->Modified.setStamp(oldStamp);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto computeRemove = [&bt](const auto &list, const set<int> &existing, set<int> &remove) {
|
auto getBaseMap = [](auto &list) {
|
||||||
|
map<int, oBase *> ret;
|
||||||
|
for (auto &c : list)
|
||||||
|
ret.emplace(c.getId(), &c);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
map<int, oBase*> baseMap;
|
||||||
|
|
||||||
|
auto computeRemove = [&bt, &baseMap](const auto &list, const set<int> &existing, set<int> &remove) {
|
||||||
for (auto &c : list) {
|
for (auto &c : list) {
|
||||||
|
if (!baseMap.empty() && !baseMap.count(c.Id))
|
||||||
|
continue; // Did non exist in base -> not removed
|
||||||
if (!c.isRemoved() && !existing.count(c.Id) && c.getStamp() < bt)
|
if (!c.isRemoved() && !existing.count(c.Id) && c.getStamp() < bt)
|
||||||
remove.insert(c.Id);
|
remove.insert(c.Id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Swap id
|
||||||
|
auto changeBaseId = [&baseMap](int oldId, int newId) {
|
||||||
|
oBase *rOld = nullptr, *rNew = nullptr;
|
||||||
|
auto ob = baseMap.find(newId);
|
||||||
|
if (ob != baseMap.end() && ob->second) {
|
||||||
|
rOld = ob->second;
|
||||||
|
rOld->changeId(oldId);
|
||||||
|
}
|
||||||
|
ob = baseMap.find(oldId);
|
||||||
|
if (ob != baseMap.end() && ob->second) {
|
||||||
|
rNew = ob->second;
|
||||||
|
rNew->changeId(newId);
|
||||||
|
}
|
||||||
|
baseMap[newId] = rNew;
|
||||||
|
baseMap[oldId] = rOld;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto getBaseObject = [&baseMap](const oBase &src) {
|
||||||
|
auto res = baseMap.find(src.getId());
|
||||||
|
if (res != baseMap.end())
|
||||||
|
return res->second;
|
||||||
|
else
|
||||||
|
return (oBase*)nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
map<int, pControl> ctrl;
|
map<int, pControl> ctrl;
|
||||||
@ -105,8 +140,12 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
ctrl[c.Id] = &c;
|
ctrl[c.Id] = &c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base)
|
||||||
|
baseMap = getBaseMap(base->Controls);
|
||||||
|
|
||||||
set<int> srcControl;
|
set<int> srcControl;
|
||||||
for (const oControl &c : src.Controls) {
|
for (const oControl &c : src.Controls) {
|
||||||
|
const oBase *baseObj = getBaseObject(c);
|
||||||
const string &stmp = c.getStamp();
|
const string &stmp = c.getStamp();
|
||||||
if (!c.isRemoved()) {
|
if (!c.isRemoved()) {
|
||||||
if (stmp > previousMergeTime) {
|
if (stmp > previousMergeTime) {
|
||||||
@ -114,7 +153,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
thisMergeTime = stmp;
|
thisMergeTime = stmp;
|
||||||
auto mc = ctrl.find(c.Id);
|
auto mc = ctrl.find(c.Id);
|
||||||
if (mc != ctrl.end()) {
|
if (mc != ctrl.end()) {
|
||||||
mergeItem(mc->second, c);
|
mergeItem(mc->second, c, baseObj);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pControl pNew = addControl(c);
|
pControl pNew = addControl(c);
|
||||||
@ -135,8 +174,12 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
crs[c.Id] = &c;
|
crs[c.Id] = &c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base)
|
||||||
|
baseMap = getBaseMap(base->Courses);
|
||||||
|
|
||||||
set<int> srcCourse;
|
set<int> srcCourse;
|
||||||
for (const oCourse &c : src.Courses) {
|
for (const oCourse &c : src.Courses) {
|
||||||
|
const oBase *baseObj = getBaseObject(c);
|
||||||
const string &stmp = c.getStamp();
|
const string &stmp = c.getStamp();
|
||||||
if (!c.isRemoved()) {
|
if (!c.isRemoved()) {
|
||||||
bool okMerge = stmp > previousMergeTime;
|
bool okMerge = stmp > previousMergeTime;
|
||||||
@ -145,7 +188,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
auto mc = crs.find(c.Id);
|
auto mc = crs.find(c.Id);
|
||||||
if (mc != crs.end()) {
|
if (mc != crs.end()) {
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mc->second, c);
|
mergeItem(mc->second, c, baseObj);
|
||||||
}
|
}
|
||||||
else if (okMerge) {
|
else if (okMerge) {
|
||||||
pCourse pNew = addCourse(c);
|
pCourse pNew = addCourse(c);
|
||||||
@ -168,9 +211,13 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
clsN[c.Name] = &c;
|
clsN[c.Name] = &c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base)
|
||||||
|
baseMap = getBaseMap(base->Classes);
|
||||||
|
|
||||||
set<int> srcClass;
|
set<int> srcClass;
|
||||||
for (oClass &c : src.Classes) {
|
for (oClass &c : src.Classes) {
|
||||||
|
oBase *baseObj = getBaseObject(c);
|
||||||
const string &stmp = c.getStamp();
|
const string &stmp = c.getStamp();
|
||||||
bool merged = false;
|
bool merged = false;
|
||||||
if (!c.isRemoved()) {
|
if (!c.isRemoved()) {
|
||||||
@ -183,23 +230,24 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
if (mc != cls.end()) {
|
if (mc != cls.end()) {
|
||||||
if (compareClassName(mc->second->Name, c.Name)) {
|
if (compareClassName(mc->second->Name, c.Name)) {
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mc->second, c);
|
mergeItem(mc->second, c, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto updateIdCls = [&](int id) {
|
auto updateIdCls = [&](int id) {
|
||||||
pClass other = src.getClass(id);
|
changeBaseId(c.Id, id);
|
||||||
if (other)
|
pClass other = src.getClass(id);
|
||||||
|
if (other)
|
||||||
other->changeId(c.Id);
|
other->changeId(c.Id);
|
||||||
c.changeId(id);
|
c.changeId(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!merged) {
|
if (!merged) {
|
||||||
auto mcN = clsN.find(c.Name);
|
auto mcN = clsN.find(c.Name);
|
||||||
if (mcN != clsN.end()) {
|
if (mcN != clsN.end()) {
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mcN->second, c);
|
mergeItem(mcN->second, c, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
updateIdCls(mcN->second->Id);
|
updateIdCls(mcN->second->Id);
|
||||||
}
|
}
|
||||||
@ -230,8 +278,12 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
crdByHash[c.getCardHash()] = &c;
|
crdByHash[c.getCardHash()] = &c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base)
|
||||||
|
baseMap = getBaseMap(base->Cards);
|
||||||
|
|
||||||
for (oCard &c : src.Cards) {
|
for (oCard &c : src.Cards) {
|
||||||
|
const oBase *baseObj = getBaseObject(c);
|
||||||
const string &stmp = c.getStamp();
|
const string &stmp = c.getStamp();
|
||||||
if (!c.isRemoved() && stmp > previousMergeTime) {
|
if (!c.isRemoved() && stmp > previousMergeTime) {
|
||||||
if (stmp > thisMergeTime)
|
if (stmp > thisMergeTime)
|
||||||
@ -244,12 +296,13 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
auto c2 = mc->second;
|
auto c2 = mc->second;
|
||||||
auto p2 = c2->getNumPunches() > 0 ? c2->getPunchByIndex(c2->getNumPunches() - 1)->getTimeInt() : 0;
|
auto p2 = c2->getNumPunches() > 0 ? c2->getPunchByIndex(c2->getNumPunches() - 1)->getTimeInt() : 0;
|
||||||
if (p1 == p2)
|
if (p1 == p2)
|
||||||
mergeItem(mc->second, c), merged = true;
|
mergeItem(mc->second, c, baseObj), merged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto updateIdCrd = [&](int id) {
|
auto updateIdCrd = [&](int id) {
|
||||||
|
changeBaseId(c.Id, id);
|
||||||
pCard other = src.getCard(id);
|
pCard other = src.getCard(id);
|
||||||
if (other)
|
if (other)
|
||||||
other->changeId(c.Id);
|
other->changeId(c.Id);
|
||||||
c.changeId(id);
|
c.changeId(id);
|
||||||
};
|
};
|
||||||
@ -257,7 +310,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
if (!merged) {
|
if (!merged) {
|
||||||
auto mcN = crdByHash.find(c.getCardHash());
|
auto mcN = crdByHash.find(c.getCardHash());
|
||||||
if (mcN != crdByHash.end()) {
|
if (mcN != crdByHash.end()) {
|
||||||
mergeItem(mcN->second, c);
|
mergeItem(mcN->second, c, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
updateIdCrd(mcN->second->Id);
|
updateIdCrd(mcN->second->Id);
|
||||||
}
|
}
|
||||||
@ -288,9 +341,13 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
clbByName[c.getName()] = &c;
|
clbByName[c.getName()] = &c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base)
|
||||||
|
baseMap = getBaseMap(base->Clubs);
|
||||||
|
|
||||||
set<int> srcClub;
|
set<int> srcClub;
|
||||||
for (oClub &c : src.Clubs) {
|
for (oClub &c : src.Clubs) {
|
||||||
|
const oBase *baseObj = getBaseObject(c);
|
||||||
const string &stmp = c.getStamp();
|
const string &stmp = c.getStamp();
|
||||||
if (!c.isRemoved()) {
|
if (!c.isRemoved()) {
|
||||||
bool okMerge = stmp > previousMergeTime;
|
bool okMerge = stmp > previousMergeTime;
|
||||||
@ -304,12 +361,13 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
if ((c.getExtIdentifier() != 0 && c.getExtIdentifier() == mc->second->getExtIdentifier())
|
if ((c.getExtIdentifier() != 0 && c.getExtIdentifier() == mc->second->getExtIdentifier())
|
||||||
|| c.getName() == mc->second->getName()) {
|
|| c.getName() == mc->second->getName()) {
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mc->second, c);
|
mergeItem(mc->second, c, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto updateIdClb = [&](int id) {
|
auto updateIdClb = [&](int id) {
|
||||||
|
changeBaseId(c.Id, id);
|
||||||
pClub other = src.getClub(id);
|
pClub other = src.getClub(id);
|
||||||
if (other)
|
if (other)
|
||||||
other->changeId(c.Id);
|
other->changeId(c.Id);
|
||||||
@ -320,7 +378,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
auto mcN = clbByExt.find(c.getExtIdentifier());
|
auto mcN = clbByExt.find(c.getExtIdentifier());
|
||||||
if (mcN != clbByExt.end()) {
|
if (mcN != clbByExt.end()) {
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mcN->second, c);
|
mergeItem(mcN->second, c, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
updateIdClb(mcN->second->Id);
|
updateIdClb(mcN->second->Id);
|
||||||
}
|
}
|
||||||
@ -330,7 +388,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
auto mcN = clbByName.find(c.getName());
|
auto mcN = clbByName.find(c.getName());
|
||||||
if (mcN != clbByName.end()) {
|
if (mcN != clbByName.end()) {
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mcN->second, c);
|
mergeItem(mcN->second, c, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
updateIdClb(mcN->second->Id);
|
updateIdClb(mcN->second->Id);
|
||||||
}
|
}
|
||||||
@ -356,6 +414,9 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
map<int, pRunner> rn;
|
map<int, pRunner> rn;
|
||||||
map<int64_t, pRunner> rnByExt;
|
map<int64_t, pRunner> rnByExt;
|
||||||
map<pair<int, wstring>, pRunner> rnByCardName;
|
map<pair<int, wstring>, pRunner> rnByCardName;
|
||||||
|
|
||||||
|
if (base)
|
||||||
|
baseMap = getBaseMap(base->Runners);
|
||||||
|
|
||||||
for (oRunner &r : Runners) {
|
for (oRunner &r : Runners) {
|
||||||
if (!r.isRemoved()) {
|
if (!r.isRemoved()) {
|
||||||
@ -367,6 +428,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
}
|
}
|
||||||
set<int> srcRunner;
|
set<int> srcRunner;
|
||||||
for (oRunner &r : src.Runners) {
|
for (oRunner &r : src.Runners) {
|
||||||
|
const oBase *baseObj = getBaseObject(r);
|
||||||
const string &stmp = r.getStamp();
|
const string &stmp = r.getStamp();
|
||||||
if (!r.isRemoved()) {
|
if (!r.isRemoved()) {
|
||||||
bool okMerge = stmp > previousMergeTime;
|
bool okMerge = stmp > previousMergeTime;
|
||||||
@ -382,15 +444,16 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
|| mc->second->isVacant()) {
|
|| mc->second->isVacant()) {
|
||||||
|
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mc->second, r);
|
mergeItem(mc->second, r, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto updateIdR = [&](int id) {
|
auto updateIdR = [&](int id) {
|
||||||
pRunner other = src.getRunner(id, 0);
|
changeBaseId(r.Id, id);
|
||||||
if (other)
|
pRunner other = src.getRunner(id, 0);
|
||||||
other->changeId(src.Id);
|
if (other)
|
||||||
|
other->changeId(r.Id);
|
||||||
r.changeId(id);
|
r.changeId(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -398,7 +461,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
auto mcN = rnByExt.find(r.getExtIdentifier());
|
auto mcN = rnByExt.find(r.getExtIdentifier());
|
||||||
if (mcN != rnByExt.end()) {
|
if (mcN != rnByExt.end()) {
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mcN->second, r);
|
mergeItem(mcN->second, r, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
updateIdR(mcN->second->Id);
|
updateIdR(mcN->second->Id);
|
||||||
}
|
}
|
||||||
@ -408,7 +471,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
auto mcN = rnByCardName.find(make_pair(r.getCardNo(), r.sName));
|
auto mcN = rnByCardName.find(make_pair(r.getCardNo(), r.sName));
|
||||||
if (mcN != rnByCardName.end()) {
|
if (mcN != rnByCardName.end()) {
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mcN->second, r);
|
mergeItem(mcN->second, r, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
updateIdR(mcN->second->Id);
|
updateIdR(mcN->second->Id);
|
||||||
}
|
}
|
||||||
@ -441,8 +504,12 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base)
|
||||||
|
baseMap = getBaseMap(base->Teams);
|
||||||
|
|
||||||
set<int> srcTeam;
|
set<int> srcTeam;
|
||||||
for (oTeam &t : src.Teams) {
|
for (oTeam &t : src.Teams) {
|
||||||
|
const oBase *baseObj = getBaseObject(t);
|
||||||
const string &stmp = t.getStamp();
|
const string &stmp = t.getStamp();
|
||||||
if (!t.isRemoved()) {
|
if (!t.isRemoved()) {
|
||||||
bool okMerge = stmp > previousMergeTime;
|
bool okMerge = stmp > previousMergeTime;
|
||||||
@ -454,24 +521,24 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
if (mc != tm.end()) {
|
if (mc != tm.end()) {
|
||||||
if (t.getClubId() == mc->second->getClubId()) {
|
if (t.getClubId() == mc->second->getClubId()) {
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mc->second, t);
|
mergeItem(mc->second, t, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto updateIdT = [&](int id) {
|
auto updateIdT = [&](int id) {
|
||||||
|
changeBaseId(t.Id, id);
|
||||||
pTeam other = src.getTeam(id);
|
pTeam other = src.getTeam(id);
|
||||||
if (other)
|
if (other)
|
||||||
other->changeId(src.Id);
|
other->changeId(t.Id);
|
||||||
t.changeId(id);
|
t.changeId(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (!merged) {
|
if (!merged) {
|
||||||
auto mcN = tmByClassName.find(make_pair(t.getClassId(false), t.getName()));
|
auto mcN = tmByClassName.find(make_pair(t.getClassId(false), t.getName()));
|
||||||
if (mcN != tmByClassName.end()) {
|
if (mcN != tmByClassName.end()) {
|
||||||
if (okMerge)
|
if (okMerge)
|
||||||
mergeItem(mcN->second, t);
|
mergeItem(mcN->second, t, baseObj);
|
||||||
merged = true;
|
merged = true;
|
||||||
updateIdT(mcN->second->Id);
|
updateIdT(mcN->second->Id);
|
||||||
}
|
}
|
||||||
@ -503,12 +570,14 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
removeEnts(rTeam, [this](int id) -> pBase {return getTeam(id); });
|
if (allowRemove) {
|
||||||
removeEnts(rRunner, [this](int id) -> pBase {return getRunner(id, 0); });
|
removeEnts(rTeam, [this](int id) -> pBase {return getTeam(id); });
|
||||||
removeEnts(rClub, [this](int id) -> pBase {return getClub(id); });
|
removeEnts(rRunner, [this](int id) -> pBase {return getRunner(id, 0); });
|
||||||
removeEnts(rClass, [this](int id) -> pBase {return getClass(id); });
|
removeEnts(rClub, [this](int id) -> pBase {return getClub(id); });
|
||||||
removeEnts(rCourse, [this](int id) -> pBase {return getCourse(id); });
|
removeEnts(rClass, [this](int id) -> pBase {return getClass(id); });
|
||||||
removeEnts(rControl, [this](int id) -> pBase {return getControl(id); });
|
removeEnts(rCourse, [this](int id) -> pBase {return getCourse(id); });
|
||||||
|
removeEnts(rControl, [this](int id) -> pBase {return getControl(id); });
|
||||||
|
}
|
||||||
|
|
||||||
wstring mtOut(thisMergeTime.begin(), thisMergeTime.end());
|
wstring mtOut(thisMergeTime.begin(), thisMergeTime.end());
|
||||||
addMergeInfo(mergeTag, mtOut);
|
addMergeInfo(mergeTag, mtOut);
|
||||||
@ -1228,102 +1297,149 @@ void oEvent::transferResult(oEvent &ce,
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void oAbstractRunner::merge(const oBase &input) {
|
void oAbstractRunner::merge(const oBase &input, const oBase *baseIn) {
|
||||||
const oAbstractRunner &src = dynamic_cast<const oAbstractRunner&>(input);
|
const oAbstractRunner &src = dynamic_cast<const oAbstractRunner&>(input);
|
||||||
setName(src.sName, false);
|
const oAbstractRunner *base = dynamic_cast<const oAbstractRunner*>(baseIn);
|
||||||
|
|
||||||
setStartTime(src.startTime, true, ChangeType::Update, false);
|
if (base == nullptr || base->sName != src.sName)
|
||||||
setFinishTime(src.FinishTime);
|
setName(src.sName, false);
|
||||||
setStatus(src.status, true, ChangeType::Update);
|
|
||||||
setStartNo(src.StartNo, ChangeType::Update);
|
if (base == nullptr || base->startTime != src.startTime)
|
||||||
setClubId(src.getClubId());
|
setStartTime(src.startTime, true, ChangeType::Update, false);
|
||||||
setClassId(src.getClassId(false), false);
|
|
||||||
|
if (base == nullptr || base->FinishTime != src.FinishTime)
|
||||||
|
setFinishTime(src.FinishTime);
|
||||||
|
|
||||||
|
if (base == nullptr || base->status != src.status)
|
||||||
|
setStatus(src.status, true, ChangeType::Update);
|
||||||
|
|
||||||
|
if (base == nullptr || base->StartNo != src.StartNo)
|
||||||
|
setStartNo(src.StartNo, ChangeType::Update);
|
||||||
|
|
||||||
|
if (base == nullptr || base->getClub() != src.getClub())
|
||||||
|
setClubId(src.getClubId());
|
||||||
|
|
||||||
|
if (base == nullptr || base->getClass(false) != src.getClass(false))
|
||||||
|
setClassId(src.getClassId(false), false);
|
||||||
|
|
||||||
setInputPlace(src.inputPlace);
|
if (base == nullptr || base->inputPlace != src.inputPlace)
|
||||||
if (inputTime != src.inputTime) {
|
setInputPlace(src.inputPlace);
|
||||||
inputTime = src.inputTime;
|
|
||||||
updateChanged();
|
if (base == nullptr || base->inputTime != src.inputTime) {
|
||||||
|
if (inputTime != src.inputTime) {
|
||||||
|
inputTime = src.inputTime;
|
||||||
|
updateChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setInputStatus(src.inputStatus);
|
if (base == nullptr || base->inputStatus != src.inputStatus)
|
||||||
setInputPoints(src.inputPoints);
|
setInputStatus(src.inputStatus);
|
||||||
|
|
||||||
|
if (base == nullptr || base->inputPoints != src.inputPoints)
|
||||||
|
setInputPoints(src.inputPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void oRunner::merge(const oBase &input) {
|
void oRunner::merge(const oBase &input, const oBase *baseIn) {
|
||||||
oAbstractRunner::merge(input);
|
oAbstractRunner::merge(input, baseIn);
|
||||||
|
|
||||||
const oRunner &src = dynamic_cast<const oRunner&>(input);
|
const oRunner &src = dynamic_cast<const oRunner&>(input);
|
||||||
setCourseId(src.getCourseId());
|
const oRunner *base = dynamic_cast<const oRunner*>(baseIn);
|
||||||
if (src.getCardId() != 0)
|
|
||||||
setCard(src.getCardId());
|
|
||||||
setCardNo(src.getCardNo(), false);
|
|
||||||
|
|
||||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
if (base == nullptr || base->getCourseId() != src.getCourseId())
|
||||||
memcpy(oData, src.oData, sizeof(oData));
|
setCourseId(src.getCourseId());
|
||||||
|
|
||||||
|
if ((base == nullptr && src.getCardId() != 0) || (base != nullptr && base->getCardId() != src.getCardId()))
|
||||||
|
setCard(src.getCardId());
|
||||||
|
|
||||||
|
if (base == nullptr || base->getCardNo() != src.getCardNo())
|
||||||
|
setCardNo(src.getCardNo(), false);
|
||||||
|
|
||||||
|
if (getDI().merge(input, base))
|
||||||
updateChanged();
|
updateChanged();
|
||||||
}
|
|
||||||
synchronize(true);
|
synchronize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void oTeam::merge(const oBase &input) {
|
void oTeam::merge(const oBase &input, const oBase *baseIn) {
|
||||||
oAbstractRunner::merge(input);
|
oAbstractRunner::merge(input, baseIn);
|
||||||
|
|
||||||
const oTeam &src = dynamic_cast<const oTeam&>(input);
|
const oTeam &src = dynamic_cast<const oTeam&>(input);
|
||||||
|
const oTeam *base = dynamic_cast<const oTeam*>(baseIn);
|
||||||
|
|
||||||
bool same = src.Runners.size() == Runners.size();
|
auto getRId = [](const oTeam &t, int ix) {
|
||||||
vector<int> r(src.Runners.size());
|
pRunner r = t.getRunner(ix);
|
||||||
for (size_t i = 0; i < src.Runners.size(); i++) {
|
return r ? r->getId() : 0;
|
||||||
if (src.Runners[i]) {
|
};
|
||||||
r[i] = src.Runners[i]->Id;
|
|
||||||
src.Runners[i]->tInTeam = nullptr;
|
|
||||||
}
|
|
||||||
if (same) {
|
|
||||||
int rc = Runners[i] ? Runners[i]->Id : 0;
|
|
||||||
if (rc != r[i])
|
|
||||||
same = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
importRunners(r);
|
|
||||||
if (!same)
|
|
||||||
updateChanged();
|
|
||||||
|
|
||||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
bool chR;
|
||||||
memcpy(oData, src.oData, sizeof(oData));
|
if (base) {
|
||||||
updateChanged();
|
chR = base->Runners.size() != src.Runners.size();
|
||||||
|
if (!chR) {
|
||||||
|
for (size_t i = 0; i < src.Runners.size(); i++) {
|
||||||
|
if (getRId(src, i) != getRId(*base, i))
|
||||||
|
chR = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else chR = true;
|
||||||
|
|
||||||
|
if (chR) {
|
||||||
|
bool same = src.Runners.size() == Runners.size();
|
||||||
|
vector<int> r(src.Runners.size());
|
||||||
|
for (size_t i = 0; i < src.Runners.size(); i++) {
|
||||||
|
if (src.Runners[i]) {
|
||||||
|
r[i] = src.Runners[i]->Id;
|
||||||
|
src.Runners[i]->tInTeam = nullptr;
|
||||||
|
}
|
||||||
|
if (same) {
|
||||||
|
int rc = Runners[i] ? Runners[i]->Id : 0;
|
||||||
|
if (rc != r[i])
|
||||||
|
same = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!same) {
|
||||||
|
importRunners(r);
|
||||||
|
updateChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getDI().merge(input, base))
|
||||||
|
updateChanged();
|
||||||
|
|
||||||
synchronize(true);
|
synchronize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void oControl::merge(const oBase &input) {
|
void oControl::merge(const oBase &input, const oBase *base) {
|
||||||
const oControl &src = dynamic_cast<const oControl&>(input);
|
const oControl &src = dynamic_cast<const oControl&>(input);
|
||||||
if (src.Name.length() > 0)
|
if (src.Name.length() > 0)
|
||||||
setName(src.Name);
|
setName(src.Name);
|
||||||
setNumbers(src.codeNumbers());
|
setNumbers(src.codeNumbers());
|
||||||
setStatus(src.getStatus());
|
setStatus(src.getStatus());
|
||||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
if (getDI().merge(input, base))
|
||||||
memcpy(oData, src.oData, sizeof(oData));
|
|
||||||
updateChanged();
|
updateChanged();
|
||||||
}
|
|
||||||
synchronize(true);
|
synchronize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void oCourse::merge(const oBase &input) {
|
void oCourse::merge(const oBase &input, const oBase *baseIn) {
|
||||||
const oCourse &src = dynamic_cast<const oCourse&>(input);
|
const oCourse &src = dynamic_cast<const oCourse&>(input);
|
||||||
|
const oCourse *base = dynamic_cast<const oCourse*>(baseIn);
|
||||||
|
|
||||||
if (src.Name.length() > 0)
|
if ((base == nullptr || base->Name != src.Name) && (src.Name.length() > 0))
|
||||||
setName(src.Name);
|
setName(src.Name);
|
||||||
setLength(src.Length);
|
if (!base || base->Length != src.Length)
|
||||||
|
setLength(src.Length);
|
||||||
|
|
||||||
importControls(src.getControls(), true, false);
|
importControls(src.getControls(), true, false);
|
||||||
importLegLengths(src.getLegLengths(), true);
|
importLegLengths(src.getLegLengths(), true);
|
||||||
|
|
||||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
if (getDI().merge(input, base))
|
||||||
memcpy(oData, src.oData, sizeof(oData));
|
|
||||||
updateChanged();
|
updateChanged();
|
||||||
}
|
|
||||||
synchronize(true);
|
synchronize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void oClass::merge(const oBase &input) {
|
void oClass::merge(const oBase &input, const oBase *base) {
|
||||||
const oClass &src = dynamic_cast<const oClass&>(input);
|
const oClass &src = dynamic_cast<const oClass&>(input);
|
||||||
|
|
||||||
if (src.Name.length() > 0)
|
if (src.Name.length() > 0)
|
||||||
@ -1351,25 +1467,23 @@ void oClass::merge(const oBase &input) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
if (getDI().merge(input, base))
|
||||||
memcpy(oData, src.oData, sizeof(oData));
|
|
||||||
updateChanged();
|
updateChanged();
|
||||||
}
|
|
||||||
synchronize(true);
|
synchronize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void oClub::merge(const oBase &input) {
|
void oClub::merge(const oBase &input, const oBase *base) {
|
||||||
const oClub &src = dynamic_cast<const oClub&>(input);
|
const oClub &src = dynamic_cast<const oClub&>(input);
|
||||||
|
|
||||||
setName(src.getName());
|
setName(src.getName());
|
||||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
if (getDI().merge(input, base))
|
||||||
memcpy(oData, src.oData, sizeof(oData));
|
|
||||||
updateChanged();
|
updateChanged();
|
||||||
}
|
|
||||||
synchronize(true);
|
synchronize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void oCard::merge(const oBase &input) {
|
void oCard::merge(const oBase &input, const oBase *base) {
|
||||||
const oCard &src = dynamic_cast<const oCard&>(input);
|
const oCard &src = dynamic_cast<const oCard&>(input);
|
||||||
|
|
||||||
setCardNo(src.getCardNo());
|
setCardNo(src.getCardNo());
|
||||||
@ -1384,19 +1498,19 @@ void oCard::merge(const oBase &input) {
|
|||||||
synchronize(true);
|
synchronize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void oPunch::merge(const oBase &input) {
|
void oPunch::merge(const oBase &input, const oBase *base) {
|
||||||
const oPunch &src = dynamic_cast<const oPunch&>(input);
|
const oPunch &src = dynamic_cast<const oPunch&>(input);
|
||||||
// Not implemented
|
// Not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void oFreePunch::merge(const oBase &input) {
|
void oFreePunch::merge(const oBase &input, const oBase *base) {
|
||||||
const oFreePunch &src = dynamic_cast<const oFreePunch&>(input);
|
const oFreePunch &src = dynamic_cast<const oFreePunch&>(input);
|
||||||
// Not implemented
|
// Not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void oEvent::merge(const oBase &srcIn) {
|
void oEvent::merge(const oBase &srcIn, const oBase *base) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1113,7 +1113,7 @@ void RestServer::lookup(oEvent &oe, const string &what, const multimap<string, s
|
|||||||
xml.write("Card", r->getCardNo());
|
xml.write("Card", r->getCardNo());
|
||||||
xml.write("Status", {make_pair("code", itow(r->getStatusComputed()))}, r->getStatusS(true, true));
|
xml.write("Status", {make_pair("code", itow(r->getStatusComputed()))}, r->getStatusS(true, true));
|
||||||
xml.write("Start", r->getStartTimeS());
|
xml.write("Start", r->getStartTimeS());
|
||||||
if (r->getFinishTime() > 0 && r->getStatusComputed() != StatusNoTiming) {
|
if (r->getFinishTime() > 0 && r->getStatusComputed() != StatusNoTiming && !r->noTiming()) {
|
||||||
xml.write("Finish", r->getFinishTimeS());
|
xml.write("Finish", r->getFinishTimeS());
|
||||||
xml.write("RunningTime", r->getRunningTimeS(true));
|
xml.write("RunningTime", r->getRunningTimeS(true));
|
||||||
xml.write("Place", r->getPlaceS());
|
xml.write("Place", r->getPlaceS());
|
||||||
@ -1127,7 +1127,8 @@ void RestServer::lookup(oEvent &oe, const string &what, const multimap<string, s
|
|||||||
}
|
}
|
||||||
if ((r->getFinishTime() > 0 || r->getCard() != nullptr) &&
|
if ((r->getFinishTime() > 0 || r->getCard() != nullptr) &&
|
||||||
r->getCourse(false) &&
|
r->getCourse(false) &&
|
||||||
r->getStatusComputed() != StatusNoTiming) {
|
r->getStatusComputed() != StatusNoTiming &&
|
||||||
|
!r->noTiming()) {
|
||||||
auto &sd = r->getSplitTimes(false);
|
auto &sd = r->getSplitTimes(false);
|
||||||
vector<int> after;
|
vector<int> after;
|
||||||
r->getLegTimeAfter(after);
|
r->getLegTimeAfter(after);
|
||||||
|
|||||||
@ -2527,3 +2527,7 @@ Tjänstebeställningar (IOF XML) = Tjänstebeställningar (IOF XML)
|
|||||||
Tjänster (IOF XML) = Tjänster (IOF XML)
|
Tjänster (IOF XML) = Tjänster (IOF XML)
|
||||||
Flytta deltagare från överfulla grupper = Flytta deltagare från överfulla grupper
|
Flytta deltagare från överfulla grupper = Flytta deltagare från överfulla grupper
|
||||||
Lotta med startgrupper = Lotta med startgrupper
|
Lotta med startgrupper = Lotta med startgrupper
|
||||||
|
Startgrupp med id X tilldelad Y finns inte = Startgrupp med id X definierad för Y finns inte
|
||||||
|
Använd om möjligt samma dator som användes vid senaste importen = Använd om möjligt samma dator som användes vid senaste importen
|
||||||
|
Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen = Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen
|
||||||
|
Varning: Kunde inte hitta föregående version av tävlingen (X) = Varning: Kunde inte hitta föregående version av tävlingen (X)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user