• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

MSFS20 Making a (L: local var wrapper

Messages
162
Country
italy
Code:
#include "ssw_wasm_gauges.h"
#include "simvars.h"
PCSTRINGZ custom_event_name = "custom_event";
PCSTRINGZ dummy_name = "dummy";

struct SSWGaugeCustomVar
{
    ID custom_event;
    ID dummy;
};

SSWGaugeCustomVar m_SSWGaugeCustomVars;
LocalSimVar* custom_event = (LocalSimVar*) NULL;

////////////////////////////////////////////////
extern "C" {
  
    MSFS_CALLBACK bool custom_event_gauge_callback(FsContext ctx, int service_id, void* pData)
    {
        switch (service_id)
        {
        case PANEL_SERVICE_PRE_INSTALL:
        {

            if (custom_event == (LocalSimVar*) NULL )
                custom_event = new LocalSimVar(custom_event_name);
            return true;
        }
        break;
        case PANEL_SERVICE_POST_INSTALL:
.......

Hello,
above code is an attempt to make a wrapper for local vars, however it seems the calling a C++ ctor has problems with linking:
Code:
C:\MSFS SDK\WASM\vs\2019\Microsoft.Cpp.MSFS.Common.targets(473, 5) error MSB4181: The "MSFSLinkTask" task returned false but did not log an error.
someone had same issue ?
TIA
mario
 
Last edited:
I have never seen this error.
What do you mean of wrapper for local vars? What does LocalSimVar class do? And where is it implemented?
 
Thanks for answer.
btw: using your code exaple above i could find the "rosebud" to make C++ gauges.

I mean a "wrapper" an object that encapsulates some behaviours of sim vars.
LocalSimVar is a class into below header file (own made), a wrapper for named variables in MSFS
/Mario

Code:
// simvars.h
#pragma once
#include "ssw_wasm_gauges.h"
/*
Generic simulation var, root class
*/
class SimVar {
protected:
    STRING name[128];
    ENUM var_units;
    ENUM var_enum;
public:
    SimVar(PCSTRINGZ s_name): var_units(0),var_enum(0) { strcpy(name, s_name); }
    ~SimVar() {}
    virtual void Set(FLOAT64 val) {}
    virtual double Get(void) { return 0.0; }
    virtual void operator=(FLOAT64 value) {}
    virtual FLOAT operator*() { return 0.0; }
    virtual bool operator==(FLOAT64 value) { return false; }
};
/*
* Read Only simulation var: A:, P: ...
*/

class ROSimVar : public SimVar {
protected:
    SINT32 index;
public:
    ROSimVar(PCSTRINGZ s_name, char* type, SINT32 index = 0);
    ~ROSimVar() {}
    double Get(void);
};
/*
* Local simulation var : L:
*/

class LocalSimVar : public SimVar {
    ID id;
public:
    LocalSimVar(PCSTRINGZ s_name);
    ~LocalSimVar();
    double Get(void);
    void Set(FLOAT64 val);
};
and the implementation here:
Code:
#include "simvars.h"
/*
*/
ROSimVar::ROSimVar(PCSTRINGZ s_name, char* type,SINT32 index):SimVar(name),index(index) {
    var_units = get_aircraft_var_enum(type);
    var_enum = get_aircraft_var_enum(s_name);
}
/*
*/
double ROSimVar::Get(void) {
    return aircraft_varget(var_enum, var_units, index);
}
/*
*/
LocalSimVar::LocalSimVar(PCSTRINGZ s_name) : SimVar(s_name) {
    ID m_id = check_named_variable(s_name);
    if(m_id == -1)
        id = register_named_variable(s_name);
    else
        id = m_id;
}
 
I have reproduced your error.
The problem was that you doesn't implement methods Get and Set of class LocalSimVar.
C++:
class LocalSimVar : public SimVar {
    ID id;
public:
    LocalSimVar(PCSTRINGZ s_name);
    ~LocalSimVar() {};
    double Get(void) { return get_named_variable_value(id); };
    void Set(FLOAT64 val) { set_named_variable_value(id, val); };
};

P.S. also show warning on parent constructor call with wrong parameter
ROSimVar::ROSimVar(PCSTRINGZ s_name, char* type, SINT32 index) :SimVar(s_name), index(index) {
P.S.2 you class architecture is not good. Because you inherited from SimVar class that already have Set, operator= and so on methods you confuse the user of ROSimVar class.
 
I have reproduced your error.
The problem was that you doesn't implement methods Get and Set of class LocalSimVar.
C++:
class LocalSimVar : public SimVar {
    ID id;
public:
    LocalSimVar(PCSTRINGZ s_name);
    ~LocalSimVar() {};
    double Get(void) { return get_named_variable_value(id); };
    void Set(FLOAT64 val) { set_named_variable_value(id, val); };
};

P.S. also show warning on parent constructor call with wrong parameter
ROSimVar::ROSimVar(PCSTRINGZ s_name, char* type, SINT32 index) :SimVar(s_name), index(index) {
P.S.2 you class architecture is not good. Because you inherited from SimVar class that already have Set, operator= and so on methods you confuse the user of ROSimVar class.
Thanks for answer, completely right, forgotten to implement the LocalSimVar method already declared.
However cannot agree completely:
- inheritance assures that the right method will be called on the right object, the ROSimVar::Get() will be called on ROSimVar object while SimVar::Get() method will be called on the SimVar objects., furthermore the virtuality assures that having a generic SimVar* the ambiguity will be resolved and the right method will be called on the right object.
However again thanks, often trivial errors can't be seen.
 
You didn't use the override moniker on the methods declared in the descendent classes, the only way to truly ensure that the correct method is called.
 
I have been working with MSFS wasm projects and development. I have not been able to successfully do a set on anything in the sim yet from my cpp wasm module. Have you guys been able to set anything successfully yet through a wasm module? wing lights on/off etc?

I have tried -
lookup_var( &nav_light);
trigger_key_event( KEY_TOGGLE_NAV_LIGHTS, 0 );

i have also tried-
set_named_variable_value - after I got the ID


Are these not wired up to the API yet or is my GaugePlane not "Virtually wired up correctly"?
 
Firecracker2020, try this.
Light from SDK sample GaugePlane responds accordingly.
C++:
send_key_event(KEY_TOGGLE_NAV_LIGHTS, 0);
 
The difference between trigger_key_event and send_key_event is the same as a windows PostMessage versus SendMessage. Other than that, they should work identical.
 
Other than that, they should work identical.
I also expected that. But in my example...
C++:
    case PANEL_SERVICE_PRE_UPDATE:
    {
        // Logic to toggle lights
        if ((g_Time - g_prevChangeTime) > 2)
        {
            g_prevChangeTime = g_Time;
            //trigger_key_event(KEY_TOGGLE_NAV_LIGHTS, 0); // doesn't work
            send_key_event(KEY_TOGGLE_NAV_LIGHTS, 0);
        }
        return true;
    }
 
I also expected that. But in my example...
C++:
    case PANEL_SERVICE_PRE_UPDATE:
    {
        // Logic to toggle lights
        if ((g_Time - g_prevChangeTime) > 2)
        {
            g_prevChangeTime = g_Time;
            //trigger_key_event(KEY_TOGGLE_NAV_LIGHTS, 0); // doesn't work
            send_key_event(KEY_TOGGLE_NAV_LIGHTS, 0);
        }
        return true;
    }
 
OMG It worked!!!!!!!!!!!!, You would not believe how much that helped me. I have tried and tried all ways. Now I am on my way. I owe you my friend.
 
Back
Top