mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-23 07:15:35 +08:00
refs #248 C++ API wrapper for the X-Plane Plugin SDK's C API for accessing datarefs
This commit is contained in:
188
src/xbus/datarefs.h
Normal file
188
src/xbus/datarefs.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / contributors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BLACKSIM_XBUS_DATAREFS_H
|
||||
#define BLACKSIM_XBUS_DATAREFS_H
|
||||
|
||||
//! \file
|
||||
|
||||
#include <XPLM/XPLMDataAccess.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
#include "datarefs.inc"
|
||||
|
||||
namespace XBus
|
||||
{
|
||||
|
||||
//! \private
|
||||
class DataRefImpl
|
||||
{
|
||||
public:
|
||||
DataRefImpl(char const* name) : m_ref(XPLMFindDataRef(name))
|
||||
{
|
||||
//TODO warn if m_ref is NULL
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void implSet(T);
|
||||
|
||||
template <typename T>
|
||||
T implGet() const;
|
||||
|
||||
private:
|
||||
XPLMDataRef m_ref;
|
||||
};
|
||||
|
||||
//! \private
|
||||
class ArrayDataRefImpl
|
||||
{
|
||||
public:
|
||||
ArrayDataRefImpl(char const* name, size_t size) : m_ref(XPLMFindDataRef(name)), m_size(size)
|
||||
{
|
||||
//TODO warn if m_ref is NULL
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void implSetAll(std::vector<T> const&);
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> implGetAll() const;
|
||||
|
||||
template <typename T>
|
||||
void implSetAt(size_t index, T);
|
||||
|
||||
template <typename T>
|
||||
T implGetAt(size_t index);
|
||||
|
||||
private:
|
||||
XPLMDataRef m_ref;
|
||||
size_t const m_size;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class providing access to a single X-Plane dataref
|
||||
* \tparam DataRefTraits The trait class representing the dataref.
|
||||
* See the xplane::data namespace and http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html
|
||||
*/
|
||||
template<class DataRefTraits>
|
||||
class DataRef : private DataRefImpl
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
DataRef() : DataRefImpl(DataRefTraits::name()) {}
|
||||
|
||||
//! Traits type
|
||||
typedef DataRefTraits TraitsType;
|
||||
|
||||
//! Dataref type
|
||||
typedef typename DataRefTraits::type DataRefType;
|
||||
|
||||
//! Set the value of the dataref (if it is writable)
|
||||
void set(DataRefType d) { DataRefImpl::implSet(d); }
|
||||
|
||||
//! Get the value of the dataref
|
||||
DataRefType get() const { return DataRefImpl::implGet<DataRefType>(); }
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class providing access to a single X-Plane array dataref
|
||||
* \tparam DataRefTraits The trait class representing the dataref.
|
||||
* See the xplane::data namespace and http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html
|
||||
*/
|
||||
template<class DataRefTraits>
|
||||
class ArrayDataRef : private ArrayDataRefImpl
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
ArrayDataRef() : ArrayDataRefImpl(DataRefTraits::name(), DataRefTraits::size) {}
|
||||
|
||||
//! Traits type
|
||||
typedef DataRefTraits TraitsType;
|
||||
|
||||
//! Dataref type
|
||||
typedef typename DataRefTraits::type DataRefType;
|
||||
|
||||
//! Set the value of the whole array (if it is writable)
|
||||
void setAll(std::vector<DataRefType> const& a) { ArrayDataRefImpl::implSetAll(a); }
|
||||
|
||||
//! Get the value of the whole array
|
||||
std::vector<DataRefType> getAll() const { return ArrayDataRefImpl::implGetAll<DataRefType>(); }
|
||||
|
||||
//! Set the value of a single element (if it is writable)
|
||||
void setAt(size_t index, DataRefType d) { ArrayDataRefImpl::implSetAt(index, d); }
|
||||
|
||||
//! Get the value of a single element
|
||||
DataRefType getAt(size_t index) const { return ArrayDataRefImpl::implGetAt<DataRefType>(index); }
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class providing access to a single X-Plane string dataref
|
||||
* \tparam DataRefTraits The trait class representing the dataref.
|
||||
* See the xplane::data namespace and http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html
|
||||
*/
|
||||
template<class DataRefTraits>
|
||||
class StringDataRef
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
StringDataRef() : m_ref(XPLMFindDataRef(DataRefTraits::name()))
|
||||
{
|
||||
//TODO warn if m_ref is NULL
|
||||
}
|
||||
|
||||
//! Set the value of the whole string (if it is writable)
|
||||
void set(std::string const& s) { setSubstr(0, s); }
|
||||
|
||||
//! Get the value of the whole string
|
||||
std::string get() const { return getSubstr(0, DataRefTraits::size); }
|
||||
|
||||
//! Set the value of part of the string (if it is writable)
|
||||
void setSubstr(size_t offset, std::string const& s)
|
||||
{ assert((s.size() + 1) <= (DataRefTraits::size - offset)); XPLMSetDatab(m_ref, s.c_str(), offset, s.size() + 1); }
|
||||
|
||||
//! Get the value of part of the string
|
||||
std::string getSubstr(size_t offset, size_t size) const
|
||||
{ std::string s (size, 0); XPLMGetDatab(m_ref, &s[0], (int)offset, (int)size); size = s.find(char(0)); if (size != std::string::npos) s.resize(size); return s; }
|
||||
|
||||
private:
|
||||
XPLMDataRef m_ref;
|
||||
};
|
||||
|
||||
template <>
|
||||
inline void DataRefImpl::implSet<int>(int d) { XPLMSetDatai(m_ref, d); }
|
||||
template <>
|
||||
inline void DataRefImpl::implSet<float>(float d) { XPLMSetDataf(m_ref, d); }
|
||||
template <>
|
||||
inline void DataRefImpl::implSet<double>(double d) { XPLMSetDatad(m_ref, d); }
|
||||
template <>
|
||||
inline int DataRefImpl::implGet<int>() const { return XPLMGetDatai(m_ref); }
|
||||
template <>
|
||||
inline float DataRefImpl::implGet<float>() const { return XPLMGetDataf(m_ref); }
|
||||
template <>
|
||||
inline double DataRefImpl::implGet<double>() const { return XPLMGetDatad(m_ref); }
|
||||
|
||||
template <>
|
||||
inline void ArrayDataRefImpl::implSetAll<int>(std::vector<int> const& v) { assert(v.size() <= m_size); XPLMSetDatavi(m_ref, const_cast<int*>(&v[0]), 0, (int)v.size()); }
|
||||
template <>
|
||||
inline void ArrayDataRefImpl::implSetAll<float>(std::vector<float> const& v) { assert(v.size() <= m_size); XPLMSetDatavf(m_ref, const_cast<float*>(&v[0]), 0, (int)v.size()); }
|
||||
template <>
|
||||
inline std::vector<int> ArrayDataRefImpl::implGetAll<int>() const { std::vector<int> v (m_size); XPLMGetDatavi(m_ref, &v[0], 0, (int)m_size); return v; }
|
||||
template <>
|
||||
inline std::vector<float> ArrayDataRefImpl::implGetAll<float>() const { std::vector<float> v (m_size); XPLMGetDatavf(m_ref, &v[0], 0, (int)m_size); return v; }
|
||||
|
||||
template <>
|
||||
inline void ArrayDataRefImpl::implSetAt<int>(size_t i, int d) { assert(i <= m_size); XPLMSetDatavi(m_ref, &d, (int)i, 1); }
|
||||
template <>
|
||||
inline void ArrayDataRefImpl::implSetAt<float>(size_t i, float d) { assert(i <= m_size); XPLMSetDatavf(m_ref, &d, (int)i, 1); }
|
||||
template <>
|
||||
inline int ArrayDataRefImpl::implGetAt<int>(size_t i) { assert(i <= m_size); int d; XPLMGetDatavi(m_ref, &d, (int)i, 1); return d; }
|
||||
template <>
|
||||
inline float ArrayDataRefImpl::implGetAt<float>(size_t i) { assert(i <= m_size); float d; XPLMGetDatavf(m_ref, &d, (int)i, 1); return d; }
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // guard
|
||||
44489
src/xbus/datarefs.inc
Normal file
44489
src/xbus/datarefs.inc
Normal file
File diff suppressed because it is too large
Load Diff
142
src/xbus/datarefs.pl
Normal file
142
src/xbus/datarefs.pl
Normal file
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Script to generate C++ traits classes for all X-Plane datarefs.
|
||||
#
|
||||
# Copyright (C) 2014 VATSIM Community / contributors
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub usage
|
||||
{
|
||||
print STDERR <<"EOF";
|
||||
This program generates C++ traits classes that describe the data refs of the
|
||||
X-Plane Plugin SDK.
|
||||
Usage:
|
||||
$0 <XPLANEPATH>
|
||||
Arguments:
|
||||
<XPLANEPATH> - directory in which X-Plane is installed
|
||||
EOF
|
||||
exit 1;
|
||||
}
|
||||
|
||||
@ARGV == 1 or usage();
|
||||
|
||||
my $filename = "$ARGV[0]/Resources/plugins/DataRefs.txt";
|
||||
|
||||
my $fh;
|
||||
unless (open $fh, '<', $filename)
|
||||
{
|
||||
print STDERR "$filename: $!\n";
|
||||
usage();
|
||||
}
|
||||
|
||||
my %hierarchy;
|
||||
|
||||
while (<$fh>)
|
||||
{
|
||||
chomp;
|
||||
next unless m"\t";
|
||||
|
||||
my @fields = split "\t";
|
||||
next unless @fields >= 3;
|
||||
|
||||
my($dataref, $type, $writable, $extra, $comment) = @fields;
|
||||
$writable = $writable eq 'y' ? 'true' : 'false';
|
||||
$comment ||= 'Undocumented dataref';
|
||||
my $size;
|
||||
$type =~ m"(\w+)\[(\d+)\]" and ($type, $size) = ($1, $2);
|
||||
|
||||
my @namespaces = split '/', $dataref;
|
||||
my $class = pop @namespaces;
|
||||
$class =~ s(\])()g;
|
||||
$class =~ s(\[)(_)g;
|
||||
$class =~ s((plane\d+)_sla1_ratio)(${1}_slat_ratio);
|
||||
$class eq 'type' and $class .= '_';
|
||||
|
||||
my $namespace = \%hierarchy;
|
||||
$namespace = ($namespace->{$_} ||= {}) foreach @namespaces;
|
||||
|
||||
$namespace->{$class} = [$dataref, $type, $size, $writable, $extra, $comment];
|
||||
}
|
||||
|
||||
close $fh;
|
||||
|
||||
our $indent = ' ';
|
||||
print <<"EOF";
|
||||
// DO NOT EDIT
|
||||
// This file automatically generated from DataRefs.txt by $0
|
||||
|
||||
//! X-Plane Plugin SDK C++ API
|
||||
namespace xplane
|
||||
{
|
||||
${indent}//! X-Plane datarefs
|
||||
${indent}namespace data
|
||||
${indent}{
|
||||
EOF
|
||||
|
||||
recurse(\%hierarchy, 2);
|
||||
|
||||
print <<"EOF";
|
||||
${indent}}
|
||||
}
|
||||
EOF
|
||||
|
||||
sub recurse
|
||||
{
|
||||
my($hash, $indentLevel) = @_;
|
||||
|
||||
my $in = $indent x $indentLevel;
|
||||
foreach my $key (sort keys %$hash)
|
||||
{
|
||||
if (ref $hash->{$key} eq 'HASH')
|
||||
{
|
||||
print <<"EOF";
|
||||
${in}//! $key datarefs
|
||||
${in}namespace $key
|
||||
${in}{
|
||||
EOF
|
||||
|
||||
recurse($hash->{$key}, $indentLevel + 1);
|
||||
|
||||
print <<"EOF";
|
||||
${in}}
|
||||
|
||||
EOF
|
||||
}
|
||||
else
|
||||
{
|
||||
my($name, $type, $size, $writable, $extra, $comment) = @{ $hash->{$key} };
|
||||
|
||||
defined $extra and $extra ne '???' and $comment .= " ($extra)";
|
||||
|
||||
print <<"EOF";
|
||||
${in}//! $comment
|
||||
${in}struct $key
|
||||
${in}{
|
||||
${in}${indent}//! Dataref name
|
||||
${in}${indent}static const char *name() { return "$name"; }
|
||||
${in}${indent}//! Can be written to?
|
||||
${in}${indent}static const bool writable = $writable;
|
||||
EOF
|
||||
|
||||
print <<"EOF" if $type =~ m(int|float|double);
|
||||
${in}${indent}//! Dataref type
|
||||
${in}${indent}typedef $type type;
|
||||
EOF
|
||||
|
||||
print <<"EOF" if defined $size;
|
||||
${in}${indent}//! Size of array dataref
|
||||
${in}${indent}static const size_t size = $size;
|
||||
EOF
|
||||
|
||||
print <<"EOF";
|
||||
${in}};
|
||||
|
||||
EOF
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user