4 #ifndef SWIFT_SIM_XSWIFTBUS_DATAREFS_H
5 #define SWIFT_SIM_XSWIFTBUS_DATAREFS_H
9 #include <XPLM/XPLMDataAccess.h>
10 #include <XPLM/XPLMUtilities.h>
20 # include "datarefs.inc"
30 DataRefImpl(
char const *name) : m_ref(XPLMFindDataRef(name))
34 XPLMDebugString(
"Missing dataref:");
35 XPLMDebugString(name);
36 XPLMDebugString(
"\n");
40 bool isValid()
const {
return m_ref; }
53 class ArrayDataRefImpl
56 ArrayDataRefImpl(
char const *name,
int size) : m_ref(XPLMFindDataRef(name)), m_size(size)
60 XPLMDebugString(
"Missing dataref:");
61 XPLMDebugString(name);
62 XPLMDebugString(
"\n");
66 bool isValid()
const {
return m_ref; }
69 void implSetAll(T *
const);
72 void implGetAll(T *)
const;
75 void implSetAt(
int index, T);
78 T implGetAt(
int index)
const;
90 template <
class DataRefTraits>
93 static_assert(!DataRefTraits::is_array,
"this is an array dataref");
97 DataRef() : DataRefImpl(DataRefTraits::name()) {}
108 static_assert(DataRefTraits::writable,
"read-only dataref");
109 DataRefImpl::implSet(d);
121 using DataRefImpl::isValid;
129 template <
class DataRefTraits>
132 static_assert(DataRefTraits::is_array,
"not an array dataref");
136 ArrayDataRef() : ArrayDataRefImpl(DataRefTraits::name(), DataRefTraits::size) {}
148 void setAll(std::array<DataRefType, DataRefSize>
const &a)
150 static_assert(DataRefTraits::writable,
"read-only dataref");
151 ArrayDataRefImpl::implSetAll<DataRefType>(a.data());
155 std::array<DataRefType, DataRefSize>
getAll()
const
157 std::array<DataRefType, DataRefSize> result;
158 ArrayDataRefImpl::implGetAll<DataRefType>(result.data());
165 static_assert(DataRefTraits::writable,
"read-only dataref");
166 ArrayDataRefImpl::implSetAt(index, d);
170 DataRefType getAt(
int index)
const {
return ArrayDataRefImpl::implGetAt<DataRefType>(index); }
172 using ArrayDataRefImpl::isValid;
180 template <
class DataRefTraits>
183 static_assert(DataRefTraits::is_array,
"not an array dataref");
191 XPLMDebugString(
"Missing dataref:");
192 XPLMDebugString(DataRefTraits::name());
193 XPLMDebugString(
"\n");
209 static_assert(DataRefTraits::writable,
"read-only dataref");
210 assert((s.size() + 1) <= (DataRefTraits::size - offset));
211 XPLMSetDatab(m_ref, (
void *)s.c_str(), (
int)offset, (
int)s.size() + 1);
217 std::string s(size, 0);
218 XPLMGetDatab(m_ref, &s[0], (
int)offset, (
int)size);
219 size = s.find(
char(0));
220 if (size != std::string::npos) s.resize(size);
237 template <
class DataRefTraits>
244 if constexpr (std::is_same_v<typename DataRefTraits::type, int>)
246 m_ref = XPLMRegisterDataAccessor(DataRefTraits::name(), xplmType_Int, 0, readInt,
nullptr,
nullptr,
247 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
248 nullptr,
this,
nullptr);
250 else if constexpr (std::is_same_v<typename DataRefTraits::type, std::string>)
252 m_ref = XPLMRegisterDataAccessor(DataRefTraits::name(), xplmType_Data, 0,
nullptr,
nullptr,
nullptr,
253 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
254 readData,
nullptr,
this,
nullptr);
256 else { static_assert(dependent_false<typename DataRefTraits::type>,
"Unsupported custom dataref type"); }
259 XPLMDebugString(
"Missing dataref:");
260 XPLMDebugString(DataRefTraits::name());
261 XPLMDebugString(
"\n");
271 if (m_ref) { XPLMUnregisterDataAccessor(m_ref); }
275 static typename DataRefTraits::type
readInt(
void *refcon)
281 static int readData(
void *refcon,
void *out,
int offset,
int max_length)
283 if constexpr (std::is_same_v<typename DataRefTraits::type, std::string>)
285 std::string_view sv(
reinterpret_cast<CustomDataRef *
>(refcon)->get());
286 const size_t start = std::clamp<size_t>(offset, 0, sv.size());
287 const size_t remaining_length = sv.size() - start;
288 const auto len = std::min(
static_cast<size_t>(max_length), remaining_length);
289 sv = sv.substr(start, len);
290 std::memcpy(out, sv.data(), len);
291 return static_cast<int>(len);
298 bool isValid()
const {
return m_ref !=
nullptr; }
301 void set(
typename DataRefTraits::type val) { m_datarefVal = val; }
304 const typename DataRefTraits::type &
get()
const {
return m_datarefVal; }
314 inline void DataRefImpl::implSet<int>(
int d)
316 XPLMSetDatai(m_ref, d);
319 inline void DataRefImpl::implSet<float>(
float d)
321 XPLMSetDataf(m_ref, d);
324 inline void DataRefImpl::implSet<double>(
double d)
326 XPLMSetDatad(m_ref, d);
329 inline int DataRefImpl::implGet<int>()
const
331 return XPLMGetDatai(m_ref);
334 inline float DataRefImpl::implGet<float>()
const
336 return XPLMGetDataf(m_ref);
339 inline double DataRefImpl::implGet<double>()
const
341 return XPLMGetDatad(m_ref);
345 inline void ArrayDataRefImpl::implSetAll(
int const *v)
347 XPLMSetDatavi(m_ref,
const_cast<int *
>(v), 0, m_size);
350 inline void ArrayDataRefImpl::implSetAll(
float const *v)
352 XPLMSetDatavf(m_ref,
const_cast<float *
>(v), 0, m_size);
355 inline void ArrayDataRefImpl::implGetAll(
int *v)
const
357 XPLMGetDatavi(m_ref, &v[0], 0, m_size);
360 inline void ArrayDataRefImpl::implGetAll(
float *v)
const
362 XPLMGetDatavf(m_ref, &v[0], 0, m_size);
366 inline void ArrayDataRefImpl::implSetAt<int>(
int i,
int d)
369 XPLMSetDatavi(m_ref, &d, i, 1);
372 inline void ArrayDataRefImpl::implSetAt<float>(
int i,
float d)
375 XPLMSetDatavf(m_ref, &d, i, 1);
378 inline int ArrayDataRefImpl::implGetAt<int>(
int i)
const
382 XPLMGetDatavi(m_ref, &d, i, 1);
386 inline float ArrayDataRefImpl::implGetAt<float>(
int i)
const
390 XPLMGetDatavf(m_ref, &d, i, 1);
Class providing access to a single X-Plane array dataref.
static constexpr auto DataRefSize
Array dataref size.
std::array< DataRefType, DataRefSize > getAll() const
Get the value of the whole array.
void setAt(int index, DataRefType d)
Set the value of a single element (if it is writable)
void setAll(std::array< DataRefType, DataRefSize > const &a)
Set the value of the whole array (if it is writable)
ArrayDataRef()
Constructor.
DataRefType getAt(int index) const
Get the value of a single element.
typename DataRefTraits::type DataRefType
Dataref type.
DataRefTraits TraitsType
Traits type.
Class providing a custom variable + dataref Currently only readable int and std::string datarefs are ...
bool isValid() const
True if the dataref exists.
static int readData(void *refcon, void *out, int offset, int max_length)
Read data/string.
DataRefTraits::type m_datarefVal
Dataref content.
CustomDataRef()
Constructor.
const DataRefTraits::type & get() const
Get the value.
static DataRefTraits::type readInt(void *refcon)
Read integer.
void set(typename DataRefTraits::type val)
Set the value.
XPLMDataRef m_ref
X-Plane dataref.
Class providing access to a single X-Plane dataref.
void set(DataRefType d)
Set the value of the dataref (if it is writable)
void setAsDouble(double d)
Set as integer, avoids cast warnings such as "possible loss of data".
void setAsInt(int d)
Set as integer, avoids cast warnings such as "possible loss of data".
typename DataRefTraits::type DataRefType
Dataref type.
DataRefTraits TraitsType
Traits type.
DataRefType get() const
Get the value of the dataref.
Class providing access to a single X-Plane string dataref.
void set(std::string const &s)
Set the value of the whole string (if it is writable)
std::string getSubstr(size_t offset, size_t size) const
Get the value of part of the string.
StringDataRef()
Constructor.
bool isValid() const
True if the dataref exists.
void setSubstr(size_t offset, std::string const &s)
Set the value of part of the string (if it is writable)
std::string get() const
Get the value of the whole string.
Plugin loaded by X-Plane which publishes a DBus service.
constexpr bool dependent_false
Helper to conditionally fail compilation if no matching constexpr if case is found.