Improved DataManager string Get and Set methods.
- The Get method no longer assumes unknown drefs are floats. - The Get method now properly accounts for the fact that the dref data type is a bitflag. - Binary drefs are now properly read and packed into `values`. - This is a rather inefficient process, as it quadruples the number of bytes we have to send out. Should look into better ways to do this in the future. - The Set method now handles data types correctly. - The Set method now supports binary datarefs. - Improved logging of edge cases. - Added a check to warn about setting read-only datarefs if verbose logging is enabled.
This commit is contained in:
@@ -198,72 +198,127 @@ namespace XPC
|
||||
{
|
||||
xdref = XPLMFindDataRef(dref.c_str());
|
||||
}
|
||||
if (!xdref)
|
||||
if (!xdref) // DREF does not exist
|
||||
{
|
||||
// DREF does not exist
|
||||
#if LOG_VERBOSITY > 0
|
||||
Log::WriteLine("[DMAN] ERROR: invalid DREF");
|
||||
Log::FormatLine("[DMAN] ERROR: invalid DREF %s", dref.c_str());
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
XPLMDataTypeID dataType = XPLMGetDataRefTypes(xdref);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] Get DREF %s (x:%X) type %i", dref.c_str(), xdref, dataType);
|
||||
Log::FormatLine("[DMAN] Get DREF %s (x:%X) Type: %i", dref.c_str(), xdref, dataType);
|
||||
#endif
|
||||
switch (dataType)
|
||||
// XPLMDataTypeID is a bit flag, so it may contain more than one of the
|
||||
// following types. We prefer types as close to float as possible.
|
||||
if ((dataType & 2) == 2) // Float
|
||||
{
|
||||
case 1: // Integer
|
||||
{
|
||||
values[0] = (float)XPLMGetDatai(xdref);
|
||||
values[0] = XPLMGetDataf(xdref);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine(" value was %i", (int)values[0]);
|
||||
Log::FormatLine("[DMAN] -- value was %f", values[0]);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
case 4: // Double
|
||||
{
|
||||
values[0] = (float)XPLMGetDatad(xdref);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine(" value was %f", values[0]);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
case 8: // Float Array
|
||||
if ((dataType & 8) == 8) // Float array
|
||||
{
|
||||
int drefSize = XPLMGetDatavf(xdref, NULL, 0, 0);
|
||||
drefSize = min(drefSize, size);
|
||||
if (drefSize > size)
|
||||
{
|
||||
#if LOG_VERBOSITY > 1
|
||||
Log::WriteLine("[DMAN] WARN: dref size is larger than available space");
|
||||
Log::FormatLine(" Actual dref size: %i, Available size: %i", drefSize, size);
|
||||
#endif
|
||||
drefSize = size;
|
||||
}
|
||||
XPLMGetDatavf(xdref, values, 0, drefSize);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine(" value count was %i", drefSize);
|
||||
Log::FormatLine("[DMAN] -- value count was %i", drefSize);
|
||||
#endif
|
||||
return drefSize;
|
||||
}
|
||||
case 16: // Integer Array
|
||||
if ((dataType & 4) == 4) // Double
|
||||
{
|
||||
int iValues[64];
|
||||
values[0] = (float)XPLMGetDatad(xdref);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] -- value was %f", values[0]);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
if ((dataType & 1) == 1) // Integer
|
||||
{
|
||||
values[0] = (float)XPLMGetDatai(xdref);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] -- value was %i", (int)values[0]);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
if ((dataType & 16) == 16) // Integer array
|
||||
{
|
||||
int iValues[200];
|
||||
int drefSize = XPLMGetDatavi(xdref, NULL, 0, 0);
|
||||
drefSize = min(drefSize, size);
|
||||
drefSize = min(drefSize, 64);
|
||||
if (drefSize > size)
|
||||
{
|
||||
#if LOG_VERBOSITY > 1
|
||||
Log::WriteLine("[DMAN] WARN: dref size is larger than available space");
|
||||
Log::FormatLine(" Actual dref size: %i, Available size: %i", drefSize, size);
|
||||
#endif
|
||||
drefSize = size;
|
||||
}
|
||||
if (drefSize > 200)
|
||||
{
|
||||
#if LOG_VERBOSITY > 1
|
||||
Log::WriteLine("[DMAN] WARN: dref size is larger than temp buffer");
|
||||
Log::FormatLine(" Actual dref size: %i, Temp buffer size: 200", drefSize);
|
||||
#endif
|
||||
drefSize = 200;
|
||||
}
|
||||
XPLMGetDatavi(xdref, iValues, 0, drefSize);
|
||||
for (int i = 0; i < drefSize; ++i)
|
||||
{
|
||||
values[i] = (float)iValues[i];
|
||||
}
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine(" value count was %i", drefSize);
|
||||
Log::FormatLine("[DMAN] -- value count was %i", drefSize);
|
||||
#endif
|
||||
return drefSize;
|
||||
}
|
||||
default: // Assume float
|
||||
if ((dataType & 32) == 32) // Byte array
|
||||
{
|
||||
values[0] = XPLMGetDataf(xdref);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine(" value was %f", values[0]);
|
||||
char bValues[1024];
|
||||
int drefSize = XPLMGetDatab(xdref, NULL, 0, 0);
|
||||
if (drefSize > size)
|
||||
{
|
||||
#if LOG_VERBOSITY > 1
|
||||
Log::WriteLine("[DMAN] WARN: dref size is larger than available space");
|
||||
Log::FormatLine(" Actual dref size: %i, Available size: %i", drefSize, size);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
drefSize = size;
|
||||
}
|
||||
if (drefSize > 1024)
|
||||
{
|
||||
#if LOG_VERBOSITY > 1
|
||||
Log::WriteLine("[DMAN] WARN: dref size is larger than temp buffer");
|
||||
Log::FormatLine(" Actual dref size: %i, Temp buffer size: 1024", drefSize);
|
||||
#endif
|
||||
drefSize = 1024;
|
||||
}
|
||||
XPLMGetDatab(xdref, bValues, 0, drefSize);
|
||||
for (int i = 0; i < drefSize; ++i)
|
||||
{
|
||||
values[i] = (float)bValues[i];
|
||||
}
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] -- value count was %i", drefSize);
|
||||
#endif
|
||||
return drefSize;
|
||||
}
|
||||
|
||||
// No match
|
||||
#if LOG_VERBOSITY > 0
|
||||
Log::WriteLine("[DMAN] ERROR: Unrecognized data type.");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
double DataManager::GetDouble(DREF dref, char aircraft)
|
||||
@@ -372,14 +427,11 @@ namespace XPC
|
||||
{
|
||||
xdref = XPLMFindDataRef(dref.c_str());
|
||||
}
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] Setting DREF %s (x:%X) (%i values)", dref.c_str(), xdref, size);
|
||||
#endif
|
||||
if (!xdref)
|
||||
{
|
||||
// DREF does not exist
|
||||
#if LOG_VERBOSITY > 0
|
||||
Log::WriteLine("[DMAN] ERROR: invalid DREF");
|
||||
Log::FormatLine("[DMAN] ERROR: invalid DREF %s", dref.c_str());
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -392,44 +444,118 @@ namespace XPC
|
||||
}
|
||||
|
||||
XPLMDataTypeID dataType = XPLMGetDataRefTypes(xdref);
|
||||
switch (dataType)
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] Setting DREF %s (x:%X) Type: %i", dref.c_str(), xdref, dataType);
|
||||
#endif
|
||||
if ((dataType & 2) == 2) // Float
|
||||
{
|
||||
case 1: // Integer
|
||||
{
|
||||
XPLMSetDatai(xdref, (int)values[0]);
|
||||
break;
|
||||
XPLMSetDataf(xdref, values[0]);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] -- value was %f", values[0]);
|
||||
#endif
|
||||
}
|
||||
case 4: // Double
|
||||
{
|
||||
XPLMSetDatad(xdref, values[0]);
|
||||
break;
|
||||
}
|
||||
case 8: // Float Array
|
||||
else if ((dataType & 8) == 8) // Float Array
|
||||
{
|
||||
int drefSize = XPLMGetDatavf(xdref, NULL, 0, 0);
|
||||
#if LOG_VERBOSITY > 1
|
||||
if (size > drefSize)
|
||||
{
|
||||
Log::WriteLine("[DMAN] WARN: Provided size is larger than actual dref size");
|
||||
Log::FormatLine(" Actual dref size: %i, Provided buffer size: %i", drefSize, size);
|
||||
}
|
||||
#endif
|
||||
drefSize = min(drefSize, size);
|
||||
XPLMSetDatavf(xdref, values, 0, drefSize);
|
||||
break;
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] -- value count was %i", drefSize);
|
||||
#endif
|
||||
}
|
||||
case 16: // Integer Array
|
||||
else if ((dataType & 4) == 4) // Double
|
||||
{
|
||||
int iValues[64];
|
||||
XPLMSetDatad(xdref, values[0]);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] -- value was %f", values[0]);
|
||||
#endif
|
||||
}
|
||||
else if ((dataType & 1) == 1) // Integer
|
||||
{
|
||||
XPLMSetDatai(xdref, (int)values[0]);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] -- value was %i", (int)values[0]);
|
||||
#endif
|
||||
}
|
||||
else if ((dataType & 16) == 16) // Integer Array
|
||||
{
|
||||
int iValues[200];
|
||||
int drefSize = XPLMGetDatavi(xdref, NULL, 0, 0);
|
||||
#if LOG_VERBOSITY > 1
|
||||
if (size > drefSize)
|
||||
{
|
||||
Log::WriteLine("[DMAN] WARN: Provided size is larger than actual dref size");
|
||||
Log::FormatLine(" Actual dref size: %i, Provided buffer size: %i", drefSize, size);
|
||||
}
|
||||
#endif
|
||||
drefSize = min(drefSize, size);
|
||||
drefSize = min(drefSize, 64);
|
||||
if (drefSize > 200)
|
||||
{
|
||||
#if LOG_VERBOSITY > 1
|
||||
Log::WriteLine("[DMAN] WARN: drefSize larger than temp buffer size.");
|
||||
Log::FormatLine(" Actual dref size: %i, Temp buffer size: 200", drefSize);
|
||||
#endif
|
||||
drefSize = 200;
|
||||
}
|
||||
for (int i = 0; i < drefSize; ++i)
|
||||
{
|
||||
iValues[i] = (int)values[i];
|
||||
}
|
||||
XPLMSetDatavi(xdref, iValues, 0, drefSize);
|
||||
break;
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] -- value count was %i", drefSize);
|
||||
#endif
|
||||
}
|
||||
default: // Assume float
|
||||
else if ((dataType & 32) == 32) // Byte Array
|
||||
{
|
||||
XPLMSetDataf(xdref, values[0]);
|
||||
break;
|
||||
char bValues[1024];
|
||||
int drefSize = XPLMGetDatab(xdref, NULL, 0, 0);
|
||||
#if LOG_VERBOSITY > 1
|
||||
if (size > drefSize)
|
||||
{
|
||||
Log::WriteLine("[DMAN] WARN: Provided size is larger than actual dref size");
|
||||
Log::FormatLine(" Actual dref size: %i, Provided buffer size: %i", drefSize, size);
|
||||
}
|
||||
#endif
|
||||
drefSize = min(drefSize, size);
|
||||
if (drefSize > 1024)
|
||||
{
|
||||
#if LOG_VERBOSITY > 1
|
||||
Log::WriteLine("[DMAN] WARN: drefSize larger than temp buffer size.");
|
||||
Log::FormatLine(" Actual dref size: %i, Temp buffer size: 1024", drefSize);
|
||||
#endif
|
||||
drefSize = 1024;
|
||||
}
|
||||
for (int i = 0; i < drefSize; ++i)
|
||||
{
|
||||
bValues[i] = (char)values[i];
|
||||
}
|
||||
XPLMSetDatab(xdref, bValues, 0, drefSize);
|
||||
#if LOG_VERBOSITY > 4
|
||||
Log::FormatLine("[DMAN] -- value count was %i", drefSize);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOG_VERBOSITY > 0
|
||||
Log::WriteLine("[DMAN] ERROR: Unknown type.");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if LOG_VERBOSITY > 1
|
||||
if (!XPLMCanWriteDataRef(xdref))
|
||||
{
|
||||
Log::WriteLine("[DMAN] WARN: dref is not writable. The write operation probably failed.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DataManager::SetGear(float gear, bool immediate, char aircraft)
|
||||
|
||||
@@ -137,10 +137,10 @@ namespace XPC
|
||||
/// Marshals data between the plugin and X-Plane.
|
||||
///
|
||||
/// \author Jason Watkins
|
||||
/// \version 1.0
|
||||
/// \since 1.0
|
||||
/// \version 1.0.1
|
||||
/// \since 1.0.0
|
||||
/// \date Intial Version: 2015-04-13
|
||||
/// \date Last Updated: 2015-04-13
|
||||
/// \date Last Updated: 2015-04-29
|
||||
class DataManager
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user