From a5b14d100d8a6c33c03c1f1121a5930f7742186a Mon Sep 17 00:00:00 2001 From: Wei Shuai Date: Mon, 2 May 2022 14:02:17 +0800 Subject: [PATCH 1/4] reduce ReadSimVars() count to improve performance 1. use std::list instead of std::vector, for circular iteration 2. list max 5 SimVars reading in very frame 3. VimVars clean() needs update list iterator --- src/Sources/Code/Module.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Sources/Code/Module.cpp b/src/Sources/Code/Module.cpp index 3d3ec59..e301671 100644 --- a/src/Sources/Code/Module.cpp +++ b/src/Sources/Code/Module.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -53,11 +54,14 @@ struct Client { SIMCONNECT_CLIENT_DATA_ID DataAreaIDCommand; SIMCONNECT_CLIENT_DATA_DEFINITION_ID DataDefinitionIDStringResponse; SIMCONNECT_CLIENT_DATA_DEFINITION_ID DataDefinitionIDStringCommand; - std::vector SimVars; + std::list SimVars; SIMCONNECT_CLIENT_DATA_DEFINITION_ID DataDefinitionIdSimVarsStart; // This is an optimization to be able to re-use already defined data definition IDs & request IDs // after resetting registered SimVars uint16_t MaxClientDataDefinition = 0; + // Runtime Rolling CLient Data reading Index + std::list::iterator RollingClientDataReadIndex; + }; // The list of currently registered clients @@ -230,7 +234,7 @@ void WriteSimVar(SimVar& simVar, Client* client) { // Register a single SimVar and send the current value to SimConnect Clients void RegisterSimVar(const std::string code, Client* client) { - std::vector* SimVars = &(client->SimVars); + std::list* SimVars = &(client->SimVars); SimVar var1; var1.Name = code; var1.ID = SimVars->size() + client->DataDefinitionIdSimVarsStart; @@ -250,6 +254,7 @@ void RegisterSimVar(const std::string code, Client* client) { ); client->MaxClientDataDefinition = SimVars->size(); + client->RollingClientDataReadIndex = SimVars->begin(); } #if _DEBUG fprintf(stderr, "MobiFlight[%s]: RegisterSimVar SimVars Size: %d\n", client->Name.c_str(), SimVars->size()); @@ -272,6 +277,7 @@ void RegisterSimVar(const std::string code, Client* client) { void ClearSimVars(Client* client) { client->SimVars.clear(); fprintf(stderr, "MobiFlight: Cleared SimVar tracking."); + client->RollingClientDataReadIndex = client->SimVars.begin(); } // Read a single SimVar and send the current value to SimConnect Clients @@ -292,9 +298,15 @@ void ReadSimVar(SimVar &simVar, Client* client) { // Read all dynamically registered SimVars void ReadSimVars() { for (auto& client : RegisteredClients) { - std::vector* SimVars = &(client->SimVars); - for (auto& value : *SimVars) { - ReadSimVar(value, client); + std::list* SimVars = &(client->SimVars); + //circular list, Max 5 SimVars at once + for (int i=0; i < 5; ++i) { + std:advance(client->RollingClientDataReadIndex, 1); + if(client->RollingClientDataReadIndex == SimVars->end()){ + client->RollingClientDataReadIndex = SimVars->begin(); + } + + ReadSimVar(*(client->RollingClientDataReadIndex), client); } } } @@ -378,7 +390,7 @@ Client* RegisterNewClient(const std::string clientName) { newClient->DataAreaNameCommand = newClient->Name + std::string(CLIENT_DATA_NAME_POSTFIX_COMMAND); newClient->DataDefinitionIDStringResponse = 2 * newClient->ID; // 500 Clients possible until offset 1000 is reached newClient->DataDefinitionIDStringCommand = newClient->DataDefinitionIDStringResponse + 1; - newClient->SimVars = std::vector(); + newClient->SimVars = std::list(); newClient->DataDefinitionIdSimVarsStart = SimVarOffset + (newClient->ID * ClientDataDefinitionIdSimVarsRange); RegisteredClients.push_back(newClient); From fc0cbb56056248889a5987a7f5655df97a7fd514 Mon Sep 17 00:00:00 2001 From: Wei Shuai Date: Sat, 14 May 2022 20:11:11 +0800 Subject: [PATCH 2/4] too slow for feedback data use 12 for a while --- src/Sources/Code/Module.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Sources/Code/Module.cpp b/src/Sources/Code/Module.cpp index e301671..2050896 100644 --- a/src/Sources/Code/Module.cpp +++ b/src/Sources/Code/Module.cpp @@ -299,8 +299,8 @@ void ReadSimVar(SimVar &simVar, Client* client) { void ReadSimVars() { for (auto& client : RegisteredClients) { std::list* SimVars = &(client->SimVars); - //circular list, Max 5 SimVars at once - for (int i=0; i < 5; ++i) { + //circular list, Max 12 SimVars at once + for (int i=0; i < 12; ++i) { std:advance(client->RollingClientDataReadIndex, 1); if(client->RollingClientDataReadIndex == SimVars->end()){ client->RollingClientDataReadIndex = SimVars->begin(); From daec4d5ff35d5f33477c0fc5f3c2e77704cf1a34 Mon Sep 17 00:00:00 2001 From: Sebastian M Date: Sun, 7 Aug 2022 23:17:44 +0200 Subject: [PATCH 3/4] Changed back to std::vector and added method to send command for changing it. --- .../mobiflight-event-module.xml | 2 +- src/Sources/Code/Module.cpp | 46 ++++++++++++------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/PackageDefinitions/mobiflight-event-module.xml b/src/PackageDefinitions/mobiflight-event-module.xml index f6b9e7b..91e6512 100644 --- a/src/PackageDefinitions/mobiflight-event-module.xml +++ b/src/PackageDefinitions/mobiflight-event-module.xml @@ -1,5 +1,5 @@ - + MISC Codestin Search App diff --git a/src/Sources/Code/Module.cpp b/src/Sources/Code/Module.cpp index 2050896..9d13e07 100644 --- a/src/Sources/Code/Module.cpp +++ b/src/Sources/Code/Module.cpp @@ -11,7 +11,7 @@ #include "Module.h" HANDLE g_hSimConnect; -const char* version = "0.5.0"; +const char* version = "0.6.0"; const char* ClientName = "MobiFlightWasmModule"; const char* MobiFlightEventPrefix = "MobiFlight."; @@ -26,6 +26,7 @@ const char* CLIENT_DATA_NAME_POSTFIX_COMMAND = ".Command"; const char* CLIENT_DATA_NAME_POSTFIX_RESPONSE = ".Response"; const int MOBIFLIGHT_MESSAGE_SIZE = 1024; +const int MOBIFLIGHT_MAX_VARS_PER_FRAME_DEFAULT = 30; // This is an offset for the dynamically registered SimVars // to avoid any conflicts with base IDs @@ -34,6 +35,8 @@ uint16_t SimVarOffset = 1000; // For each registered client can 10000 data definition ids are reserved uint16_t ClientDataDefinitionIdSimVarsRange = 10000; +uint16_t MOBIFLIGHT_MAX_VARS_PER_FRAME = MOBIFLIGHT_MAX_VARS_PER_FRAME_DEFAULT; + // data struct for dynamically registered SimVars struct SimVar { int ID; @@ -54,13 +57,14 @@ struct Client { SIMCONNECT_CLIENT_DATA_ID DataAreaIDCommand; SIMCONNECT_CLIENT_DATA_DEFINITION_ID DataDefinitionIDStringResponse; SIMCONNECT_CLIENT_DATA_DEFINITION_ID DataDefinitionIDStringCommand; - std::list SimVars; + std::vector SimVars; SIMCONNECT_CLIENT_DATA_DEFINITION_ID DataDefinitionIdSimVarsStart; // This is an optimization to be able to re-use already defined data definition IDs & request IDs // after resetting registered SimVars uint16_t MaxClientDataDefinition = 0; // Runtime Rolling CLient Data reading Index - std::list::iterator RollingClientDataReadIndex; + //std::vector::iterator RollingClientDataReadIndex; + uint16_t RollingClientDataReadIndex; }; @@ -234,7 +238,7 @@ void WriteSimVar(SimVar& simVar, Client* client) { // Register a single SimVar and send the current value to SimConnect Clients void RegisterSimVar(const std::string code, Client* client) { - std::list* SimVars = &(client->SimVars); + std::vector* SimVars = &(client->SimVars); SimVar var1; var1.Name = code; var1.ID = SimVars->size() + client->DataDefinitionIdSimVarsStart; @@ -254,7 +258,6 @@ void RegisterSimVar(const std::string code, Client* client) { ); client->MaxClientDataDefinition = SimVars->size(); - client->RollingClientDataReadIndex = SimVars->begin(); } #if _DEBUG fprintf(stderr, "MobiFlight[%s]: RegisterSimVar SimVars Size: %d\n", client->Name.c_str(), SimVars->size()); @@ -277,7 +280,8 @@ void RegisterSimVar(const std::string code, Client* client) { void ClearSimVars(Client* client) { client->SimVars.clear(); fprintf(stderr, "MobiFlight: Cleared SimVar tracking."); - client->RollingClientDataReadIndex = client->SimVars.begin(); + //client->RollingClientDataReadIndex = client->SimVars.begin(); + client->RollingClientDataReadIndex = 0; } // Read a single SimVar and send the current value to SimConnect Clients @@ -298,15 +302,15 @@ void ReadSimVar(SimVar &simVar, Client* client) { // Read all dynamically registered SimVars void ReadSimVars() { for (auto& client : RegisteredClients) { - std::list* SimVars = &(client->SimVars); - //circular list, Max 12 SimVars at once - for (int i=0; i < 12; ++i) { - std:advance(client->RollingClientDataReadIndex, 1); - if(client->RollingClientDataReadIndex == SimVars->end()){ - client->RollingClientDataReadIndex = SimVars->begin(); - } - - ReadSimVar(*(client->RollingClientDataReadIndex), client); + std::vector* SimVars = &(client->SimVars); + + int maxVarsPerFrame = SimVars->size() < MOBIFLIGHT_MAX_VARS_PER_FRAME ? SimVars->size() : MOBIFLIGHT_MAX_VARS_PER_FRAME; + + for (int i=0; i < maxVarsPerFrame; ++i) { + ReadSimVar(SimVars->at(client->RollingClientDataReadIndex), client); + client->RollingClientDataReadIndex++; + if (client->RollingClientDataReadIndex >= SimVars->size()) + client->RollingClientDataReadIndex = 0; } } } @@ -390,7 +394,9 @@ Client* RegisterNewClient(const std::string clientName) { newClient->DataAreaNameCommand = newClient->Name + std::string(CLIENT_DATA_NAME_POSTFIX_COMMAND); newClient->DataDefinitionIDStringResponse = 2 * newClient->ID; // 500 Clients possible until offset 1000 is reached newClient->DataDefinitionIDStringCommand = newClient->DataDefinitionIDStringResponse + 1; - newClient->SimVars = std::list(); + newClient->SimVars = std::vector(); + //newClient->RollingClientDataReadIndex = newClient->SimVars.begin(); + newClient->RollingClientDataReadIndex = 0; newClient->DataDefinitionIdSimVarsStart = SimVarOffset + (newClient->ID * ClientDataDefinitionIdSimVarsRange); RegisteredClients.push_back(newClient); @@ -537,6 +543,14 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex SendNewClientResponse(client, newClient); fprintf(stderr, "MobiFlight: Received Client to register: %s.\n", str.c_str()); } + + if (m_str.get()->find("MF.Config.MAX_VARS_PER_FRAME.Set.") != std::string::npos) { + std::string prefix = "MF.Config.MAX_VARS_PER_FRAME.Set."; + str = m_str.get()->substr(prefix.length()); + uint16_t value = static_cast(std::stoi(str)); + MOBIFLIGHT_MAX_VARS_PER_FRAME = value; + fprintf(stderr, "MobiFlight: Set MF.Config.MAX_VARS_PER_FRAME to %u.\n", value); + } break; } From 3a2b01589cf43f4fefb5dbc918dbf4c6e68ba9af Mon Sep 17 00:00:00 2001 From: Sebastian M Date: Wed, 10 Aug 2022 21:34:13 +0200 Subject: [PATCH 4/4] removed explicit DEFAULT value --- src/Sources/Code/Module.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Sources/Code/Module.cpp b/src/Sources/Code/Module.cpp index 9d13e07..d700b37 100644 --- a/src/Sources/Code/Module.cpp +++ b/src/Sources/Code/Module.cpp @@ -26,7 +26,6 @@ const char* CLIENT_DATA_NAME_POSTFIX_COMMAND = ".Command"; const char* CLIENT_DATA_NAME_POSTFIX_RESPONSE = ".Response"; const int MOBIFLIGHT_MESSAGE_SIZE = 1024; -const int MOBIFLIGHT_MAX_VARS_PER_FRAME_DEFAULT = 30; // This is an offset for the dynamically registered SimVars // to avoid any conflicts with base IDs @@ -35,7 +34,9 @@ uint16_t SimVarOffset = 1000; // For each registered client can 10000 data definition ids are reserved uint16_t ClientDataDefinitionIdSimVarsRange = 10000; -uint16_t MOBIFLIGHT_MAX_VARS_PER_FRAME = MOBIFLIGHT_MAX_VARS_PER_FRAME_DEFAULT; +// Maximum number of variables that are read from sim per frame, Default: 30 +// Can be set to different value via config command +uint16_t MOBIFLIGHT_MAX_VARS_PER_FRAME = 30; // data struct for dynamically registered SimVars struct SimVar {