26#include <msclr/marshal.h>
27#include <msclr/marshal_cppstd.h>
32using namespace System;
33using namespace System::Collections::Generic;
34using namespace System::Runtime::InteropServices;
35using namespace msclr::interop;
38#pragma warning(disable:4068)
55 template<uint32_t SIZE >
56 [Runtime::CompilerServices::UnsafeValueType]
57 [StructLayout(LayoutKind::Explicit, Size=(
sizeof(Byte)*SIZE))]
58 public value struct char_array {
64 char_array<SIZE>(String ^str) { fromManagedStr(str); }
65 char_array<SIZE>(
const std::string &str) { fromStdStr(str); }
66 char_array<SIZE>(
const char *str) : char_array<SIZE>(str, std::strlen(str)) {}
67 char_array<SIZE>(
const char *str,
const size_t len) {
69 const pin_ptr<Byte> ptr = &_item;
70 memcpy(ptr, str, min(SIZE, len));
73 void fromStdStr(
const std::string &str) {
77 const pin_ptr<Byte> ptr = &_item;
78 const uint32_t len = std::min<uint32_t>(SIZE-1, (uint32_t)str.size());
79 memcpy(ptr, str.data(), len);
84 void fromManagedStr(String ^str) {
86 if (String::IsNullOrEmpty(str))
88 const pin_ptr<Byte> ptr = &_item;
89 const array<Byte> ^strData = Text::Encoding::UTF8->GetBytes(str);
90 const pin_ptr<Byte> src = &strData[0];
91 const uint32_t len = std::min<uint32_t>(SIZE-1, strData->Length);
92 memcpy(ptr, src, len);
98 const pin_ptr<Byte> ptr = &_item;
102 String ^ToString()
override {
return (String^)*
this; }
104 operator String ^() {
105 const pin_ptr<Byte> ptr = &this->_item;
106 return gcnew String((
const char *)ptr, 0, (
int)std::strlen((
const char *)ptr), Text::Encoding::UTF8);
110 operator std::string() {
111 const pin_ptr<Byte> ptr = &this->_item;
112 return std::string((
const char *)ptr);
116 Byte% operator[](
int index) {
117 return *((&_item)+index);
120 static operator interior_ptr<Byte>(char_array<SIZE>% ia) {
140 [StructLayout(LayoutKind::Sequential, CharSet = CharSet::Ansi, Pack = 1)]
148 char_array<STRSZ_CMD> sData;
151 explicit Command(CommandId
id) : commandId(
id) { }
152 explicit Command(CommandId
id, uint32_t uData) : uData(uData), commandId(
id) { }
153 explicit Command(CommandId
id, uint32_t uData,
double fData) : uData(uData), fData(fData), commandId(
id) { }
154#pragma diag_suppress 144
155 explicit Command(CommandId
id, uint32_t uData, String ^sData) : uData(uData), fData(0.0), commandId(
id), sData{sData} { }
156 explicit Command(CommandId
id, uint32_t uData, String ^sData,
double fData) : uData(uData), fData(fData), commandId(
id), sData{sData} { }
157 explicit Command(CommandId
id, uint32_t uData, String ^sData,
double fData, int32_t token) : token(token), uData(uData), fData(fData), commandId(
id), sData{sData} { }
158#pragma diag_restore 144
160 void setStringData(String ^sData)
162 this->sData = char_array<STRSZ_CMD>(sData);
165 String ^ToString()
override {
166 return String::Format(
"Command {{{0}; token: {1}; uData: {2}; fData: {3:F6}; sData: \"{4}\"}}", commandId, token, uData, fData, sData);
172 pin_ptr<UInt32> ptr = &this->token;
178 pin_ptr<UInt32> ptr = &this->token;
187 [StructLayout(LayoutKind::Sequential, CharSet = CharSet::Ansi, Pack = 1)]
193 char_array<STRSZ_LOG> message;
195 String ^ToString()
override {
196 return String::Format(
"{0} [{1}] {2}", DateTimeOffset::FromUnixTimeMilliseconds(timestamp).LocalDateTime.ToString(
"MM/dd HH:mm:ss.fff"), level, (String ^)message);
202 pin_ptr<UInt64> ptr = &this->timestamp;
210 [StructLayout(LayoutKind::Sequential, CharSet = CharSet::Ansi, Pack = 1)]
214 UInt32 requestId {0};
215 UInt32 valueSize {0};
216 float deltaEpsilon {0.0f};
218 UpdatePeriod period {UpdatePeriod::Never};
219 RequestType requestType {RequestType::None};
220 CalcResultType calcResultType {CalcResultType::None};
221 Byte simVarIndex {0};
222 SByte varTypePrefix {
'L'};
223 char_array<STRSZ_REQ> nameOrCode;
224 char_array<STRSZ_UNIT> unitName;
229 explicit DataRequest(UInt32 requestId, Char variableType, String ^variableName, UInt32 valueSize) :
230 requestId(requestId), valueSize(valueSize), period(UpdatePeriod::Tick),
231 requestType(RequestType::Named), varTypePrefix((Byte)variableType), nameOrCode(variableName)
234 explicit DataRequest(UInt32 requestId, Char variableType, String ^variableName, UInt32 valueSize, UpdatePeriod period, UInt32 interval,
float deltaEpsilon) :
235 requestId(requestId), valueSize(valueSize), deltaEpsilon(deltaEpsilon), interval(interval), period(period),
236 requestType(RequestType::Named), varTypePrefix((Byte)variableType), nameOrCode(variableName)
239 explicit DataRequest(UInt32 requestId, String ^simVarName, String ^unitName, Byte simVarIndex, UInt32 valueSize) :
240 requestId(requestId), valueSize(valueSize), period(UpdatePeriod::Tick),
241 requestType(RequestType::Named), simVarIndex(simVarIndex), varTypePrefix(
'A'), nameOrCode(simVarName), unitName(unitName)
244 explicit DataRequest(UInt32 requestId, String ^simVarName, String ^unitName, Byte simVarIndex, UInt32 valueSize, UpdatePeriod period, UInt32 interval,
float deltaEpsilon) :
245 requestId(requestId), valueSize(valueSize), deltaEpsilon(deltaEpsilon), interval(interval), period(period),
246 requestType(RequestType::Named), simVarIndex(simVarIndex), varTypePrefix(
'A'), nameOrCode(simVarName), unitName(unitName)
249 explicit DataRequest(UInt32 requestId, CalcResultType resultType, String ^calculatorCode, UInt32 valueSize) :
250 requestId(requestId), valueSize(valueSize), period(UpdatePeriod::Tick),
251 requestType(RequestType::Calculated), calcResultType(resultType), nameOrCode(calculatorCode)
254 explicit DataRequest(UInt32 requestId, CalcResultType resultType, String ^calculatorCode, UInt32 valueSize, UpdatePeriod period, UInt32 interval,
float deltaEpsilon) :
255 requestId(requestId), valueSize(valueSize), deltaEpsilon(deltaEpsilon), interval(interval), period(period),
256 requestType(RequestType::Calculated), calcResultType(resultType), nameOrCode(calculatorCode)
263 explicit DataRequest(UInt32 requestId, CalcResultType resultType, String ^calculatorCode) :
264 requestId(requestId), valueSize(calcResultToValueSize(resultType)), period(UpdatePeriod::Tick),
265 requestType(RequestType::Calculated), calcResultType(resultType), nameOrCode(calculatorCode)
272 explicit DataRequest(UInt32 requestId, CalcResultType resultType, String ^calculatorCode, UpdatePeriod period, UInt32 interval,
float deltaEpsilon) :
273 requestId(requestId), valueSize(calcResultToValueSize(resultType)), deltaEpsilon(deltaEpsilon), interval(interval), period(period),
274 requestType(RequestType::Calculated), calcResultType(resultType), nameOrCode(calculatorCode)
280 this->nameOrCode = char_array<STRSZ_REQ>(nameOrCode);
286 this->unitName = char_array<STRSZ_UNIT>(unitName);
292 String ^str = String::Format(
293 "DataRequest {{{0}; size: {1}; period: {2}; interval: {3}; deltaE: {4:F6}", requestId, valueSize, period, interval, deltaEpsilon
295 Text::StringBuilder sb(str);
296 if (requestType == RequestType::None)
297 return sb.Append(
"; type: None; }")->ToString();
298 if (requestType == RequestType::Named)
299 return sb.AppendFormat(
"; type: Named; name: \"{0}\"; unit: \"{1}\"; varType: '{2}'; varIndex: {3}}}", nameOrCode, unitName, varTypePrefix, simVarIndex)->ToString();
300 return sb.AppendFormat(
"; type: Calculated; code: \"{0}\"; resultType: {1}}}", nameOrCode, calcResultType)->ToString();
306 pin_ptr<UInt32> ptr = &this->requestId;
313 pin_ptr<UInt32> ptr = &this->requestId;
318 UInt32 calcResultToValueSize(CalcResultType type) {
344 [StructLayout(LayoutKind::Sequential, CharSet = CharSet::Ansi, Pack = 1)]
358 where T :
value class, gcnew()
362 if (
data->Length == (
int)
sizeof(T)) {
363 pin_ptr<T> pr = &result;
364 pin_ptr<Byte> pd = &
data[0];
365 memcpy_s(pr,
sizeof(T), pd,
data->Length);
377 result = String::Empty;
380 pin_ptr<Byte> pd = &
data[0];
381 result = gcnew String((
const char *)pd);
387 inline static operator double(
DataRequestRecord ^dr) {
return dr->toType<
double>(); }
388 inline static operator float(DataRequestRecord ^dr) {
return dr->toType<
float>(); }
389 inline static operator int64_t(DataRequestRecord ^dr) {
return dr->toType<int64_t>(); }
390 inline static operator uint64_t(DataRequestRecord ^dr) {
return dr->toType<uint64_t>(); }
391 inline static operator int32_t(DataRequestRecord ^dr) {
return dr->toType<int32_t>(); }
392 inline static operator uint32_t(DataRequestRecord ^dr) {
return dr->toType<uint32_t>(); }
393 inline static operator int16_t(DataRequestRecord ^dr) {
return dr->toType<int16_t>(); }
394 inline static operator uint16_t(DataRequestRecord ^dr) {
return dr->toType<uint16_t>(); }
395 inline static operator int8_t(DataRequestRecord ^dr) {
return dr->toType<int8_t>(); }
396 inline static operator uint8_t(DataRequestRecord ^dr) {
return dr->toType<uint8_t>(); }
397 inline static operator String ^(DataRequestRecord ^dr) {
return dr->toType<
String ^>(); }
413 return String::Format(
414 "{0}; DataRequestRecord {{Last Update: {1}; Data: {2}}}",
416 DateTimeOffset::FromUnixTimeMilliseconds(
lastUpdate).LocalDateTime.ToString(
"HH:mm:ss.fff"),
417 BitConverter::ToString(
data)
425 Marshal::Copy(IntPtr((
void*)dr.
data.data()),
data, 0, (
int)dr.
data.size());
444 ClientEventType eventType;
448 String ^ToString()
override {
449 return String::Format(
"ClientEvent {{{0}; status: {1}; message: \"{2}\"}}", eventType, status, message);
454 eventType = (ClientEventType)n.
eventType;
455 status = (ClientStatus)n.
status;
456 message = gcnew String(n.
message.c_str());
466 using ListCollectionType = Dictionary<int, String^>;
468 LookupItemType listType;
470 ListCollectionType ^list;
472 String ^ToString()
override {
473 Text::StringBuilder sb(String::Format(
"ListResult {{{0}; result: {1}; Values:\n", listType, result));
474 ListCollectionType::Enumerator en = list->GetEnumerator();
475 while (en.MoveNext())
476 sb.AppendFormat(
"{0,4} = {1}\n", en.Current.Key, en.Current.Value);
478 return sb.ToString();
483 listType{(LookupItemType)r.
listType}, result(r.
result), list{gcnew ListCollectionType((
int)r.
list.size()) }
485#pragma diag_suppress 2242
486 for (
const auto &pr : r.
list)
487 list[pr.first] = gcnew String(pr.second.c_str());
488#pragma diag_default 2242
499 String ^ code { String::Empty };
500 String ^ name { String::Empty };
504 eventId{eventId}, code{code} { }
506 eventId{eventId}, code{code}, name{name} { }
508 String ^ToString()
override {
509 return String::Format(
"RegisteredEvent {{{0}; code: {1}; name: {2}}}", eventId, code, name);
514 eventId{ev.
eventId}, code{gcnew String(ev.
code.c_str())}, name{gcnew String(ev.
name.c_str())} { }
530 SByte variableType {
'L' };
531 String ^ variableName { String::Empty };
532 String ^ unitName { String::Empty };
533 int variableId { -1 };
535 Byte simVarIndex { 0 };
536 bool createLVar =
false;
541 variableType{(SByte)variableType}, variableName{variableName} { }
544 variableType{(SByte)variableType}, variableId{variableId} { }
547 variableType{(SByte)variableType}, variableName{variableName}, unitName{unitName} { }
550 variableType{(SByte)variableType}, variableId{variableId}, unitId{unitId} { }
552 explicit VariableRequest(String ^simVariableName, String ^unitName, Byte simVarIndex) :
553 variableType{
'A'}, variableName{simVariableName}, unitName{unitName} { }
556 variableType{
'A'}, variableId{simVariableId}, unitId{unitId} { }
559 variableType{
'L'}, variableName{localVariableName} { }
563 variableType{
'L'}, variableName{localVariableName}, createLVar{createVariable} { }
566 explicit VariableRequest(String ^localVariableName,
bool createVariable, String ^unitName) :
567 variableType{
'L'}, variableName{localVariableName}, unitName{unitName}, createLVar{createVariable} { }
570 variableType{
'L'}, variableId{localVariableId} { }
572 String ^ToString()
override {
573 return String::Format(
574 "VariableRequest {{{0}; variableName: \"{1}\"; unitName: \"{2}\"; variableId: {3}; unitId {4}; simVarIndex: {5}}}",
575 variableType, variableName, unitName, variableId, unitId, simVarIndex
584 r.variableId = variableId;
WASimCommander::CLI::Enums namespace. C++/CLI specific definitions only. See documentation for WASimC...
WASimCommander::CLI::Structs namespace. CLI/.NET versions of WASimCommander API and Client data struc...
HRESULT result
Execution result, one of: S_OK, E_FAIL, E_TIMEOUT
WASimCommander::Enums::LookupItemType listType
the type of items being listed
ClientEventType eventType
The type of event. See enum docs for details.
std::string message
A short message about the event (eg. "Server Connected")
listResult_t list
Mapping of numeric item IDs to name strings.
ClientStatus status
Current status flag(s). See enum docs for details.
Client Event data, delivered via callback.
Structure for delivering list results, eg. of local variables sent from Server.
@ String
Expect a string type result from execute_calculator_code().
WASimCommander main namespace. Defines constants and structs used in Client-Server interactions....
static const uint32_t DATA_TYPE_INT32
32-bit integer number (signed or unsigned)
static const uint32_t DATA_TYPE_DOUBLE
64-bit floating-point number
Client Event data, delivered via callback.
Command data structure. The member contents depend on the command type as described in each command t...
Structure for value update subscription requests.
DataRequest(UInt32 requestId, CalcResultType resultType, String ^ calculatorCode, UpdatePeriod period, UInt32 interval, float deltaEpsilon)
Constructs a calculator code request (requestType = RequestType::Calculated) with given update period...
DataRequest(UInt32 requestId, Char variableType, String ^ variableName, UInt32 valueSize)
Constructs a request for a named variable (requestType = RequestType::Named) with default update peri...
String ^ ToString() override
Serializes this DataRequest to a string for debugging purposes.
DataRequest(UInt32 requestId, CalcResultType resultType, String ^ calculatorCode)
Constructs a calculator code request (requestType = RequestType::Calculated) with default update peri...
DataRequest(UInt32 requestId, Char variableType, String ^ variableName, UInt32 valueSize, UpdatePeriod period, UInt32 interval, float deltaEpsilon)
Constructs a request for a named variable (requestType = RequestType::Named) with given update period...
void setUnitName(String ^ unitName)
Set the unitName member using a string type value.
DataRequest(UInt32 requestId, CalcResultType resultType, String ^ calculatorCode, UInt32 valueSize)
Constructs a calculator code request (requestType = RequestType::Calculated) with default update peri...
void setNameOrCode(String ^ nameOrCode)
Set the nameOrCode member using a string type value.
DataRequest(UInt32 requestId, CalcResultType resultType, String ^ calculatorCode, UInt32 valueSize, UpdatePeriod period, UInt32 interval, float deltaEpsilon)
Constructs a calculator code request (requestType = RequestType::Calculated) with given update period...
DataRequest()
Default constructor. Properties must be set to valid values, either later or inline,...
DataRequest(UInt32 requestId, String ^ simVarName, String ^ unitName, Byte simVarIndex, UInt32 valueSize, UpdatePeriod period, UInt32 interval, float deltaEpsilon)
Constructs a request for a named Simulator Variable (requestType = RequestType::Named and ‘varTypePre...
DataRequest(UInt32 requestId, String ^ simVarName, String ^ unitName, Byte simVarIndex, UInt32 valueSize)
Constructs a request for a named Simulator Variable (requestType = RequestType::Named and ‘varTypePre...
DataRequestRecord inherits and extends WASimCommander::CLI::Structs::DataRequest with data pertinent ...
array< Byte > ^ data
Value data array.
bool tryConvert([Out] T % result)
Tries to populate a value reference of the desired type T and returns true or false depending on if t...
time_t lastUpdate
Timestamp of last data update in ms since epoch.
String ^ ToString() override
Serializes this DataRequestRecord to string for debugging purposes.
bool tryConvert([Out] String ^ % result)
Overload for String type results. This will simply load whatever bytes are in the data array into a S...
Structure for delivering list results, eg. of local variables sent from Server.
Structure to hold data for registered (reusable) calculator events. Used to submit events with WASimC...
Structure for using with WASimClient::getVariable() and WASimClient::setVariable() to specify informa...
VariableRequest(Char variableType, int variableId, int unitId)
Construct a variable request for specified variable type ('A', 'L', etc), numeric variable ID,...
VariableRequest(String ^ localVariableName)
Construct a variable request a Local variable ('L') with the specified name.
VariableRequest(String ^ simVariableName, String ^ unitName, Byte simVarIndex)
Construct a variable request for a Simulator variable ('A') with given name, named unit specifier,...
VariableRequest(int localVariableId)
Construct a variable request a Local variable ('L') with the specified numeric ID.
VariableRequest(Char variableType, int variableId)
Construct a variable request for specified variable type ('A', 'L', etc) and numeric variable ID.
VariableRequest(int simVariableId, int unitId, Byte simVarIndex)
Construct a variable request for a Simulator variable ('A') with given variable ID,...
VariableRequest(Char variableType, String ^ variableName)
Construct a variable request for specified variable type ('A', 'L', etc) and variable name.
VariableRequest(String ^ localVariableName, bool createVariable)
Construct a variable request for a Local ('L') variable with the specified name.
VariableRequest(Char variableType, String ^ variableName, String ^ unitName)
Construct a variable request for specified variable type ('A', 'L', etc), variable name,...
VariableRequest(String ^ localVariableName, bool createVariable, String ^ unitName)
Construct a variable request for a Local ('L') variable with the specified name.
DataRequestRecord inherits and extends WASimCommander::DataRequest with data pertinent for use by a d...
std::vector< uint8_t > data
Value data array.
Structure to hold data for registered (reusable) calculator events. Used to submit events with WASimC...
std::string name
Optional custom name for this event. The name is for use with SimConnect_MapClientEventToSimEvent(id,...
std::string code
The calculator code string to execute as the event action. The code is pre-compiled and stored on the...
uint32_t eventId
A unique ID for this event. The ID can later be used to modify, trigger, or remove this event.
Structure for using with WASimClient::getVariable() and WASimClient::setVariable() to specify informa...
Command data structure. The member contents depend on the command type as described in each command t...
Structure for variable value subscription requests.