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);
230 constexpr
bool dependent_false =
false;
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); }
274 static typename DataRefTraits::type readInt(
void *refcon)
276 return reinterpret_cast<CustomDataRef *
>(refcon)->get();
279 static int readData(
void *refcon,
void *out,
int offset,
int max_length)
281 if constexpr (std::is_same_v<typename DataRefTraits::type, std::string>)
283 std::string_view sv(
reinterpret_cast<CustomDataRef *
>(refcon)->get());
284 const size_t start = std::clamp<size_t>(offset, 0, sv.size());
285 const size_t remaining_length = sv.size() - start;
286 const auto len = std::min(
static_cast<size_t>(max_length), remaining_length);
287 sv = sv.substr(start, len);
288 std::memcpy(out, sv.data(), len);
289 return static_cast<int>(len);
296 bool isValid()
const {
return m_ref !=
nullptr; }
299 void set(
typename DataRefTraits::type val) { m_datarefVal = val; }
302 const typename DataRefTraits::type &
get()
const {
return m_datarefVal; }
305 typename DataRefTraits::type m_datarefVal;
309 inline void DataRefImpl::implSet<int>(
int d)
311 XPLMSetDatai(m_ref, d);
314 inline void DataRefImpl::implSet<float>(
float d)
316 XPLMSetDataf(m_ref, d);
319 inline void DataRefImpl::implSet<double>(
double d)
321 XPLMSetDatad(m_ref, d);
324 inline int DataRefImpl::implGet<int>()
const
326 return XPLMGetDatai(m_ref);
329 inline float DataRefImpl::implGet<float>()
const
331 return XPLMGetDataf(m_ref);
334 inline double DataRefImpl::implGet<double>()
const
336 return XPLMGetDatad(m_ref);
340 inline void ArrayDataRefImpl::implSetAll(
int const *v)
342 XPLMSetDatavi(m_ref,
const_cast<int *
>(v), 0, m_size);
345 inline void ArrayDataRefImpl::implSetAll(
float const *v)
347 XPLMSetDatavf(m_ref,
const_cast<float *
>(v), 0, m_size);
350 inline void ArrayDataRefImpl::implGetAll(
int *v)
const
352 XPLMGetDatavi(m_ref, &v[0], 0, m_size);
355 inline void ArrayDataRefImpl::implGetAll(
float *v)
const
357 XPLMGetDatavf(m_ref, &v[0], 0, m_size);
361 inline void ArrayDataRefImpl::implSetAt<int>(
int i,
int d)
364 XPLMSetDatavi(m_ref, &d, i, 1);
367 inline void ArrayDataRefImpl::implSetAt<float>(
int i,
float d)
370 XPLMSetDatavf(m_ref, &d, i, 1);
373 inline int ArrayDataRefImpl::implGetAt<int>(
int i)
const
377 XPLMGetDatavi(m_ref, &d, i, 1);
381 inline float ArrayDataRefImpl::implGetAt<float>(
int i)
const
385 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 \hint Currently only readable int and std::string dataref...
bool isValid() const
True if the dataref exists.
CustomDataRef()
Constructor.
const DataRefTraits::type & get() const
Get the value.
void set(typename DataRefTraits::type val)
Set the value.
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.