diff --git a/fbw-a32nx/src/wasm/extra-backend/src/Example/ExampleModule.cpp b/fbw-a32nx/src/wasm/extra-backend/src/Example/ExampleModule.cpp index 7df6599e9b9d..44d0a611d325 100644 --- a/fbw-a32nx/src/wasm/extra-backend/src/Example/ExampleModule.cpp +++ b/fbw-a32nx/src/wasm/extra-backend/src/Example/ExampleModule.cpp @@ -4,6 +4,7 @@ #ifdef EXAMPLES #include +#include #include "logging.h" #include "ExampleModule.h" @@ -129,7 +130,7 @@ bool ExampleModule::initialize() { beaconLightSetEventPtr, UNITS.Bool, true, false, 0, 0); // Data definition variables - std::vector exampleDataDef = { + std::vector exampleDataDef = { {"LIGHT STROBE", 0, UNITS.Bool}, {"LIGHT WING", 0, UNITS.Bool}, {"ZULU TIME"}, @@ -167,35 +168,32 @@ bool ExampleModule::initialize() { bigClientDataPtr = dataManager->make_clientdataarea_var("BIG CLIENT DATA"); bigClientDataPtr->setSkipChangeCheck(true); - bigClientDataPtr->addCallback([=]() { + bigClientDataPtr->addCallback([&]() { // Big Client Data - LOG_INFO_BLOCK( - std::cout << "--- CALLBACK: BIG CLIENT DATA (External - reading)" << std::endl; - std::cout << bigClientDataPtr->str() << std::endl; - std::cout << "Bid Client Data data: " << std::endl; - auto s = std::string_view((const char*) &bigClientDataPtr->data().dataChunk, 100); - std::cout << bigClientDataPtr->data().dataChunk.size() << " bytes: " << s - << " ... " << std::endl; - ) + std::cout << "--- CALLBACK: BIG CLIENT DATA (External - reading)" << std::endl; + std::cout << bigClientDataPtr->str() << std::endl; + std::cout << "Bid Client Data data: " << std::endl; + auto s = std::string_view((const char*) &bigClientDataPtr->data().dataChunk, 100); + std::cout << bigClientDataPtr->data().dataChunk.size() << " bytes: " << s + << " ... " << std::endl; }); - if (!bigClientDataPtr->requestPeriodicDataFromSim(SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET)) { - LOG_ERROR("Failed to request periodic data from sim"); - } + // if (!bigClientDataPtr->requestPeriodicDataFromSim(SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET)) { + // LOG_ERROR("Failed to request periodic data from sim"); + // } // Metadata for the ClientDataBufferedAreaVariable test metaDataPtr = dataManager->make_clientdataarea_var("HUGE CLIENT DATA META DATA"); metaDataPtr->setSkipChangeCheck(true); - metaDataPtr->addCallback([=]() { + metaDataPtr->addCallback([&]() { + receiptTimerStart = std::chrono::high_resolution_clock::now(); hugeClientDataPtr->reserve(metaDataPtr->data().size); // Huge Client Data Meta Data - LOG_INFO_BLOCK( - std::cout << "--- CALLBACK: HUGE CLIENT META DATA (External - reading)" << std::endl; + std::cout << "--- CALLBACK: HUGE CLIENT META DATA (External - reading)" << std::endl; std::cout << metaDataPtr->str() << std::endl; std::cout << "HUGE CLIENT DATA META DATA size = " << metaDataPtr->data().size << " fingerprint = " << metaDataPtr->data().hash << std::endl; std::cout << std::endl; - ); }); if (!metaDataPtr->requestPeriodicDataFromSim(SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET)) { LOG_ERROR("Failed to request periodic data from sim"); @@ -205,17 +203,24 @@ bool ExampleModule::initialize() { hugeClientDataPtr = dataManager->make_clientdatabufferedarea_var("HUGE CLIENT DATA"); hugeClientDataPtr->setSkipChangeCheck(true); - hugeClientDataPtr->addCallback([=]() { - LOG_INFO_BLOCK( - std::cout << "--- CALLBACK: HUGE CLIENT DATA (External - reading)" << std::endl; + hugeClientDataPtr->addCallback([&]() { + receiptTimerEnd = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - receiptTimerStart); + std::cout << "--- CALLBACK: HUGE CLIENT DATA (External - reading)" << std::endl; std::cout << hugeClientDataPtr->str() << std::endl; const uint64_t fingerPrintFvn = fingerPrintFVN(hugeClientDataPtr->getData()); - std::cout << "HUGE CLIENT DATA size = " << hugeClientDataPtr->getData().size() - << " fingerprint = " << fingerPrintFvn - << " fingerprint match = " << std::boolalpha - << (fingerPrintFvn == metaDataPtr->data().hash) << std::endl; + std::cout << "HUGE CLIENT DATA " + << " size = " << hugeClientDataPtr->getData().size() + << " bytes = " << hugeClientDataPtr->getReceivedBytes() + << " chunks = " << hugeClientDataPtr->getReceivedChunks() + << " fingerprint = " << std::setw(21) << fingerPrintFvn + << " (match = " << std::boolalpha << (fingerPrintFvn == metaDataPtr->data().hash) << ")" + << " time = " << std::setw(10) << receiptTimerEnd.count() << " ns" << std::endl; + std::cout << "Content: " << "[" + << std::string(hugeClientDataPtr->getData().begin(), + hugeClientDataPtr->getData().begin() + hugeClientDataPtr->getReceivedBytes()) + << "]" << std::endl; std::cout << std::endl; - ) }); if (!SUCCEEDED(hugeClientDataPtr->requestPeriodicDataFromSim(SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET))) { LOG_ERROR("Failed to request periodic data from sim"); diff --git a/fbw-a32nx/src/wasm/extra-backend/src/Example/ExampleModule.h b/fbw-a32nx/src/wasm/extra-backend/src/Example/ExampleModule.h index 142e909c802a..d1071600ee4f 100644 --- a/fbw-a32nx/src/wasm/extra-backend/src/Example/ExampleModule.h +++ b/fbw-a32nx/src/wasm/extra-backend/src/Example/ExampleModule.h @@ -7,6 +7,7 @@ #define FLYBYWIRE_EXAMPLEMODULE_H #include +#include #include "Module.h" #include "DataManager.h" @@ -131,6 +132,8 @@ class ExampleModule : public Module { return hash; } + std::chrono::time_point> receiptTimerStart; + std::chrono::duration receiptTimerEnd; }; #endif //FLYBYWIRE_EXAMPLEMODULE_H diff --git a/fbw-common/src/wasm/extra-backend/MsfsHandler/DataManager/ClientDataBufferedAreaVariable.hpp b/fbw-common/src/wasm/extra-backend/MsfsHandler/DataManager/ClientDataBufferedAreaVariable.hpp index 566faacafbd6..15bbc7e0f98f 100644 --- a/fbw-common/src/wasm/extra-backend/MsfsHandler/DataManager/ClientDataBufferedAreaVariable.hpp +++ b/fbw-common/src/wasm/extra-backend/MsfsHandler/DataManager/ClientDataBufferedAreaVariable.hpp @@ -21,10 +21,13 @@ class ClientDataBufferedAreaVariable : public ClientDataAreaVariable { std::vector content; // the number of bytes expected to be received - set in reserve() - std::size_t expectedByteCount; + std::size_t expectedByteCount{}; // the number of bytes received so far - re-set in reserve() - std::size_t receivedBytes; + std::size_t receivedBytes{}; + + // the number of chunks received so far - re-set in reserve() + std::size_t receivedChunks{}; // hide incompatible methods // TODO: is this ok?? @@ -66,48 +69,44 @@ class ClientDataBufferedAreaVariable : public ClientDataAreaVariable { remainingBytes = ChunkSize; } - auto now = std::chrono::high_resolution_clock::now(); + // auto now = std::chrono::high_resolution_clock::now(); // memcpy into a vector ignores the vector's metadata and just copies the data // it is therefore faster than std::copy or std::back_inserter but std::memcpy(&this->content.data()[this->receivedBytes], &pClientData->dwData, remainingBytes); // std::copy(&pClientData->dwData, &pClientData->dwData + remainingBytes, std::back_inserter(this->content)); // this->content.insert(this->content.end(), &pClientData->dwData, &pClientData->dwData + remainingBytes); - auto duration = std::chrono::duration_cast( - std::chrono::high_resolution_clock::now() - now); - - LOG_DEBUG_BLOCK( - std::cout << "ClientDataBufferedAreaVariable DATA START========================" << std::endl; - auto d = &this->content.data()[this->receivedBytes]; - for (std::size_t i = 0; i < 50; i++) { // remainingBytes - auto c = BYTE(*(d + i)); - std::cout << c; - } - std::cout << std::endl; - std::cout << "ClientDataBufferedAreaVariable DATA END==========================" << std::endl; - ) + // auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - now); + + this->receivedChunks++; + + // DEBUG + // std::cout << "ClientDataBufferedAreaVariable DATA START========================" << std::endl; + // auto d = &this->content.data()[this->receivedBytes]; + // auto s = std::string_view((const char*) d, 100); + // std::cout << s << std::endl; + // std::cout << "ClientDataBufferedAreaVariable DATA END==========================" << std::endl; + // DEBUG this->receivedBytes += remainingBytes; const bool receivedAllData = this->receivedBytes >= this->expectedByteCount; if (receivedAllData) { - LOG_DEBUG_BLOCK( - std::cout << "ClientDataBufferedAreaVariable: Data fully received: " << this->name - << " (" << this->receivedBytes << "/" << this->expectedByteCount - << ") in " << duration.count() << " ns" << std::endl; - - ) - LOG_DEBUG("Content: " + std::string(this->content.begin(), this->content.end())); + // // DEBUG + // std::cout << "ClientDataBufferedAreaVariable: Data fully received: " << this->name + // << " (" << this->receivedBytes << "/" << this->expectedByteCount + // << ") in " << duration.count() << " ns" << std::endl; + // // DEBUG this->timeStampSimTime = simTime; this->tickStamp = tickCounter; this->setChanged(true); return; } - LOG_DEBUG_BLOCK( - std::cout << "ClientDataBufferedAreaVariable: Data chunk received: " << this->name - << " (" << this->receivedBytes << "/" << this->expectedByteCount - << ") in " << duration.count() << " ns" << std::endl; - ) + // // DEBUG + // std::cout << "ClientDataBufferedAreaVariable: Data chunk received: " << this->name + // << " (" << this->receivedBytes << "/" << this->expectedByteCount + // << ") in " << duration.count() << " ns" << std::endl; + // // DEBUG } /** @@ -116,12 +115,13 @@ class ClientDataBufferedAreaVariable : public ClientDataAreaVariable { * expected byte count. * @param _expectedByteCount Number of expected bytes in streaming cases */ - void reserve(std::size_t _expectedByteCount) { + void reserve(std::size_t expectedByteCnt) { this->setChanged(false); this->content.clear(); - this->content.reserve(_expectedByteCount); - this->expectedByteCount = _expectedByteCount; this->receivedBytes = 0; + this->receivedChunks = 0; + this->expectedByteCount = expectedByteCnt; + this->content.reserve(expectedByteCnt); } /** @@ -136,6 +136,18 @@ class ClientDataBufferedAreaVariable : public ClientDataAreaVariable { */ [[maybe_unused]] [[nodiscard]] const std::vector &getData() const { return content; } + /** + * Returns the number of bytes received so far + * @return std::size_t Number of bytes received so far + */ + [[nodiscard]] std::size_t getReceivedBytes() const { return receivedBytes; } + + /** + * Returns the number of chunks received so far + * @return std::size_t Number of chunks received so far + */ + [[nodiscard]] std::size_t getReceivedChunks() const { return receivedChunks; } + [[nodiscard]] std::string str() const override { std::stringstream ss; @@ -145,6 +157,7 @@ class ClientDataBufferedAreaVariable : public ClientDataAreaVariable { ss << ", requestId=" << this->requestId; ss << ", expectedByteCount=" << this->expectedByteCount; ss << ", receivedBytes=" << this->receivedBytes; + ss << ", receivedChunks=" << this->receivedChunks; ss << ", structSize=" << content.size() * sizeof(T); ss << ", timeStamp: " << this->timeStampSimTime; ss << ", tickStamp: " << this->tickStamp;