diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index fe90f149..13d7685b 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -22,7 +22,7 @@ export class Unit extends CustomMarker { #alive: boolean = false; #human: boolean = false; #controlled: boolean = false; - #coalition: string = ""; + #coalition: string = "neutral"; #country: number = 0; #name: string = ""; #unitName: string = ""; @@ -30,7 +30,7 @@ export class Unit extends CustomMarker { #state: string = states[0]; #task: string = "" #hasTask: boolean = false; - #position: LatLng = new LatLng(0, 0); + #position: LatLng = new LatLng(0, 0, 0); #speed: number = 0; #heading: number = 0; #isTanker: boolean = false; @@ -50,13 +50,13 @@ export class Unit extends CustomMarker { }; #targetID: number = 0; #targetPosition: LatLng = new LatLng(0, 0); - #ROE: string = ROEs[0]; - #reactionToThreat: string = reactionsToThreat[0]; - #emissionsCountermeasures: string = emissionsCountermeasures[0]; + #ROE: string = ROEs[1]; + #reactionToThreat: string = reactionsToThreat[2]; + #emissionsCountermeasures: string = emissionsCountermeasures[2]; #TACAN: TACAN = { isOn: false, XY: 'X', - callsign: '', + callsign: 'TKR', channel: 0 }; #radio: Radio = { @@ -135,50 +135,50 @@ export class Unit extends CustomMarker { setData(dataExtractor: DataExtractor) { var updateMarker = !getMap().hasLayer(this); - var datumIndex = dataExtractor.extractUInt8(); - if (datumIndex == DataIndexes.startOfData) { - while (datumIndex != DataIndexes.endOfData) { - datumIndex = dataExtractor.extractUInt8(); - switch (datumIndex) { - case DataIndexes.alive: this.setAlive(dataExtractor.extractBool()); updateMarker = true; break; - case DataIndexes.human: this.#human = dataExtractor.extractBool(); break; - case DataIndexes.controlled: this.#controlled = dataExtractor.extractBool(); updateMarker = true; break; - case DataIndexes.coalition: this.#coalition = enumToCoalition(dataExtractor.extractUInt8()); break; - case DataIndexes.country: this.#country = dataExtractor.extractUInt8(); break; - case DataIndexes.name: this.#name = dataExtractor.extractString(); break; - case DataIndexes.unitName: this.#unitName = dataExtractor.extractString(); break; - case DataIndexes.groupName: this.#groupName = dataExtractor.extractString(); break; - case DataIndexes.state: this.#state = enumToState(dataExtractor.extractUInt8()); updateMarker = true; break; - case DataIndexes.task: this.#task = dataExtractor.extractString(); break; - case DataIndexes.hasTask: this.#hasTask = dataExtractor.extractBool(); break; - case DataIndexes.position: this.#position = dataExtractor.extractLatLng(); updateMarker = true; break; - case DataIndexes.speed: this.#speed = dataExtractor.extractFloat64(); updateMarker = true; break; - case DataIndexes.heading: this.#heading = dataExtractor.extractFloat64(); updateMarker = true; break; - case DataIndexes.isTanker: this.#isTanker = dataExtractor.extractBool(); break; - case DataIndexes.isAWACS: this.#isAWACS = dataExtractor.extractBool(); break; - case DataIndexes.onOff: this.#onOff = dataExtractor.extractBool(); break; - case DataIndexes.followRoads: this.#followRoads = dataExtractor.extractBool(); break; - case DataIndexes.fuel: this.#fuel = dataExtractor.extractUInt16(); break; - case DataIndexes.desiredSpeed: this.#desiredSpeed = dataExtractor.extractFloat64(); break; - case DataIndexes.desiredSpeedType: this.#desiredSpeedType = dataExtractor.extractBool() ? "GS" : "CAS"; break; - case DataIndexes.desiredAltitude: this.#desiredAltitude = dataExtractor.extractFloat64(); break; - case DataIndexes.desiredAltitudeType: this.#desiredAltitudeType = dataExtractor.extractFloat64() ? "AGL" : "ASL"; break; - case DataIndexes.leaderID: this.#leaderID = dataExtractor.extractUInt32(); break; - case DataIndexes.formationOffset: dataExtractor.extractOffset(); break; - case DataIndexes.targetID: this.#targetID = dataExtractor.extractUInt32(); break; - case DataIndexes.targetPosition: this.#targetPosition = dataExtractor.extractLatLng(); break; - case DataIndexes.ROE: this.#ROE = enumToROE(dataExtractor.extractUInt8()); break; - case DataIndexes.reactionToThreat: this.#reactionToThreat = enumToReactionToThreat(dataExtractor.extractUInt8()); break; - case DataIndexes.emissionsCountermeasures: this.#emissionsCountermeasures = enumToEmissioNCountermeasure(dataExtractor.extractUInt8()); break; - case DataIndexes.TACAN: this.#TACAN = dataExtractor.extractTACAN(); break; - case DataIndexes.radio: this.#radio = dataExtractor.extractRadio(); break; - case DataIndexes.generalSettings: this.#generalSettings = dataExtractor.extractGeneralSettings(); break; - case DataIndexes.ammo: this.#ammo = dataExtractor.extractAmmo(); break; - case DataIndexes.contacts: this.#contacts = dataExtractor.extractContacts(); break; - case DataIndexes.activePath: this.#activePath = dataExtractor.extractActivePath(); break; - } + var datumIndex = 0; + while (datumIndex != DataIndexes.endOfData) { + datumIndex = dataExtractor.extractUInt8(); + switch (datumIndex) { + case DataIndexes.category: dataExtractor.extractString(); break; + case DataIndexes.alive: this.setAlive(dataExtractor.extractBool()); updateMarker = true; break; + case DataIndexes.human: this.#human = dataExtractor.extractBool(); break; + case DataIndexes.controlled: this.#controlled = dataExtractor.extractBool(); updateMarker = true; break; + case DataIndexes.coalition: this.#coalition = enumToCoalition(dataExtractor.extractUInt8()); break; + case DataIndexes.country: this.#country = dataExtractor.extractUInt8(); break; + case DataIndexes.name: this.#name = dataExtractor.extractString(); break; + case DataIndexes.unitName: this.#unitName = dataExtractor.extractString(); break; + case DataIndexes.groupName: this.#groupName = dataExtractor.extractString(); break; + case DataIndexes.state: this.#state = enumToState(dataExtractor.extractUInt8()); updateMarker = true; break; + case DataIndexes.task: this.#task = dataExtractor.extractString(); break; + case DataIndexes.hasTask: this.#hasTask = dataExtractor.extractBool(); break; + case DataIndexes.position: this.#position = dataExtractor.extractLatLng(); updateMarker = true; break; + case DataIndexes.speed: this.#speed = dataExtractor.extractFloat64(); updateMarker = true; break; + case DataIndexes.heading: this.#heading = dataExtractor.extractFloat64(); updateMarker = true; break; + case DataIndexes.isTanker: this.#isTanker = dataExtractor.extractBool(); break; + case DataIndexes.isAWACS: this.#isAWACS = dataExtractor.extractBool(); break; + case DataIndexes.onOff: this.#onOff = dataExtractor.extractBool(); break; + case DataIndexes.followRoads: this.#followRoads = dataExtractor.extractBool(); break; + case DataIndexes.fuel: this.#fuel = dataExtractor.extractUInt16(); break; + case DataIndexes.desiredSpeed: this.#desiredSpeed = dataExtractor.extractFloat64(); break; + case DataIndexes.desiredSpeedType: this.#desiredSpeedType = dataExtractor.extractBool() ? "GS" : "CAS"; break; + case DataIndexes.desiredAltitude: this.#desiredAltitude = dataExtractor.extractFloat64(); break; + case DataIndexes.desiredAltitudeType: this.#desiredAltitudeType = dataExtractor.extractFloat64() ? "AGL" : "ASL"; break; + case DataIndexes.leaderID: this.#leaderID = dataExtractor.extractUInt32(); break; + case DataIndexes.formationOffset: this.#formationOffset = dataExtractor.extractOffset(); break; + case DataIndexes.targetID: this.#targetID = dataExtractor.extractUInt32(); break; + case DataIndexes.targetPosition: this.#targetPosition = dataExtractor.extractLatLng(); break; + case DataIndexes.ROE: this.#ROE = enumToROE(dataExtractor.extractUInt8()); break; + case DataIndexes.reactionToThreat: this.#reactionToThreat = enumToReactionToThreat(dataExtractor.extractUInt8()); break; + case DataIndexes.emissionsCountermeasures: this.#emissionsCountermeasures = enumToEmissioNCountermeasure(dataExtractor.extractUInt8()); break; + case DataIndexes.TACAN: this.#TACAN = dataExtractor.extractTACAN(); break; + case DataIndexes.radio: this.#radio = dataExtractor.extractRadio(); break; + case DataIndexes.generalSettings: this.#generalSettings = dataExtractor.extractGeneralSettings(); break; + case DataIndexes.ammo: this.#ammo = dataExtractor.extractAmmo(); break; + case DataIndexes.contacts: this.#contacts = dataExtractor.extractContacts(); break; + case DataIndexes.activePath: this.#activePath = dataExtractor.extractActivePath(); break; } } + /* Dead units can't be selected */ this.setSelected(this.getSelected() && this.#alive && !this.getHidden()) diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index 4759cb4f..2b70e07f 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -36,6 +36,7 @@ + @@ -52,6 +53,7 @@ + diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index 00e7a412..50797e65 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -48,6 +48,9 @@ Header Files + + Header Files + @@ -92,5 +95,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/src/core/include/datatypes.h b/src/core/include/datatypes.h new file mode 100644 index 00000000..14eb91b8 --- /dev/null +++ b/src/core/include/datatypes.h @@ -0,0 +1,49 @@ +#pragma once +#include "framework.h" + +#pragma pack(push, 1) +namespace DataTypes { + struct TACAN + { + bool isOn = false; + unsigned char channel = 40; + char XY = 'X'; + char callsign[4]; + }; + + struct Radio + { + unsigned int frequency = 124000000; // MHz + unsigned char callsign = 1; + unsigned char callsignNumber = 1; + }; + + struct GeneralSettings + { + bool prohibitJettison = false; + bool prohibitAA = false; + bool prohibitAG = false; + bool prohibitAfterburner = false; + bool prohibitAirWpn = false; + }; + + struct Ammo { + unsigned short quantity = 0; + char name[33]; + unsigned char guidance = 0; + unsigned char category = 0; + unsigned char missileCategory = 0; + }; + + struct Contact { + unsigned int ID = 0; + unsigned char detectionMethod = 0; + }; +} +#pragma pack(pop) + +bool operator==(const DataTypes::TACAN& lhs, const DataTypes::TACAN& rhs); +bool operator==(const DataTypes::Radio& lhs, const DataTypes::Radio& rhs); +bool operator==(const DataTypes::GeneralSettings& lhs, const DataTypes::GeneralSettings& rhs); +bool operator==(const DataTypes::Ammo& lhs, const DataTypes::Ammo& rhs); +bool operator==(const DataTypes::Contact& lhs, const DataTypes::Contact& rhs); diff --git a/src/core/include/unit.h b/src/core/include/unit.h index c9670358..fa973d5b 100644 --- a/src/core/include/unit.h +++ b/src/core/include/unit.h @@ -6,6 +6,7 @@ #include "measure.h" #include "logger.h" #include "commands.h" +#include "datatypes.h" #include using namespace std::chrono; @@ -76,47 +77,6 @@ namespace State }; }; -#pragma pack(push, 1) -namespace DataTypes { - struct TACAN - { - bool isOn = false; - unsigned char channel = 40; - char XY = 'X'; - char callsign[4]; - }; - - struct Radio - { - unsigned int frequency = 124000000; // MHz - unsigned char callsign = 1; - unsigned char callsignNumber = 1; - }; - - struct GeneralSettings - { - bool prohibitJettison = false; - bool prohibitAA = false; - bool prohibitAG = false; - bool prohibitAfterburner = false; - bool prohibitAirWpn = false; - }; - - struct Ammo { - unsigned short quantity = 0; - char name[32]; - unsigned char guidance = 0; - unsigned char category = 0; - unsigned char missileCategory = 0; - }; - - struct Contact { - unsigned int ID = 0; - unsigned char detectionMethod = 0; - }; -} -#pragma pack(pop) - class Unit { public: @@ -168,7 +128,7 @@ public: virtual void setHuman(bool newValue) { updateValue(human, newValue, DataIndex::human); } virtual void setControlled(bool newValue) { updateValue(controlled, newValue, DataIndex::controlled); } virtual void setCoalition(unsigned char newValue) { updateValue(coalition, newValue, DataIndex::coalition); } - virtual void setCountry(unsigned int newValue) { updateValue(country, newValue, DataIndex::country); } + virtual void setCountry(unsigned char newValue) { updateValue(country, newValue, DataIndex::country); } virtual void setName(string newValue) { updateValue(name, newValue, DataIndex::name); } virtual void setUnitName(string newValue) { updateValue(unitName, newValue, DataIndex::unitName); } virtual void setGroupName(string newValue) { updateValue(groupName, newValue, DataIndex::groupName); } @@ -197,8 +157,8 @@ public: virtual void setTACAN(DataTypes::TACAN newValue, bool force = false); virtual void setRadio(DataTypes::Radio newValue, bool force = false); virtual void setGeneralSettings(DataTypes::GeneralSettings newValue, bool force = false); - virtual void setAmmo(vector newAmmo) { ammo = newAmmo; } - virtual void setContacts(vector newContacts) { contacts = newContacts; } + virtual void setAmmo(vector newValue) { updateValue(ammo, newValue, DataIndex::ammo); } + virtual void setContacts(vector newValue) { updateValue(contacts, newValue, DataIndex::contacts); } virtual void setActivePath(list newValue); /********** Getters **********/ @@ -207,7 +167,7 @@ public: virtual bool getHuman() { return human; } virtual bool getControlled() { return controlled; } virtual unsigned int getCoalition() { return coalition; } - virtual unsigned int getCountry() { return country; } + virtual unsigned char getCountry() { return country; } virtual string getName() { return name; } virtual string getUnitName() { return unitName; } virtual string getGroupName() { return groupName; } @@ -244,14 +204,14 @@ protected: unsigned int ID; string category; - bool alive = true; + bool alive = false; bool human = false; bool controlled = false; - unsigned char coalition; - unsigned int country = NULL; - string name = "undefined"; - string unitName = "undefined"; - string groupName = "undefined"; + unsigned char coalition = NULL; + unsigned char country = NULL; + string name = ""; + string unitName = ""; + string groupName = ""; unsigned char state = State::NONE; string task = ""; bool hasTask = false; @@ -260,7 +220,7 @@ protected: double heading = NULL; bool isTanker = false; bool isAWACS = false; - bool onOff = true; + bool onOff = false; bool followRoads = false; unsigned short fuel = 0; double desiredSpeed = 0; @@ -329,7 +289,7 @@ protected: ss.write((const char*)&datumIndex, sizeof(unsigned char)); ss.write((const char*)&size, sizeof(unsigned short)); - for (auto el: datumValue) + for (auto& el: datumValue) ss.write((const char*)&el, sizeof(T)); } }; diff --git a/src/core/src/core.cpp b/src/core/src/core.cpp index 9dcc5a4b..b2e7263d 100644 --- a/src/core/src/core.cpp +++ b/src/core/src/core.cpp @@ -105,18 +105,27 @@ extern "C" DllExport int coreMissionData(lua_State * L) /* Lock for thread safety */ lock_guard guard(mutexLock); - lua_getglobal(L, "Olympus"); - lua_getfield(L, -1, "missionData"); - json::value missionData = luaTableToJSON(L, -1); + try + { + lua_getglobal(L, "Olympus"); + lua_getfield(L, -1, "missionData"); + json::value missionData = luaTableToJSON(L, -1); - if (missionData.has_object_field(L"unitsData")) - unitsManager->updateMissionData(missionData[L"unitsData"]); - if (missionData.has_object_field(L"airbases")) - airbases = missionData[L"airbases"]; - if (missionData.has_object_field(L"bullseyes")) - bullseyes = missionData[L"bullseyes"]; - if (missionData.has_object_field(L"mission")) - mission = missionData[L"mission"]; + if (missionData.has_object_field(L"unitsData")) + unitsManager->updateMissionData(missionData[L"unitsData"]); + if (missionData.has_object_field(L"airbases")) + airbases = missionData[L"airbases"]; + if (missionData.has_object_field(L"bullseyes")) + bullseyes = missionData[L"bullseyes"]; + if (missionData.has_object_field(L"mission")) + mission = missionData[L"mission"]; + } + catch (exception const& e) + { + log(e.what()); + } + + return(0); } diff --git a/src/core/src/datatypes.cpp b/src/core/src/datatypes.cpp new file mode 100644 index 00000000..eb0c52cd --- /dev/null +++ b/src/core/src/datatypes.cpp @@ -0,0 +1,30 @@ +#include "datatypes.h" + +bool operator==(const DataTypes::TACAN& lhs, const DataTypes::TACAN& rhs) +{ + return lhs.isOn == rhs.isOn && lhs.channel == rhs.channel && lhs.XY == rhs.XY && strcmp(lhs.callsign, rhs.callsign) == 0; +} + +bool operator==(const DataTypes::Radio& lhs, const DataTypes::Radio& rhs) +{ + return lhs.frequency == rhs.frequency && lhs.callsign == rhs.callsign && lhs.callsignNumber == rhs.callsignNumber; +} + +bool operator==(const DataTypes::GeneralSettings& lhs, const DataTypes::GeneralSettings& rhs) +{ + return lhs.prohibitAA == rhs.prohibitAA && lhs.prohibitAfterburner == rhs.prohibitAfterburner && lhs.prohibitAG == rhs.prohibitAG && + lhs.prohibitAirWpn == rhs.prohibitAirWpn && lhs.prohibitJettison == rhs.prohibitJettison; +} + +bool operator==(const DataTypes::Ammo& lhs, const DataTypes::Ammo& rhs) +{ + return lhs.category == rhs.category && lhs.guidance == rhs.guidance && lhs.missileCategory == rhs.missileCategory && + lhs.quantity == rhs.quantity && strcmp(lhs.name, rhs.name) == 0; +} + +bool operator==(const DataTypes::Contact& lhs, const DataTypes::Contact& rhs) +{ + return lhs.detectionMethod == rhs.detectionMethod && lhs.ID == rhs.ID; +} + + diff --git a/src/core/src/unit.cpp b/src/core/src/unit.cpp index 18748335..5d3788de 100644 --- a/src/core/src/unit.cpp +++ b/src/core/src/unit.cpp @@ -15,23 +15,6 @@ using namespace GeographicLib; extern Scheduler* scheduler; extern UnitsManager* unitsManager; -// TODO: Make dedicated file -bool operator==(const DataTypes::TACAN& lhs, const DataTypes::TACAN& rhs) -{ - return lhs.isOn == rhs.isOn && lhs.channel == rhs.channel && lhs.XY == rhs.XY && lhs.callsign == rhs.callsign; -} - -bool operator==(const DataTypes::Radio& lhs, const DataTypes::Radio& rhs) -{ - return lhs.frequency == rhs.frequency && lhs.callsign == rhs.callsign && lhs.callsignNumber == rhs.callsignNumber; -} - -bool operator==(const DataTypes::GeneralSettings& lhs, const DataTypes::GeneralSettings& rhs) -{ - return lhs.prohibitAA == rhs.prohibitAA && lhs.prohibitAfterburner == rhs.prohibitAfterburner && lhs.prohibitAG == rhs.prohibitAG && - lhs.prohibitAirWpn == rhs.prohibitAirWpn && lhs.prohibitJettison == rhs.prohibitJettison; -} - Unit::Unit(json::value json, unsigned int ID) : ID(ID) { @@ -138,42 +121,51 @@ void Unit::updateExportData(json::value json, double dt) void Unit::updateMissionData(json::value json) { - //if (json.has_number_field(L"fuel")) - // setFuel(short(json[L"fuel"].as_number().to_double() * 100)); - // - //if (json.has_object_field(L"ammo")) { - // vector ammo; - // for (auto const& el : json[L"ammo"].as_object()) { - // DataTypes::Ammo ammoItem; - // auto ammoJson = el.second; - // ammoItem.quantity = ammoJson[L"count"].as_number().to_uint32(); - // ammoItem.name = to_string(ammoJson[L"desc"][L"displayName"]); - // ammoItem.guidance = ammoJson[L"desc"][L"guidance"].as_number().to_uint32(); - // ammoItem.category = ammoJson[L"desc"][L"category"].as_number().to_uint32(); - // ammoItem.missileCategory = ammoJson[L"desc"][L"missileCategory"].as_number().to_uint32(); - // ammo.push_back(ammoItem); - // } - // setAmmo(ammo); - //} - // - //if (json.has_object_field(L"contacts")) { - // vector contacts; - // for (auto const& el : json[L"ammo"].as_object()) { - // DataTypes::Contact contactItem; - // auto contactJson = el.second; - // contactItem.ID = contactJson[L"object"][L"id_"].as_number().to_uint32(); - // - // string detectionMethod = to_string(contactJson[L"detectionMethod"]); - // if (detectionMethod.compare("VISUAL")) contactItem.detectionMethod = 1; - // else if (detectionMethod.compare("OPTIC")) contactItem.detectionMethod = 2; - // else if (detectionMethod.compare("RADAR")) contactItem.detectionMethod = 4; - // else if (detectionMethod.compare("IRST")) contactItem.detectionMethod = 8; - // else if (detectionMethod.compare("RWR")) contactItem.detectionMethod = 16; - // else if (detectionMethod.compare("DLINK")) contactItem.detectionMethod = 32; - // contacts.push_back(contactItem); - // } - // setContacts(contacts); - //} + if (json.has_number_field(L"fuel")) { + setFuel(short(json[L"fuel"].as_number().to_double() * 100)); + } + + if (json.has_object_field(L"ammo")) { + vector ammo; + for (auto const& el : json[L"ammo"].as_object()) { + log(el.second.serialize()); + DataTypes::Ammo ammoItem; + auto ammoJson = el.second; + ammoItem.quantity = ammoJson[L"count"].as_number().to_uint32(); + string name = to_string(ammoJson[L"desc"][L"displayName"].as_string()).substr(0, sizeof(ammoItem.name) - 1); + strcpy_s(ammoItem.name, sizeof(ammoItem.name), name.c_str()); + + if (ammoJson[L"desc"].has_number_field(L"guidance")) + ammoItem.guidance = ammoJson[L"desc"][L"guidance"].as_number().to_uint32(); + + if (ammoJson[L"desc"].has_number_field(L"category")) + ammoItem.category = ammoJson[L"desc"][L"category"].as_number().to_uint32(); + + if (ammoJson[L"desc"].has_number_field(L"missileCategory")) + ammoItem.missileCategory = ammoJson[L"desc"][L"missileCategory"].as_number().to_uint32(); + ammo.push_back(ammoItem); + } + setAmmo(ammo); + } + + if (json.has_object_field(L"contacts")) { + vector contacts; + for (auto const& el : json[L"contacts"].as_object()) { + DataTypes::Contact contactItem; + auto contactJson = el.second; + contactItem.ID = contactJson[L"object"][L"id_"].as_number().to_uint32(); + + string detectionMethod = to_string(contactJson[L"detectionMethod"]); + if (detectionMethod.compare("VISUAL")) contactItem.detectionMethod = 1; + else if (detectionMethod.compare("OPTIC")) contactItem.detectionMethod = 2; + else if (detectionMethod.compare("RADAR")) contactItem.detectionMethod = 4; + else if (detectionMethod.compare("IRST")) contactItem.detectionMethod = 8; + else if (detectionMethod.compare("RWR")) contactItem.detectionMethod = 16; + else if (detectionMethod.compare("DLINK")) contactItem.detectionMethod = 32; + contacts.push_back(contactItem); + } + setContacts(contacts); + } if (json.has_boolean_field(L"hasTask")) setHasTask(json[L"hasTask"].as_bool()); @@ -191,11 +183,9 @@ void Unit::getData(stringstream& ss, unsigned long long time, bool refresh) // p->heading = heading; //} - const unsigned char startOfData = DataIndex::startOfData; const unsigned char endOfData = DataIndex::endOfData; ss.write((const char*)&ID, sizeof(ID)); - ss.write((const char*)&startOfData, sizeof(startOfData)); for (auto d : updateTimeMap) { if (d.second > time) { switch (d.first) {