v1.3.0.0
structs.h
1/*
2This file is part of the WASimCommander project.
3https://github.com/mpaperno/WASimCommander
4
5COPYRIGHT: (c) Maxim Paperno; All Rights Reserved.
6
7This file may be used under the terms of either the GNU General Public License (GPL)
8or the GNU Lesser General Public License (LGPL), as published by the Free Software
9Foundation, either version 3 of the Licenses, or (at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16Copies of the GNU GPL and LGPL are included with this project
17and are available at <http://www.gnu.org/licenses/>.
18*/
19#pragma once
20
21#include "client/enums.h"
22
23//----------------------------------------------------------------------------
24// Client-side struct definitions, used in WASimClient API.
25//----------------------------------------------------------------------------
26
28{
29
30/// Client Event data, delivered via callback. \sa WASimClient::setClientEventCallback(), ClientEventType, ClientStatus
31struct WSMCMND_API ClientEvent
32{
33 ClientEventType eventType; ///< The type of event. See enum docs for details.
34 ClientStatus status; ///< Current status flag(s). See enum docs for details.
35 std::string message; ///< A short message about the event (eg. "Server Connected")
36};
37
38
39/// Structure for delivering list results, eg. of local variables sent from Server.
40/// \sa WASimClient::list(), listResultsCallback_t, WASimCommander::LookupItemType, WASimCommander::CommandId::List command.
41struct WSMCMND_API ListResult
42{
43 using listResult_t = std::vector<std::pair<int, std::string>>; ///< A mapping of IDs to names.
44
45 WASimCommander::Enums::LookupItemType listType; ///< the type of items being listed
46 HRESULT result; ///< Execution result, one of: `S_OK`, `E_FAIL`, `E_TIMEOUT`
47 listResult_t list; ///< Mapping of numeric item IDs to name strings.
48};
49
50
51/// `DataRequestRecord` inherits and extends `WASimCommander::DataRequest` with data pertinent for use by a data consumer/Client.
52/// In particular, any value data sent from the server is stored here as a byte array in the `data` member (a `std::vector` of `unsigned char`).
53///
54/// `DataRequest` subscription results are delivered by `WASimClient` (via `dataCallback_t` callback) using this `DataRequestRecord` structure.
55/// WASimClient also holds a list of all data requests which have been added using `WASimClient::saveDataRequest()` method. These
56/// requests are available for reference using `WASimClient::dataRequest()`, `WASimClient::dataRequests()`, and `WASimClient::dataRequestIdsList()` methods.
57///
58/// An implicit data conversion `operator T()` template is available for _default constructible_ and _trivially
59/// copyable_ types (eg. numeric, char, or fixed-size arrays of such types). This returns a default-constructed value if the
60/// conversion would be invalid (size of requested type doesn't match the data array size).
61///
62/// There is also the `bool tryConvert(T &)` template which tries to populate a pre-initialized value reference
63/// of the desired type and returns true or false depending on if the conversion was valid.
64///
65/// Note that the size of the data array may or _may not_ be the same as the inherited `DataRequest::valueSize` member, since that may contain
66/// special values for preset types. Always check the actual data array size (`data.size()`) if you need to know the storage requirements.
67///
68/// \sa WASimClient::setDataCallback, dataCallback_t, WASimCommander::DataRequest
69struct WSMCMND_API DataRequestRecord : public DataRequest
70{
71 time_t lastUpdate = 0; ///< Timestamp of last data update in ms since epoch.
72 std::vector<uint8_t> data {}; ///< Value data array.
73
74 /// Implicit conversion operator for default constructible and trivially copyable types (eg. numeric, char)
75 /// or fixed-size arrays of such types (eg. char strings). This returns a default-constructed value if the conversion
76 /// would be invalid (size of requested type doesn't match data size).
77 template<typename T,
78 std::enable_if_t<std::is_trivially_copyable_v<T>, bool> = true,
79 std::enable_if_t<std::is_default_constructible_v<T>, bool> = true>
80 inline operator T() const {
81 T ret = T();
82 tryConvert(ret);
83 return ret;
84 }
85
86 /// Tries to populate a pre-initialized value reference of the desired type and returns true or false
87 /// depending on if the conversion was valid (meaning the size of requested type matches the data size).
88 /// If the conversion fails, the original result value is not changed, allowing for any default to be preserved.
89 /// The value must be trivially copyable, (eg. numerics, chars), or fixed-size arrays of such types.
90 template<typename T, std::enable_if_t<std::is_trivially_copyable_v<T>, bool> = true>
91 inline bool tryConvert(T &result) const {
92 bool ret;
93 if ((ret = data.size() == sizeof(T)))
94 memcpy(&result, data.data(), sizeof(T));
95 return ret;
96 }
97
98 // The c'tors and assignments are primarily for internal use and container storage requirements, but may also be useful for subclasses.
99 using DataRequest::DataRequest; ///< Inherits DataRequest constructors.
100 using DataRequest::operator=; ///< Inherits DataRequest assignment operators.
101 DataRequestRecord(); ///< Default c'tor creates an invalid instance with request ID of -1, zero size, and `RequestType::None`.
102 DataRequestRecord(const DataRequest &request); ///< Constructs new instance from a `DataRequest` instance by lvalue/copy. The data array is initialized to the corresponding size with 0xFF value for all bytes.
103 DataRequestRecord(DataRequest &&request); ///< Constructs new instance from a `DataRequest` instance by rvalue/move. The data array is initialized to the corresponding size with 0xFF value for all bytes.
104};
105
106/// Structure for using with `WASimClient::getVariable()` and `WASimClient::setVariable()` to specify information about the variable to set or get. Variables and Units can be specified by name or by numeric ID.
107/// Only some variable types have an associated numeric ID ('A', 'L', 'T' types) and only some variable types accept a Unit specifier ('A', 'C', 'E', 'L' types). Using numeric IDs, if already known, is more efficient
108/// on the server side since it saves the lookup step.
109struct WSMCMND_API VariableRequest
110{
111 char variableType = 'L'; ///< A single character variable type identifier as documented in the MSFS SDK documentation (plus 'T' for Token vars).
112 std::string variableName {}; ///< Name of the variable. Ignored if `variableId` is greater than -1.
113 std::string unitName {}; ///< Unit name. For local ('L') and Sim ('A') variables the unit type will be resolved to an enum ID and, if successful, will be used in the relevant command (`(get | set)_named_variable_typed_value()`/`aircraft_varget()`).
114 /// Otherwise, for 'L' vars the default units are used (_Gauge API_ `(get | set)_named_variable_value()`) and for getting SimVars the behavior is undefined (-1 is passed to `aircraft_varget()` as the unit ID).
115 /// For the other variable types which use units ('C', 'E', or when setting 'A'), this string will simply be included in the produced calculator code (eg. `(E:SIMULATION TIME,seconds)` or `50 (>A:COCKPIT CAMERA ZOOM,percent)`).
116 /// The unit name is ignored for all other variable types, and the `unitId` field is preferred if it is greater than -1.
117 int variableId = -1; ///< Numeric ID of the variable to get/set. Overrides the `variableName` field if greater than -1. Only 'A', 'L', 'T' variable types can be referenced by numeric IDs.
118 int unitId = -1; ///< Numeric ID of the Unit type to use in the get/set command. Overrides the `unitName` field if greater than -1. See usage notes for `unitName` about applicable variable types.
119 uint8_t simVarIndex = 0; ///< Optional index number for SimVars ('A') which require them. If using named variables, the index can also be included in the variable name string (after a colon `:`, as would be used in a calculator string).
120 bool createLVar = false; ///< This flag indicates that the L var should be created if it doesn't already exist in the simulator. This applies for both "Set" and "Get" commands.
121
122 /// Default constructor, with optional parameters for variable type, name, unit name, SimVar index and `createLVar` flag.
123 explicit VariableRequest(char variableType = 'L', const std::string &variableName = std::string(), const std::string &unitName = std::string(), uint8_t simVarIndex = 0, bool createVariable = false) :
124 variableType{variableType}, variableName{variableName}, unitName{unitName}, simVarIndex(simVarIndex), createLVar{createVariable} { }
125 /// Construct a variable request using numeric variable and (optionally) unit IDs, and optional SimVar index.
126 explicit VariableRequest(char variableType, int variableId, int unitId = -1, uint8_t simVarIndex = 0) :
127 variableType{variableType}, variableId{variableId}, unitId{unitId}, simVarIndex(simVarIndex) { }
128 /// Construct a variable request for a Simulator Variable (SimVar) with given name, unit, and optional index parameter.
129 explicit VariableRequest(const std::string &simVarName, const std::string &unitName, uint8_t simVarIndex = 0) :
130 variableType{'A'}, variableName{simVarName}, unitName{unitName}, simVarIndex(simVarIndex) { }
131 /// Construct a variable request for a Simulator Variable ('A') using numeric variable and unit IDs, with optional index parameter.
132 explicit VariableRequest(int simVarId, int unitId, uint8_t simVarIndex = 0) :
133 variableType{'A'}, variableId{simVarId}, unitId{unitId}, simVarIndex(simVarIndex) { }
134 /// Construct a variable request for a Local variable ('L') with the given name. `createVariable` will create the L var on the simulator if it doesn't exist yet
135 /// (for "Get" as well as "Set" commands). An optional unit name can also be provided.
136 explicit VariableRequest(const std::string &localVarName, bool createVariable = false, const std::string &unitName = std::string()) :
137 variableType{'L'}, variableName{localVarName}, unitName{unitName}, createLVar{createVariable} { }
138 /// Construct a variable request for a Local variable ('L') with the given numeric ID.
139 explicit VariableRequest(int localVarId) :
140 variableType{'L'}, variableId{localVarId} { }
141};
142
143
144/// Structure to hold data for registered (reusable) calculator events. Used to submit events with `WASimClient::registerEvent()`.
145///
146/// WASimClient also holds a list of all registered events which have been added using `WASimClient::registerEvent()`. These
147/// requests are available for reference using `WASimClient::registeredEvent()` and `WASimClient::registeredEvents()` methods.
148/// \sa WASimClient::registerEvent(), WASimCommander::CommandId::Register
149struct WSMCMND_API RegisteredEvent
150{
151 uint32_t eventId = -1; ///< A unique ID for this event. The ID can later be used to modify, trigger, or remove this event.
152 std::string code {}; ///< The calculator code string to execute as the event action. The code is pre-compiled and stored on the server for quicker execution.
153 ///< Maximum length is `WASimCommander::STRSZ_CMD` value minus the `name` string length, if one is used.
154 std::string name {}; ///< Optional custom name for this event. The name is for use with `SimConnect_MapClientEventToSimEvent(id, "event_name")` and `SimConnect_TransmitClientEvent(id)`. Default is to use the event ID as a string.
155 /// If the custom event name contains a period (`.`) then it is used as-is. Otherwise "WASimCommander.[client_name]." will be prepended to the name.
156 /// \note The event name **cannot be changed** after the initial registration (it is essentially equivalent to the `eventId`). When updating an existing event on the server, it is
157 /// not necessary to include the name again, only the `eventId` is required (and the code to execute, of course). Maximum length for the name string is the value of `WASimCommander::STRSZ_ENAME`.
158
159 /// Default implicit constructor.
160 RegisteredEvent(uint32_t eventId = -1, const std::string &code = "", const std::string &name = "");
161 RegisteredEvent(RegisteredEvent const &) = default;
162};
163
164}; // namespace WASimCommander::Client
WASimCommander::Client namespace. Defines/declares everything needed to interact with the WASimComman...
Definition: enums_impl.h:32
HRESULT result
Execution result, one of: S_OK, E_FAIL, E_TIMEOUT
Definition: structs.h:46
WASimCommander::Enums::LookupItemType listType
the type of items being listed
Definition: structs.h:45
ClientEventType eventType
The type of event. See enum docs for details.
Definition: structs.h:33
std::string message
A short message about the event (eg. "Server Connected")
Definition: structs.h:35
listResult_t list
Mapping of numeric item IDs to name strings.
Definition: structs.h:47
std::vector< std::pair< int, std::string > > listResult_t
A mapping of IDs to names.
Definition: structs.h:43
ClientStatus status
Current status flag(s). See enum docs for details.
Definition: structs.h:34
ClientEventType
Client event type enumeration.
Definition: enums_impl.h:55
ClientStatus
Client status flags.
Definition: enums_impl.h:36
Client Event data, delivered via callback.
Definition: structs.h:32
Structure for delivering list results, eg. of local variables sent from Server.
Definition: structs.h:42
LookupItemType
Types of things to look up or list.
Definition: enums_impl.h:136
DataRequestRecord inherits and extends WASimCommander::DataRequest with data pertinent for use by a d...
Definition: structs.h:70
bool tryConvert(T &result) const
Tries to populate a pre-initialized value reference of the desired type and returns true or false dep...
Definition: structs.h:91
Structure to hold data for registered (reusable) calculator events. Used to submit events with WASimC...
Definition: structs.h:150
Structure for using with WASimClient::getVariable() and WASimClient::setVariable() to specify informa...
Definition: structs.h:110
VariableRequest(const std::string &localVarName, bool createVariable=false, const std::string &unitName=std::string())
Construct a variable request for a Local variable ('L') with the given name. createVariable will crea...
Definition: structs.h:136
VariableRequest(char variableType, int variableId, int unitId=-1, uint8_t simVarIndex=0)
Construct a variable request using numeric variable and (optionally) unit IDs, and optional SimVar in...
Definition: structs.h:126
VariableRequest(char variableType='L', const std::string &variableName=std::string(), const std::string &unitName=std::string(), uint8_t simVarIndex=0, bool createVariable=false)
Default constructor, with optional parameters for variable type, name, unit name, SimVar index and cr...
Definition: structs.h:123
VariableRequest(int simVarId, int unitId, uint8_t simVarIndex=0)
Construct a variable request for a Simulator Variable ('A') using numeric variable and unit IDs,...
Definition: structs.h:132
VariableRequest(const std::string &simVarName, const std::string &unitName, uint8_t simVarIndex=0)
Construct a variable request for a Simulator Variable (SimVar) with given name, unit,...
Definition: structs.h:129
VariableRequest(int localVarId)
Construct a variable request for a Local variable ('L') with the given numeric ID.
Definition: structs.h:139
Structure for variable value subscription requests.
DataRequest(uint32_t requestId, uint32_t valueSize=sizeof(double), WASimCommander::Enums::RequestType requestType=WASimCommander::Enums::RequestType::Calculated, WASimCommander::Enums::CalcResultType calcResultType=WASimCommander::Enums::CalcResultType::Double, WASimCommander::Enums::UpdatePeriod period=WASimCommander::Enums::UpdatePeriod::Tick, const char *nameOrCode=nullptr, const char *unitName=nullptr, char varTypePrefix='L', float deltaEpsilon=0.0f, uint8_t interval=0, uint8_t simVarIndex=0)
Constructor with required request ID, all other parameters optional. See member documentation for exp...