Demo: LVAR write access for any aircraft control

I’ve made good progress on my WASM module + client API. For lvars, I am scanning to find what is available for the loaded aircraft, and making them available to the client. For hvars, I haven’t found a way to do this programmatically yet (any ideas?), so i am using aircraft-specific files (on substring match) to load the available hvars, and these are also passed back to the client. So the client needs to know nothing about lvars/hvars, these are all passed via client data areas.
I have a separate CDA for the lvar values. This is updated on regular intervals either from the WASM (on second, frame or visual frame) or from the client on request (specifiable in Hz). All lvar values are passed, and so the client holds an up-to-date lvar/value list, so lvar reads are client side-only.
Lvar writes either go via events (for shor or unsigned short values) or via a specific client data area for writing 64bit values.
I also have an additional client data area for executing calculator code passed as a string.
I am adding the final touches at the moment and am planning on a beta release of the WASM module + client-side API + test client sometime next week.

The current issues I am having are:

  • when to start scanning for lvars: Currently I’m waiting for for an un-pause event that follows a SimConnect open after a flight loaded event. I still get more lvars if I re-scan once the flight is loaded.
    I also get lvars registered for a previous aircraft when changing aircraft.
    What is the correct event (or sequence of events) to determine when an aircraft is fully loaded and the lvars are ready to be scanned?
  • no way to determine hvars programmatically. I am using aircraft-specific files at the moment.
    I have read that they can be found using the developer mode, although I haven’t tried this yet. If anyone knows a way to determine the available hvars programmatically, please let me know. Alternatively, if you know of available hvars for any aircraft, please let me know and I will start building the aircraft specific files to distribute with the WASM.

The API exposed to the client will have the following public methods:

> class WASMIF
> {
> 	public:
> 		static class WASMIF* GetInstance(HWND hWnd, int startEventNo = EVENT_START_NO, void (*loggerFunction)(const char* logString) = nullptr);
> 		static class WASMIF* GetInstance(HWND hWnd, void (*loggerFunction)(const char* logString));
> 		void start();
> 		void end();
> 		void createAircraftLvarFile();
> 		void reloadLvars();
> 		void setLvarUpdateFrequency(int freq);
> 		int getLvarUpdateFrequency();
> 		void setLogLevel(LogLevel logLevel);
> 		double getLvar(int lvarID);
> 		double getLvar(const char * lvarName);
> 		void setLvar(unsigned short id, double value);
> 		void setLvar(unsigned short id, short value);
> 		void setLvar(unsigned short id, unsigned short value);
> 		void setHvar(int id);
> 		void listLvars(); // Just print to log for now
> 		void listHvars(); // Just print to log for now
> 		void getLvarList(unordered_map<int, string >& returnMap);
> 		void getHvarList(unordered_map<int, string >& returnMap);
> 		void executeCalclatorCode(const char *code);

John

P.S. I should also say that you can still use the FSUIPC WASM with yout own client API, but to do so you need to include and program your client with the WASM.h:

#pragma once
/*
 * Main WASM Interface. This is the file that is shared
 * between the WASM module and the Client.
 */
#define MAX_VAR_NAME_SIZE		56 // Max size of a CDA is 8k. So Max no lvars per CDK is
								   //   8192/(this valuw) = 146
#define MAX_CDA_NAME_SIZE		64 
#define MAX_NO_LVAR_CDAS		4 // Allows for 585 lvars (4*(8k/56)): 8 is max and allows for 1024 lvars, the max allowd for the value area (8k/8)
#define MAX_NO_HVAR_CDAS		4 // We can have more of these if needed
#define CONFIG_CDA_NAME			"FSUIPC_config"
#define LVARVALUE_CDA_NAME		"FSUIPC_SetLvar"
#define CCODE_CDA_NAME			"FSUIPC_CalcCode"
#define MAX_CALC_CODE_SIZE		256 // Up to 8k

// Define the default value where our events start. From this:
//    0 = Get Config Data (provided but shouldn't be needed)
//   +1 = Set LVAR (short values): parameter contains LVAR ID in low word and encoded value in hi word
//   +2 = Set HVAR: parameter contains ID of CDA that holds the lvar in the low word, and the hvar index number in the hi word
//   +3 = Request to Update LVARS: ignored if WASM is updating internally.
//   +4 = Request to List LVARS (generates aircraft LVAR file)
//   +5 = Reload Control: scans for lvars and re-reads hvar files and drops and re-creates all CDAs accordingly
// Note that it should be possible to change this value (via an ini parameter)
// in both the WASM module and any clients. They must, of course, match.
#define EVENT_START_NO			0x1FFF0

#pragma pack(push, 1)
typedef struct _CDASETLVAR
{
	int id;
	double lvarValue;
} CDASETLVAR;

typedef struct _CDACALCCODE
{
	char calcCode[MAX_CALC_CODE_SIZE];
} CDACALCCODE;

typedef struct _CDAName
{
	char name[MAX_VAR_NAME_SIZE];
} CDAName;

typedef struct _CDAValue
{
	double value;
} CDAValue;

typedef enum {
	LVAR, HVAR, VALUE
} CDAType;

typedef struct _CONFIG_CDA
{
	char CDA_Names[MAX_NO_LVAR_CDAS + MAX_NO_HVAR_CDAS + 1][MAX_CDA_NAME_SIZE];
	int CDA_Size[MAX_NO_LVAR_CDAS + MAX_NO_HVAR_CDAS + 1];
	CDAType CDA_Type[MAX_NO_LVAR_CDAS + MAX_NO_HVAR_CDAS + 1];
} CONFIG_CDA;

#pragma pack(pop)