diff --git a/client/src/index.ts b/client/src/index.ts index 239100f9..c12734e8 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -99,17 +99,29 @@ function setup() { getUnits((data: UnitsData) => getUnitsManager()?.update(data), true /* Does a full refresh */); /* Start periodically requesting updates */ - requestUpdate(true /* Start looping */); + startPeriodicUpdate(); } -function requestUpdate(loop: boolean) { +function startPeriodicUpdate() +{ + requestUpdate(); + requestRefresh(); +} + +function requestUpdate() { /* Main update rate = 250ms is minimum time, equal to server update time. */ - getUnits((data: UnitsData) => getUnitsManager()?.update(data)) - setTimeout(() => requestUpdate(loop), getConnected() ? 250 : 1000); + getUnits((data: UnitsData) => getUnitsManager()?.update(data), false); + setTimeout(() => requestUpdate(), getConnected() ? 250 : 1000); getConnectionStatusPanel()?.update(getConnected()); } +function requestRefresh() { + /* Main refresh rate = 5000ms. */ + getUnits((data: UnitsData) => getUnitsManager()?.update(data), true); + setTimeout(() => requestUpdate(), 5000); +} + export function getMap() { return map; } diff --git a/client/src/server/server.ts b/client/src/server/server.ts index 46d27ed7..1456c127 100644 --- a/client/src/server/server.ts +++ b/client/src/server/server.ts @@ -1,7 +1,7 @@ import * as L from 'leaflet' import { setConnected } from '..'; -const DEMO = true; +const DEMO = false; /* Edit here to change server address */ const REST_ADDRESS = "http://localhost:30000/olympus"; @@ -18,9 +18,11 @@ export function GET(callback: CallableFunction, uri: string){ xmlHttp.onload = function (e) { var data = JSON.parse(xmlHttp.responseText); callback(data); + setConnected(true); }; xmlHttp.onerror = function () { console.error("An error occurred during the XMLHttpRequest"); + setConnected(false); }; xmlHttp.send(null); } @@ -29,7 +31,9 @@ export function POST(request: object, callback: CallableFunction){ var xhr = new XMLHttpRequest(); xhr.open("PUT", REST_ADDRESS); xhr.setRequestHeader("Content-Type", "application/json"); - xhr.onreadystatechange = () => { callback(); }; + xhr.onreadystatechange = () => { + callback(); + }; xhr.send(JSON.stringify(request)); } @@ -47,7 +51,7 @@ export function getLogs(callback: CallableFunction) { export function getUnits(callback: CallableFunction, refresh: boolean = false) { if (!DEMO) - GET(callback, `${UNITS_URI}/${refresh? REFRESH_URI: UPDATE_URI}}`); + GET(callback, `${UNITS_URI}/${refresh? REFRESH_URI: UPDATE_URI}`); else callback(refresh? generateRandomUnitsDemoData(100): {units:{}}); } diff --git a/client/src/units/unitsmanager.ts b/client/src/units/unitsmanager.ts index cd5eb90f..62004856 100644 --- a/client/src/units/unitsmanager.ts +++ b/client/src/units/unitsmanager.ts @@ -49,14 +49,14 @@ export class UnitsManager { .reduce((timeout: number, ID: string) => { setTimeout(() => { this.addUnit(parseInt(ID), data.units[ID]); - this.#units[parseInt(ID)].setData(data.units[ID]); + this.#units[parseInt(ID)]?.setData(data.units[ID]); }, timeout); return timeout + 10; }, 10); Object.keys(data.units) .filter((ID: string) => ID in this.#units) - .forEach((ID: string) => this.#units[parseInt(ID)].setData(data.units[ID])); + .forEach((ID: string) => this.#units[parseInt(ID)]?.setData(data.units[ID])); } forceUpdate() { diff --git a/scripts/OlympusMission.lua b/scripts/OlympusMission.lua index 0666baed..9e423bc4 100644 --- a/scripts/OlympusMission.lua +++ b/scripts/OlympusMission.lua @@ -11,13 +11,13 @@ function Olympus.setMissionData(arg, time) local missionData = {} -- Bullseye data - local bullseye = {} + local bullseyes = {} for i = 0, 2 do local bullseyeVec3 = coalition.getMainRefPoint(i) local bullseyeLatitude, bullseyeLongitude, bullseyeAltitude = coord.LOtoLL(bullseyeVec3) - bullseye[i] = {} - bullseye[i]["lat"] = bullseyeLatitude - bullseye[i]["lng"] = bullseyeLongitude + bullseyes[i] = {} + bullseyes[i]["lat"] = bullseyeLatitude + bullseyes[i]["lng"] = bullseyeLongitude end -- Units tactical data @@ -51,7 +51,7 @@ function Olympus.setMissionData(arg, time) end end end - if index == endIndex then + if index >= endIndex then break end end @@ -77,10 +77,8 @@ function Olympus.setMissionData(arg, time) basesData[i] = info end - - -- Assemble missionData table - missionData["bullseye"] = bullseye + missionData["bullseyes"] = bullseyes missionData["unitsData"] = unitsData missionData["airbases"] = basesData diff --git a/src/core/src/Unit.cpp b/src/core/src/Unit.cpp index f2849807..e0c2c022 100644 --- a/src/core/src/Unit.cpp +++ b/src/core/src/Unit.cpp @@ -83,16 +83,24 @@ json::value Unit::json(bool fullRefresh) { auto json = json::value::object(); + /********** Base data **********/ + json[L"AI"] = AI; + json[L"name"] = json::value::string(name); + json[L"unitName"] = json::value::string(unitName); + json[L"groupName"] = json::value::string(groupName); + json[L"alive"] = alive; + json[L"category"] = json::value::string(getCategory()); + + /********** Flight data **********/ + json[L"flightData"] = json::value::object(); + json[L"flightData"][L"latitude"] = latitude; + json[L"flightData"][L"longitude"] = longitude; + json[L"flightData"][L"altitude"] = altitude; + json[L"flightData"][L"speed"] = speed; + json[L"flightData"][L"heading"] = heading; + if (fullRefresh) { - /********** Base data **********/ - json[L"AI"] = AI; - json[L"name"] = json::value::string(name); - json[L"unitName"] = json::value::string(unitName); - json[L"groupName"] = json::value::string(groupName); - json[L"alive"] = alive; - json[L"category"] = json::value::string(getCategory()); - /********** Mission data **********/ json[L"missionData"] = json::value::object(); json[L"missionData"][L"fuel"] = fuel; @@ -145,14 +153,6 @@ json::value Unit::json(bool fullRefresh) json[L"optionsData"][L"reactionToThreat"] = json::value::string(reactionToThreat); } - /********** Flight data **********/ - json[L"flightData"] = json::value::object(); - json[L"flightData"][L"latitude"] = latitude; - json[L"flightData"][L"longitude"] = longitude; - json[L"flightData"][L"altitude"] = altitude; - json[L"flightData"][L"speed"] = speed; - json[L"flightData"][L"heading"] = heading; - return json; } diff --git a/src/core/src/core.cpp b/src/core/src/core.cpp index e9f2b1ce..7e9726a8 100644 --- a/src/core/src/core.cpp +++ b/src/core/src/core.cpp @@ -12,7 +12,7 @@ UnitsManager* unitsManager = nullptr; Server* server = nullptr; Scheduler* scheduler = nullptr; json::value airbasesData; -json::value bullseyeData; +json::value bullseyesData; mutex mutexLock; bool initialized = false; @@ -91,7 +91,7 @@ extern "C" DllExport int coreMissionData(lua_State * L) if (missionData.has_object_field(L"airbases")) airbasesData = missionData[L"airbases"]; if (missionData.has_object_field(L"bullseye")) - bullseyeData = missionData[L"bullseye"]; + bullseyesData = missionData[L"bullseyes"]; return(0); } diff --git a/src/core/src/server.cpp b/src/core/src/server.cpp index f4d77970..b7ef7c57 100644 --- a/src/core/src/server.cpp +++ b/src/core/src/server.cpp @@ -10,7 +10,7 @@ extern UnitsManager* unitsManager; extern Scheduler* scheduler; extern json::value airbasesData; -extern json::value bullseyeData; +extern json::value bullseyesData; extern mutex mutexLock; void handle_eptr(std::exception_ptr eptr) @@ -71,28 +71,29 @@ void Server::handle_get(http_request request) std::exception_ptr eptr; try { auto answer = json::value::object(); - wstring requestUri = request.request_uri().to_string(); - log(requestUri); - if (requestUri.compare(L"/" + wstring(REST_URI) + L"/" + wstring(UNITS_URI) + L"/" + wstring(PARTIAL_REFRESH_URI)) == 0) - unitsManager->updateAnswer(answer, false); + auto path = uri::split_path(uri::decode(request.relative_uri().path())); - if (requestUri.compare(L"/" + wstring(REST_URI) + L"/" + wstring(UNITS_URI) + L"/" + wstring(FULL_REFRESH_URI)) == 0) - unitsManager->updateAnswer(answer, true); - - /* Get the logs from the logger */ - if (requestUri.compare(L"/" + wstring(REST_URI) + L"/" + wstring(LOGS_URI)) == 0) + if (path.size() > 0) { - auto logs = json::value::object(); - getLogsJSON(logs); // By reference, for thread safety - answer[L"logs"] = logs; + if (path[0] == UNITS_URI && path.size() > 1) + { + if (path[1] == UPDATE_URI) + unitsManager->updateAnswer(answer, false); + else if (path[1] == REFRESH_URI) + unitsManager->updateAnswer(answer, true); + + } + else if (path[0] == LOGS_URI) + { + auto logs = json::value::object(); + getLogsJSON(logs, 100); // By reference, for thread safety. Get the last 100 log entries + answer[L"logs"] = logs; + } + else if (path[0] == AIRBASES_URI) + answer[L"airbases"] = airbasesData; + else if (path[0] == BULLSEYE_URI) + answer[L"bullseyes"] = bullseyesData; } - - if (requestUri.compare(L"/" + wstring(REST_URI) + L"/" + wstring(AIRBASES_URI)) == 0) - answer[L"airbases"] = airbasesData; - - if (requestUri.compare(L"/" + wstring(REST_URI) + L"/" + wstring(BULLSEYE_URI)) == 0) - answer[L"bullseye"] = bullseyeData; - response.set_body(answer); } catch (...) { diff --git a/src/logger/include/interface.h b/src/logger/include/interface.h index 61991864..f5dbe800 100644 --- a/src/logger/include/interface.h +++ b/src/logger/include/interface.h @@ -3,4 +3,4 @@ void DllExport log(const std::string& sMessage); void DllExport log(const std::wstring& sMessage); -void DllExport getLogsJSON(json::value& json); +void DllExport getLogsJSON(json::value& json, int logsNumber = NULL); diff --git a/src/logger/include/logger.h b/src/logger/include/logger.h index c546879a..20e17d71 100644 --- a/src/logger/include/logger.h +++ b/src/logger/include/logger.h @@ -7,7 +7,7 @@ class Logger public: void log(const string& sMessage); void log(const wstring& sMessage); - void toJSON(json::value& json); + void toJSON(json::value& json, int logsNumber = NULL); static Logger* GetLogger(); diff --git a/src/logger/src/interface.cpp b/src/logger/src/interface.cpp index cab8b3da..77c743b5 100644 --- a/src/logger/src/interface.cpp +++ b/src/logger/src/interface.cpp @@ -14,7 +14,7 @@ void log(const wstring& message) LOGGER->log(message); } -void getLogsJSON(json::value& json) +void getLogsJSON(json::value& json, int logsNumber) { - LOGGER->toJSON(json); + LOGGER->toJSON(json, logsNumber); } \ No newline at end of file diff --git a/src/logger/src/logger.cpp b/src/logger/src/logger.cpp index 8fdab6d4..4c9810d3 100644 --- a/src/logger/src/logger.cpp +++ b/src/logger/src/logger.cpp @@ -32,12 +32,16 @@ void Logger::Close() m_Logfile.close(); } -void Logger::toJSON(json::value& json) +void Logger::toJSON(json::value& json, int logsNumber) { lock_guard guard(mutexLock); int i = 0; - for (auto log : m_logs) - json[to_wstring(i++)] = json::value::string(to_wstring(log)); + for (auto itr = m_logs.end(); itr != m_logs.begin(); --itr) + { + json[to_wstring(m_logs.size() - 1 - i)] = json::value::string(to_wstring(*itr)); + if (logsNumber != 0 && i > logsNumber) + break; + } } void Logger::log(const string& message) diff --git a/src/shared/include/defines.h b/src/shared/include/defines.h index 6a214075..215a5d8b 100644 --- a/src/shared/include/defines.h +++ b/src/shared/include/defines.h @@ -5,10 +5,10 @@ #define REST_ADDRESS L"http://localhost:30000" #define REST_URI L"olympus" #define UNITS_URI L"units" -#define PARTIAL_REFRESH_URI L"partial" -#define FULL_REFRESH_URI L"full" +#define UPDATE_URI L"update" +#define REFRESH_URI L"refresh" #define LOGS_URI L"logs" #define AIRBASES_URI L"airbases" -#define BULLSEYE_URI L"bullseye" +#define BULLSEYE_URI L"bullseyes" #define UPDATE_TIME_INTERVAL 0.25 \ No newline at end of file