From 68eb4c53e745099c17cadaa5d323c26a98ec932b Mon Sep 17 00:00:00 2001 From: MiMaKes <65442551+MiMaKes@users.noreply.github.com> Date: Wed, 24 Jan 2024 18:14:50 +0100 Subject: [PATCH 1/3] Support String values (#19) * Fix for #8 - Added new client data zone for string data - SimConnect now properly loads the string data from the var - Data is properly stored in the new data zone * Improved functionality of string SimVars * Increased string data area size to maximum * write SimVar when string-value has changed * added some debug output * fixed some compiler warnings * Separated handling for "regular" float SimVars and "new" string SimVars * Added AddString command to readme * Review changes: * Refactoring RegisterSimVar function into two separate functions. One for floats, one for strings * Removing first WriteSimVar function call when registering a simvar * Removing unused variables --------- Co-authored-by: Roderick Griffioen --- README.md | 20 ++- src/Sources/Code/Module.cpp | 283 ++++++++++++++++++++++++++---------- 2 files changed, 221 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 6627032..a9f2995 100644 --- a/README.md +++ b/README.md @@ -21,23 +21,27 @@ The default channels for the MobiFlight client are auto created on startup. Each #### Communication protocol -| Command (string)| Responses (string) | LVars offset (float) | +| Command (string)| Responses (string) | LVars value (float/string) | | ----------- | ----------- | ---------| | ```MF.Ping```| ```MF.Pong```| | ```MF.LVars.List``` | ```MF.LVars.List.Start```
```A32NX_AUTOPILOT_1_ACTIVE```
```A32NX_AUTOPILOT_HEADING_SELECTED```
```...```
```MF.LVars.List.End```| -| ```MF.SimVars.Add.(A:GROUND ALTITUDE,Meters)``` || ```1455.23``` | -|```MF.SimVars.Clear``` ||| -|```MF.SimVars.Set.5 (>L:MyVar)```||| -|```MF.Clients.Add.ClientName```|```MF.Clients.Add.ClientName.Finished```|| -|```MF.Config.MAX_VARS_PER_FRAME.Set.30```||| -|```MF.Version.Get```|```MF.Version.0.6.0```|| +| ```MF.SimVars.Add.(A:GROUND ALTITUDE,Meters)``` || ```e.g. 1455.23 (float)``` | +| ```MF.SimVars.AddString.(A:GPS WP NEXT ID,String)``` || ```e.g. EDDS (string)``` | +| ```MF.SimVars.Clear``` ||| +| ```MF.SimVars.Set.5 (>L:MyVar)```||| +| ```MF.Clients.Add.ClientName```|```MF.Clients.Add.ClientName.Finished```|| +| ```MF.Config.MAX_VARS_PER_FRAME.Set.30```||| +| ```MF.Version.Get```|```MF.Version.0.6.0```|| **MF.SimVars.Add.** -The "SimVars.Add." command needs to be extended with a gauge calculator scipt for reading a variable, like shown in the table. Each added variable needs 4 reserved bytes to return its float value in the LVars channel. The bytes are allocated in the order of the LVars being added. The first variable starts at offset 0, the second at offset 4, the third at offset 8 and so on. To access each value, the external SimConnect clients needs a unique DataDefinitionId for each memory segment. It is recommended to start with ID 1000. +The "SimVars.Add." command needs to be extended with a gauge calculator script for reading a variable, like shown in the table. Each added variable needs 4 reserved bytes to return its float value in the LVars channel. The bytes are allocated in the order of the LVars being added. The first variable starts at offset 0, the second at offset 4, the third at offset 8 and so on. To access each value, the external SimConnect clients needs a unique DataDefinitionId for each memory segment. It is recommended to start with ID 1000. ![Lvars channels](doc/lvarsChannel.png) +**MF.SimVars.AddString.** +The "SimVars.AddString." command works similar to the "SimVars.Add." command but the string result of the gauge calculator script is used. The size of a single string can be up to 128 bytes, which allows handling a total of 64 string variables. The first variable starts at offset 0, the second at offset 128, the third at offset 256 and so on. To access each value, the external SimConnect clients needs a unique DataDefinitionId for each memory segment. It is recommended to start with ID 10000. + **MF.Clients.Add.** The default channels are reserved for communication with the MobiFlight client. But they can be used to request additional channels for other SimConnect clients as well. If another client wants to use the WASM module for variable access, it can register itself with the command ```MF.Clients.Add.MyClientName``` using the default command channel. The WASM module then creates the new shared memory channels "MyClientName.LVars", "MyClientName.Command", "MyClientName.Response" and informs the client with ```MF.Clients.Add.ClientName.Finished```. diff --git a/src/Sources/Code/Module.cpp b/src/Sources/Code/Module.cpp index 73e4f30..a6c2857 100644 --- a/src/Sources/Code/Module.cpp +++ b/src/Sources/Code/Module.cpp @@ -22,22 +22,28 @@ std::vector> CodeEvents; const char* MOBIFLIGHT_CLIENT_DATA_NAME = "MobiFlight"; const char* CLIENT_DATA_NAME_POSTFIX_SIMVAR = ".LVars"; +const char* CLIENT_DATA_NAME_POSTFIX_STRINGVAR = ".StringVars"; const char* CLIENT_DATA_NAME_POSTFIX_COMMAND = ".Command"; const char* CLIENT_DATA_NAME_POSTFIX_RESPONSE = ".Response"; const int MOBIFLIGHT_MESSAGE_SIZE = 1024; -// This is an offset for the dynamically registered SimVars +// This is an offset for the dynamically registered SimVars // to avoid any conflicts with base IDs -uint16_t SimVarOffset = 1000; +constexpr uint16_t SIMVAR_OFFSET = 1000; // For each registered client can 10000 data definition ids are reserved -uint16_t ClientDataDefinitionIdSimVarsRange = 10000; +constexpr uint16_t CLIENT_DATA_DEF_ID_SIMVAR_RANGE = 10000; +constexpr uint16_t CLIENT_DATA_DEF_ID_STRINGVAR_RANGE = 10000; // 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; +// Max length of a string variable. This will affect the maximum amount of string variables +// due to the maximum client-data-array-size (SIMCONNECT_CLIENTDATA_MAX_SIZE) of 8kB! +constexpr uint16_t MOBIFLIGHT_STRING_SIMVAR_VALUE_MAX_LEN = 128; + // data struct for dynamically registered SimVars struct SimVar { int ID; @@ -46,6 +52,13 @@ struct SimVar { float Value; }; +struct StringSimVar { + int ID; + int Offset; + std::string Name; + std::string Value; +}; + // data struct for client accessing SimVars struct Client { int ID; @@ -53,20 +66,25 @@ struct Client { std::string DataAreaNameSimVar; std::string DataAreaNameResponse; std::string DataAreaNameCommand; + std::string DataAreaNameStringVar; SIMCONNECT_CLIENT_DATA_ID DataAreaIDSimvar; SIMCONNECT_CLIENT_DATA_ID DataAreaIDResponse; SIMCONNECT_CLIENT_DATA_ID DataAreaIDCommand; + SIMCONNECT_CLIENT_DATA_ID DataAreaIDStringSimVar; SIMCONNECT_CLIENT_DATA_DEFINITION_ID DataDefinitionIDStringResponse; SIMCONNECT_CLIENT_DATA_DEFINITION_ID DataDefinitionIDStringCommand; std::vector SimVars; + std::vector StringSimVars; + SIMCONNECT_CLIENT_DATA_DEFINITION_ID DataDefinitionIdSimVarsStart; + SIMCONNECT_CLIENT_DATA_DEFINITION_ID DataDefinitionIdStringVarsStart; // This is an optimization to be able to re-use already defined data definition IDs & request IDs - // after resetting registered SimVars + // after resetting registered SimVars uint16_t MaxClientDataDefinition = 0; // Runtime Rolling CLient Data reading Index //std::vector::iterator RollingClientDataReadIndex; uint16_t RollingClientDataReadIndex; - + }; // The list of currently registered clients @@ -154,12 +172,12 @@ void RegisterEvents() { hr = SimConnect_AddClientEventToNotificationGroup(g_hSimConnect, MOBIFLIGHT_GROUP::DEFAULT, eventID, false); #if _DEBUG - if (hr != S_OK) { - fprintf(stderr, "MobiFlight: Error on registering Event %s with ID %u for code %s", eventName.c_str(), eventID, eventCommand.c_str()); + if (hr != S_OK) { + fprintf(stderr, "MobiFlight: Error on registering Event %s with ID %lu for code %s", eventName.c_str(), eventID, eventCommand.c_str()); } else { std::cout << "MobiFlight: Success on registering Event " << eventName.c_str(); - std::cout << " with ID " << eventID << " for code " << eventCommand.c_str() << std::endl; + std::cout << " with ID " << eventID << " for code " << eventCommand.c_str() << std::endl; } #endif @@ -205,12 +223,11 @@ void SendNewClientResponse(Client* client, Client* nc) { // List all available LVars for the currently loaded flight // and send them to the SimConnect client void ListLVars(Client* client) { - int lVarId = 0; lVarList.clear(); for (int i = 0; i != 1000; i++) { const char * lVarName = get_name_of_named_variable(i); - if (lVarName == NULLPTR) break; + if (lVarName == NULLPTR) break; lVarList.push_back(std::string(lVarName)); } @@ -224,6 +241,29 @@ void ListLVars(Client* client) { } } +// Overloaded write function for string SimVars +void WriteSimVar(StringSimVar& simVar, Client* client) +{ + HRESULT hr = SimConnect_SetClientData( + g_hSimConnect, + client->DataAreaIDStringSimVar, + simVar.ID, + SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT, + 0, + MOBIFLIGHT_STRING_SIMVAR_VALUE_MAX_LEN, + (void*)simVar.Value.c_str() + ); + + if (hr != S_OK) { + fprintf(stderr, "MobiFlight[%s]: Error on Setting String Client Data. %lu, SimVar: %s (String-ID: %ul)\n", client->Name.c_str(), hr, simVar.Name.c_str(), simVar.ID); + } +#if _DEBUG + std::cout << "MobiFlight[" << client->Name.c_str() << "]: Written String-SimVar " << simVar.Name.c_str(); + std::cout << " with String-ID " << simVar.ID << " has value " << simVar.Value.c_str() << std::endl; +#endif +} + +// Overloaded write function for float SimVars void WriteSimVar(SimVar& simVar, Client* client) { HRESULT hr = SimConnect_SetClientData( g_hSimConnect, @@ -234,71 +274,123 @@ void WriteSimVar(SimVar& simVar, Client* client) { sizeof(simVar.Value), &simVar.Value ); - if (hr != S_OK) { - fprintf(stderr, "MobiFlight[%s]: Error on Setting Client Data. %u, SimVar: %s (ID: %u)", client->Name.c_str(), hr, simVar.Name.c_str(), simVar.ID); - } + + if (hr != S_OK) { + fprintf(stderr, "MobiFlight[%s]: Error on Setting Client Data. %lu, SimVar: %s (ID: %u)", client->Name.c_str(), hr, simVar.Name.c_str(), simVar.ID); + } #if _DEBUG - std::cout << "MobiFlight[" << client->Name.c_str() << "]: SimVar " << simVar.Name.c_str(); + std::cout << "MobiFlight[" << client->Name.c_str() << "]: Written SimVar " << simVar.Name.c_str(); std::cout << " with ID " << simVar.ID << " has value " << simVar.Value << std::endl; #endif } -// Register a single SimVar and send the current value to SimConnect Clients -void RegisterSimVar(const std::string code, Client* client) { +// Register a single Float-SimVar and send the current value to SimConnect Clients +void RegisterFloatSimVar(const std::string code, Client* client) { std::vector* SimVars = &(client->SimVars); - SimVar var1; - var1.Name = code; - var1.ID = SimVars->size() + client->DataDefinitionIdSimVarsStart; - var1.Offset = (SimVars->size()) * sizeof(float); - - SimVars->push_back(var1); + std::vector* StringSimVars = &(client->StringSimVars); + SimVar newSimVar; HRESULT hr; - if (client->MaxClientDataDefinition < SimVars->size()) - { + newSimVar.Name = code; + newSimVar.ID = SimVars->size() + client->DataDefinitionIdSimVarsStart; + newSimVar.Offset = SimVars->size() * (sizeof(float)); + newSimVar.Value = 0.0F; + SimVars->push_back(newSimVar); + + if (client->MaxClientDataDefinition < (SimVars->size() + StringSimVars->size())) { hr = SimConnect_AddToClientDataDefinition( g_hSimConnect, - var1.ID, - var1.Offset, + newSimVar.ID, + newSimVar.Offset, sizeof(float), 0 ); - client->MaxClientDataDefinition = SimVars->size(); + if (hr != S_OK) { + fprintf(stderr, "MobiFlight[%s]: Error on adding Client Data \"%s\" with ID: %u, Offset: %u and Size: %lu\n", client->Name.c_str(), newSimVar.Name.c_str(), newSimVar.ID, newSimVar.Offset, sizeof(float)); + } +#if _DEBUG + else { + std::cout << "MobiFlight[" << client->Name.c_str() << "]: Added SimVar > " << newSimVar.Name.c_str(); + std::cout << " with ID: " << newSimVar.ID << ", Offset: " << newSimVar.Offset << " and Size: " << sizeof(float) << std::endl; + } + std::cout << "MobiFlight[" << client->Name.c_str() << "]: RegisterFloatSimVar SimVars Size: " << SimVars->size() << std::endl; +#endif + client->MaxClientDataDefinition = (SimVars->size() + StringSimVars->size()); } + + FLOAT64 floatVal = 0; + execute_calculator_code(std::string(code).c_str(), &floatVal, nullptr, nullptr); + newSimVar.Value = floatVal; + WriteSimVar(newSimVar, client); #if _DEBUG - std::cout << "MobiFlight[" << client->Name.c_str() << "]: RegisterSimVar SimVars Size: " << SimVars->size() << std::endl; + std::cout << "MobiFlight[" << client->Name.c_str() << "]: RegisterFloatSimVar > " << newSimVar.Name.c_str(); + std::cout << " ID [" << newSimVar.ID << "] : Offset(" << newSimVar.Offset << ") : Value(" << newSimVar.Value << ")" << std::endl; #endif +} - FLOAT64 val; - WriteSimVar(var1, client); +// Register a single String-SimVar and send the current value to SimConnect Clients +void RegisterStringSimVar(const std::string code, Client* client) { + std::vector* SimVars = &(client->SimVars); + std::vector* StringSimVars = &(client->StringSimVars); + StringSimVar newStringSimVar; + HRESULT hr; - execute_calculator_code(std::string(code).c_str(), &val, NULL, NULL); - var1.Value = val; - - WriteSimVar(var1, client); + newStringSimVar.Name = code; + newStringSimVar.ID = StringSimVars->size() + client->DataDefinitionIdStringVarsStart; + newStringSimVar.Offset = StringSimVars->size() * MOBIFLIGHT_STRING_SIMVAR_VALUE_MAX_LEN; + newStringSimVar.Value.empty(); + StringSimVars->push_back(newStringSimVar); + + if (client->MaxClientDataDefinition < (SimVars->size() + StringSimVars->size())) { + hr = SimConnect_AddToClientDataDefinition( + g_hSimConnect, + newStringSimVar.ID, + newStringSimVar.Offset, + MOBIFLIGHT_STRING_SIMVAR_VALUE_MAX_LEN, + 0 + ); + if (hr != S_OK) { + fprintf(stderr, "MobiFlight[%s]: Error on adding Client Data \"%s\" with String-ID: %u, String-Offset: %u and Size: %u\n", client->Name.c_str(), newStringSimVar.Name.c_str(), newStringSimVar.ID, newStringSimVar.Offset, MOBIFLIGHT_STRING_SIMVAR_VALUE_MAX_LEN); + } #if _DEBUG - std::cout << "MobiFlight[" << client->Name.c_str() << "]: RegisterSimVar > " << var1.Name.c_str(); - std::cout << " ID [" << var1.ID << "] : Offset(" << var1.Offset << ") : Value(" << var1.Value << ")" << std::endl; + else { + std::cout << "MobiFlight[" << client->Name.c_str() << "]: Added String-SimVar > " << newStringSimVar.Name.c_str(); + std::cout << " with String-ID: " << newStringSimVar.ID << ", String-Offset: " << newStringSimVar.Offset << " and Size: " << MOBIFLIGHT_STRING_SIMVAR_VALUE_MAX_LEN << std::endl; + } + std::cout << "MobiFlight[" << client->Name.c_str() << "]: RegisterStringSimVar StringSimVars Size: " << StringSimVars->size() << std::endl; +#endif + client->MaxClientDataDefinition = (SimVars->size() + StringSimVars->size()); + } + + PCSTRINGZ charVal = nullptr; + execute_calculator_code(std::string(code).c_str(), nullptr, nullptr, &charVal); + newStringSimVar.Value = std::string(charVal, strnlen(charVal, MOBIFLIGHT_STRING_SIMVAR_VALUE_MAX_LEN)); + WriteSimVar(newStringSimVar, client); +#if _DEBUG + std::cout << "MobiFlight[" << client->Name.c_str() << "]: RegisterStringSimVar > " << newStringSimVar.Name.c_str(); + std::cout << " ID [" << newStringSimVar.ID << "] : Offset(" << newStringSimVar.Offset << ") : Value(" << newStringSimVar.Value << ")" << std::endl; #endif } // Clear the list of currently tracked SimVars void ClearSimVars(Client* client) { - client->SimVars.clear(); + client->SimVars.clear(); + client->StringSimVars.clear(); std::cout << "MobiFlight[" << client->Name.c_str() << "]: Cleared SimVar tracking." << std::endl; //client->RollingClientDataReadIndex = client->SimVars.begin(); client->RollingClientDataReadIndex = 0; } -// Read a single SimVar and send the current value to SimConnect Clients +// Read a single SimVar and send the current value to SimConnect Clients (overloaded for float SimVars) void ReadSimVar(SimVar &simVar, Client* client) { - FLOAT64 val = 0; - execute_calculator_code(std::string(simVar.Name).c_str(), &val, NULL, NULL); - - if (simVar.Value == val) return; - simVar.Value = val; + FLOAT64 floatVal = 0; + + execute_calculator_code(std::string(simVar.Name).c_str(), &floatVal, nullptr, nullptr); + + if (simVar.Value == floatVal) return; + simVar.Value = floatVal; WriteSimVar(simVar, client); @@ -308,17 +400,41 @@ void ReadSimVar(SimVar &simVar, Client* client) { #endif } +// Read a single SimVar and send the current value to SimConnect Clients (overloaded for string SimVars) +void ReadSimVar(StringSimVar &simVar, Client* client) { + PCSTRINGZ charVal = nullptr; + + execute_calculator_code(std::string(simVar.Name).c_str(), nullptr, nullptr, &charVal); + std::string stringVal = std::string(charVal, strnlen(charVal, MOBIFLIGHT_STRING_SIMVAR_VALUE_MAX_LEN)); + if (simVar.Value == stringVal) return; + simVar.Value = stringVal; + + WriteSimVar(simVar, client); + +#if _DEBUG + std::cout << "MobiFlight[" << client->Name.c_str() << "]: StringSimVar " << simVar.Name.c_str(); + std::cout << " with ID " << simVar.ID << " has value " << simVar.Value << std::endl; +#endif +} + // Read all dynamically registered SimVars void ReadSimVars() { for (auto& client : RegisteredClients) { std::vector* SimVars = &(client->SimVars); - - int maxVarsPerFrame = SimVars->size() < MOBIFLIGHT_MAX_VARS_PER_FRAME ? SimVars->size() : MOBIFLIGHT_MAX_VARS_PER_FRAME; - + std::vector* StringSimVars = &(client->StringSimVars); + + int totalSimVars = SimVars->size() + StringSimVars->size(); + int maxVarsPerFrame = (totalSimVars < MOBIFLIGHT_MAX_VARS_PER_FRAME) ? totalSimVars : MOBIFLIGHT_MAX_VARS_PER_FRAME; + for (int i=0; i < maxVarsPerFrame; ++i) { - ReadSimVar(SimVars->at(client->RollingClientDataReadIndex), client); + if(client->RollingClientDataReadIndex < SimVars->size() ) { + ReadSimVar(SimVars->at(client->RollingClientDataReadIndex), client); + } + else { + ReadSimVar(StringSimVars->at(client->RollingClientDataReadIndex - SimVars->size()), client); + } client->RollingClientDataReadIndex++; - if (client->RollingClientDataReadIndex >= SimVars->size()) + if (client->RollingClientDataReadIndex >= totalSimVars) client->RollingClientDataReadIndex = 0; } } @@ -331,25 +447,32 @@ void ReadSimVars() { void RegisterClientDataArea(Client* client) { HRESULT hr = SimConnect_MapClientDataNameToID(g_hSimConnect, client->DataAreaNameSimVar.c_str(), client->DataAreaIDSimvar); if (hr != S_OK) { - fprintf(stderr, "MobiFlight: Error on creating Client Data Area. %u", hr); + fprintf(stderr, "MobiFlight: Error on creating Client Data Area. %lu", hr); return; } SimConnect_CreateClientData(g_hSimConnect, client->DataAreaIDSimvar, 4096, SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT); hr = SimConnect_MapClientDataNameToID(g_hSimConnect, client->DataAreaNameResponse.c_str(), client->DataAreaIDResponse); if (hr != S_OK) { - fprintf(stderr, "MobiFlight: Error on creating Client Data Area. %u", hr); + fprintf(stderr, "MobiFlight: Error on creating Client Data Area. %lu", hr); return; } SimConnect_CreateClientData(g_hSimConnect, client->DataAreaIDResponse, MOBIFLIGHT_MESSAGE_SIZE, SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT); hr = SimConnect_MapClientDataNameToID(g_hSimConnect, client->DataAreaNameCommand.c_str(), client->DataAreaIDCommand); if (hr != S_OK) { - fprintf(stderr, "MobiFlight: Error on creating Client Data Area. %u", hr); + fprintf(stderr, "MobiFlight: Error on creating Client Data Area. %lu", hr); return; } SimConnect_CreateClientData(g_hSimConnect, client->DataAreaIDCommand, MOBIFLIGHT_MESSAGE_SIZE, SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT); + hr = SimConnect_MapClientDataNameToID(g_hSimConnect, client->DataAreaNameStringVar.c_str(), client->DataAreaIDStringSimVar); + if (hr != S_OK) { + fprintf(stderr, "MobiFlight: Error on creating Client Data Area. %lu", hr); + return; + } + SimConnect_CreateClientData(g_hSimConnect, client->DataAreaIDStringSimVar, SIMCONNECT_CLIENTDATA_MAX_SIZE, SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT); + DWORD dataAreaOffset = 0; hr = SimConnect_AddToClientDataDefinition( g_hSimConnect, @@ -395,18 +518,22 @@ Client* RegisterNewClient(const std::string clientName) { newClient = new Client(); newClient->Name = clientName; newClient->ID = RegisteredClients.size(); - newClient->DataAreaIDSimvar = 3 * newClient->ID; + newClient->DataAreaIDSimvar = 4 * newClient->ID; newClient->DataAreaIDCommand = newClient->DataAreaIDSimvar + 1; newClient->DataAreaIDResponse = newClient->DataAreaIDCommand + 1; + newClient->DataAreaIDStringSimVar = newClient->DataAreaIDResponse + 1; newClient->DataAreaNameSimVar = newClient->Name + std::string(CLIENT_DATA_NAME_POSTFIX_SIMVAR); newClient->DataAreaNameResponse = newClient->Name + std::string(CLIENT_DATA_NAME_POSTFIX_RESPONSE); newClient->DataAreaNameCommand = newClient->Name + std::string(CLIENT_DATA_NAME_POSTFIX_COMMAND); + newClient->DataAreaNameStringVar = newClient->Name + std::string(CLIENT_DATA_NAME_POSTFIX_STRINGVAR); newClient->DataDefinitionIDStringResponse = 2 * newClient->ID; // 500 Clients possible until offset 1000 is reached newClient->DataDefinitionIDStringCommand = newClient->DataDefinitionIDStringResponse + 1; newClient->SimVars = std::vector(); + newClient->StringSimVars = std::vector(); //newClient->RollingClientDataReadIndex = newClient->SimVars.begin(); newClient->RollingClientDataReadIndex = 0; - newClient->DataDefinitionIdSimVarsStart = SimVarOffset + (newClient->ID * ClientDataDefinitionIdSimVarsRange); + newClient->DataDefinitionIdSimVarsStart = SIMVAR_OFFSET + (newClient->ID * (CLIENT_DATA_DEF_ID_SIMVAR_RANGE + CLIENT_DATA_DEF_ID_STRINGVAR_RANGE)); + newClient->DataDefinitionIdStringVarsStart = newClient->DataDefinitionIdSimVarsStart + CLIENT_DATA_DEF_ID_SIMVAR_RANGE; RegisteredClients.push_back(newClient); @@ -420,19 +547,22 @@ Client* RegisterNewClient(const std::string clientName) { std::cout << "MobiFlight: NewClient DataAreaIDSimvar: " << newClient->DataAreaIDSimvar << std::endl; std::cout << "MobiFlight: NewClient DataAreaIDResponse: " << newClient->DataAreaIDResponse << std::endl; std::cout << "MobiFlight: NewClient DataAreaIDCommand: " << newClient->DataAreaIDCommand << std::endl; + std::cout << "MobiFlight: NewClient DataAreaIDStringSimVar: " << newClient->DataAreaIDStringSimVar << std::endl; std::cout << "MobiFlight: NewClient DataAreaNameSimVar: " << newClient->DataAreaNameSimVar.c_str() << std::endl; std::cout << "MobiFlight: NewClient DataAreaNameResponse: " << newClient->DataAreaNameResponse.c_str() << std::endl; std::cout << "MobiFlight: NewClient DataAreaNameCommand: " << newClient->DataAreaNameCommand.c_str() << std::endl; + std::cout << "MobiFlight: NewClient DataAreaNameStringVar: " << newClient->DataAreaNameStringVar.c_str() << std::endl; std::cout << "MobiFlight: NewClient DataDefinitionIDStringResponse: " << newClient->DataDefinitionIDStringResponse << std::endl; std::cout << "MobiFlight: NewClient DataDefinitionIDStringCommand: " << newClient->DataDefinitionIDStringCommand << std::endl; std::cout << "MobiFlight: NewClient DataDefinitionIdSimVarsStart: " << newClient->DataDefinitionIdSimVarsStart << std::endl; + std::cout << "MobiFlight: NewClient DataDefinitionIdStringVarsStart: " << newClient->DataDefinitionIdStringVarsStart << std::endl; #endif return newClient; } extern "C" MSFS_CALLBACK void module_init(void) -{ +{ g_hSimConnect = 0; HRESULT hr = SimConnect_Open(&g_hSimConnect, ClientName, (HWND) NULL, 0, 0, 0); if (hr != S_OK) @@ -440,7 +570,7 @@ extern "C" MSFS_CALLBACK void module_init(void) fprintf(stderr, "Could not open SimConnect connection.\n"); return; } - + hr = SimConnect_SubscribeToSystemEvent(g_hSimConnect, EVENT_FLIGHT_LOADED, "FlightLoaded"); if (hr != S_OK) { @@ -468,9 +598,9 @@ extern "C" MSFS_CALLBACK void module_init(void) Client* client = RegisterNewClient(std::string(MOBIFLIGHT_CLIENT_DATA_NAME)); RegisterEvents(); ListLVars(client); - + std::cout << "MobiFlight: Max Message size is " << MOBIFLIGHT_MESSAGE_SIZE << std::endl; - std::cout << "MobiFlight: Module Init Complete.Version: " << version << std::endl; + std::cout << "MobiFlight: Module Init Complete.Version: " << version << std::endl; } extern "C" MSFS_CALLBACK void module_deinit(void) @@ -491,7 +621,6 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex { case SIMCONNECT_RECV_ID_EVENT_FILENAME: { SIMCONNECT_RECV_EVENT_FILENAME* evt = (SIMCONNECT_RECV_EVENT_FILENAME*)pData; - int eventID = evt->uEventID; break; } @@ -503,18 +632,18 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex std::cout << "MobiFlight: Received Command: " << str.c_str() << std::endl; std::cout << "MobiFlight: Received ClientId: " << clientID << std::endl; #endif - + Client* client = RegisteredClients[clientID]; if (str == "MF.Ping") { SendResponse("MF.Pong", client); - std::cout << "MobiFlight[" << client->Name.c_str() << "]: Received ping" << std::endl; + std::cout << "MobiFlight[" << client->Name.c_str() << "]: Received ping" << std::endl; } else if (str == "MF.SimVars.Clear") { ClearSimVars(client); break; - } + } else if (str == "MF.LVars.List") { SendResponse("MF.LVars.List.Start", client); ListLVars(client); @@ -526,7 +655,7 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex { std::string v = "MF.Version." + std::string(version); SendResponse(v.c_str(), client); - std::cout << "MobiFlight[" << client->Name.c_str() << "]: Received get version" << std::endl; + std::cout << "MobiFlight[" << client->Name.c_str() << "]: Received get version" << std::endl; break; } @@ -535,19 +664,27 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex std::string prefix = "MF.SimVars.Set."; str = str.substr(prefix.length()); #if _DEBUG - std::cout << "MobiFlight[" << client->Name.c_str() << "]: Executing Code: " << str.c_str() << std::endl; + std::cout << "MobiFlight[" << client->Name.c_str() << "]: Executing Code: " << str.c_str() << std::endl; #endif execute_calculator_code(str.c_str(), 0, nullptr, nullptr); break; } - + std::shared_ptr m_str = std::make_shared(str); - + if (m_str.get()->find("MF.SimVars.Add.") != std::string::npos) { std::string prefix = "MF.SimVars.Add."; str = m_str.get()->substr(prefix.length()); - RegisterSimVar(str, client); - std::cout << "MobiFlight[" << client->Name.c_str() << "]: Received SimVar to register: " << str.c_str() << std::endl; + RegisterFloatSimVar(str, client); + std::cout << "MobiFlight[" << client->Name.c_str() << "]: Received SimVar to register: " << str.c_str() << std::endl; + break; + } + + if (m_str.get()->find("MF.SimVars.AddString.") != std::string::npos) { + std::string prefix = "MF.SimVars.AddString."; + str = m_str.get()->substr(prefix.length()); + RegisterStringSimVar(str, client); + std::cout << "MobiFlight[" << client->Name.c_str() << "]: Received StringSimVar to register: " << str.c_str() << std::endl; break; } @@ -556,7 +693,7 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex str= m_str.get()->substr(prefix.length()); Client* newClient = RegisterNewClient(str); SendNewClientResponse(client, newClient); - std::cout << "MobiFlight[" << client->Name.c_str() << "]: Received Client to register: " << str.c_str() << std::endl; + std::cout << "MobiFlight[" << client->Name.c_str() << "]: Received Client to register: " << str.c_str() << std::endl; } if (m_str.get()->find("MF.Config.MAX_VARS_PER_FRAME.Set.") != std::string::npos) { @@ -564,15 +701,13 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex str = m_str.get()->substr(prefix.length()); uint16_t value = static_cast(std::stoi(str)); MOBIFLIGHT_MAX_VARS_PER_FRAME = value; - std::cout << "MobiFlight: Set MF.Config.MAX_VARS_PER_FRAME to " << value << std::endl; + std::cout << "MobiFlight: Set MF.Config.MAX_VARS_PER_FRAME to " << value << std::endl; } break; } case SIMCONNECT_RECV_ID_EVENT_FRAME: { SIMCONNECT_RECV_EVENT* evt = (SIMCONNECT_RECV_EVENT*)pData; - int eventID = evt->uEventID; - ReadSimVars(); break; } @@ -586,14 +721,14 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex int CodeEventId = eventID; std::string command = std::string(CodeEvents[CodeEventId].second); #if _DEBUG - std::cout << "MobiFlight execute " << command.c_str() << std::endl; + std::cout << "MobiFlight execute " << command.c_str() << std::endl; #endif execute_calculator_code(command.c_str(), nullptr, nullptr, nullptr); - } + } else { fprintf(stderr, "MobiFlight: OOF! - EventID out of range:%u\n", eventID); } - + break; } default: From 1a82202c8473e7d056e98e642d9947ffb0624f80 Mon Sep 17 00:00:00 2001 From: DocMoebiuz Date: Fri, 26 Jan 2024 00:49:41 +0100 Subject: [PATCH 2/3] Compiled with 1.0.0 version --- src/MobiFlightEventModuleProject.xml | 4 +++- src/PackageDefinitions/mobiflight-event-module.xml | 2 +- src/Sources/Code/Module.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/MobiFlightEventModuleProject.xml b/src/MobiFlightEventModuleProject.xml index ba311d8..7d86cd9 100644 --- a/src/MobiFlightEventModuleProject.xml +++ b/src/MobiFlightEventModuleProject.xml @@ -1,9 +1,11 @@ - + . _PackageInt + _PublishingGroupInt PackageDefinitions\mobiflight-event-module.xml + diff --git a/src/PackageDefinitions/mobiflight-event-module.xml b/src/PackageDefinitions/mobiflight-event-module.xml index 14605b6..ccbfa62 100644 --- a/src/PackageDefinitions/mobiflight-event-module.xml +++ b/src/PackageDefinitions/mobiflight-event-module.xml @@ -1,5 +1,5 @@ - + MISC Event Module diff --git a/src/Sources/Code/Module.cpp b/src/Sources/Code/Module.cpp index a6c2857..f68f2e4 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.7.1"; +const char* version = "1.0.0"; const char* ClientName = "MobiFlightWasmModule"; const char* MobiFlightEventPrefix = "MobiFlight."; From b244a2680f0f7ea9e69667f3987079e4c1b9237c Mon Sep 17 00:00:00 2001 From: Sebastian M Date: Fri, 26 Jan 2024 00:58:06 +0100 Subject: [PATCH 3/3] Use the default mobiflight release.yml (#21) --- .github/release.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/release.yml diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..391ccbe --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,26 @@ +changelog: + exclude: + labels: + - ignore-for-release-notes + categories: + - title: New Feature 🎉 + labels: + - feature + - title: Improvement ✨ + labels: + - enhancement + - title: Bug Fixes 🐛 + labels: + - bug + - title: Bug Fixes (BETA) 🐛 + labels: + - bug_beta + - title: Documentation 📚 + labels: + - documentation + - title: Development 💻 + labels: + - development + - title: Other Changes ⚡ + labels: + - "*"