6 #include <XPLM/XPLMPlanes.h>
7 #include <XPLM/XPLMUtilities.h>
20 using namespace swift::misc::simulation::xplane::qtfreeutils;
25 struct CService::FramePeriodSampler :
public CDrawable
27 DataRef<xplane::data::sim::operation::misc::frame_rate_period> m_thisFramePeriod;
28 DataRef<xplane::data::sim::time::framerate_period> m_thisFramePeriodXP11;
29 DataRef<xplane::data::sim::time::total_flight_time_sec> m_secondsSinceReset;
30 DataRef<xplane::data::sim::flightmodel::position::groundspeed> m_groundSpeed;
32 std::vector<float> m_samples;
34 float m_totalOverBudget = 0;
35 float m_totalMetersShort = 0;
36 float m_totalSecondsLate = 0;
37 size_t m_lastSampleIndex = 0;
38 static constexpr
size_t c_maxSampleCount = 500;
39 static constexpr
float c_framePeriodBudget = 0.05f;
41 FramePeriodSampler() : CDrawable(xplm_Phase_Window, true) {}
43 std::tuple<float, float, float, float> getFrameStats()
45 if (m_total < 0.001f) {
return {}; }
46 const float fps = m_samples.size() / m_total;
47 const float ratio = 1 - m_totalOverBudget / m_total;
48 const float miles = m_totalMetersShort / 1852.0f;
49 const float minutes = m_totalSecondsLate / 60.0f;
51 m_totalOverBudget = 0;
53 m_lastSampleIndex = 0;
54 return std::make_tuple(fps, ratio, miles, minutes);
58 virtual void draw() override
61 m_thisFramePeriodXP11.isValid() ? m_thisFramePeriodXP11.get() : m_thisFramePeriod.get();
63 ++m_lastSampleIndex %= c_maxSampleCount;
64 if (m_samples.size() == c_maxSampleCount)
66 auto &oldSample = m_samples[m_lastSampleIndex];
68 if (oldSample > c_framePeriodBudget) { m_totalOverBudget -= oldSample - c_framePeriodBudget; }
71 else { m_samples.push_back(current); }
74 if (current > c_framePeriodBudget)
76 m_totalOverBudget += current - c_framePeriodBudget;
78 if (m_secondsSinceReset.get() > 10)
80 const float metersShort = m_groundSpeed.get() * std::max(0.0f, current - c_framePeriodBudget);
81 m_totalMetersShort += metersShort;
82 if (m_groundSpeed.get() > 1.0f)
84 m_totalSecondsLate += std::max(0.0f, current - c_framePeriodBudget);
92 :
CDBusObject(settingsProvider), m_framePeriodSampler(std::make_unique<FramePeriodSampler>())
94 this->updateMessageBoxFromSettings();
95 m_framePeriodSampler->show();
104 XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
105 if (std::strlen(filename) < 1 || std::strlen(path) < 1)
107 WARNING_LOG(
"Aircraft changed, but NO path or file name");
123 if (!m_framePeriodSampler) {
return {}; }
124 const auto result = m_framePeriodSampler->getFrameStats();
125 return std::make_tuple(
static_cast<double>(std::get<0>(result)),
static_cast<double>(std::get<1>(result)),
126 static_cast<double>(std::get<2>(result)),
static_cast<double>(std::get<3>(result)));
131 if (m_framePeriodSampler)
133 m_framePeriodSampler->m_totalMetersShort = 0;
134 m_framePeriodSampler->m_totalSecondsLate = 0;
140 if (text.empty()) {
return; }
145 U8It
begin(text.begin(), text.end());
146 auto characters = std::distance(
begin, U8It(text.end(), text.end()));
147 std::vector<CMessage::string> wrappedLines;
149 for (; characters > lineLength; characters -= lineLength)
151 auto end = std::next(
begin, lineLength);
152 wrappedLines.emplace_back(
begin.base,
end.base);
153 wrappedLines.back() += ellipsis;
156 if (characters > 0) { wrappedLines.emplace_back(
begin.base, text.end()); }
157 for (
const auto &line : wrappedLines)
160 { line,
static_cast<float>(red),
static_cast<float>(green),
static_cast<float>(blue) });
163 if (!m_messages.
isVisible() && m_popupMessageWindow) { m_messages.
toggle(); }
165 if (m_disappearMessageWindow)
167 m_disappearMessageWindowTime = std::chrono::system_clock::now() +
168 std::chrono::milliseconds(std::max(m_disapperMessageWindowTimeMs, 1500));
176 XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
184 XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
192 XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
201 XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
208 std::string liveryPath = m_liveryPath.
get();
209 if (liveryPath.empty()) {
return {}; }
212 liveryPath.pop_back();
219 XPLMGetVersions(&version,
nullptr,
nullptr);
220 if (version > 5000) { version /= 10; }
221 return version / 100;
227 XPLMGetVersions(&version,
nullptr,
nullptr);
228 if (version > 5000) { version /= 10; }
229 return version % 100;
235 XPLMGetSystemPath(path);
242 XPLMGetPrefsPath(path);
256 this->updateMessageBoxFromSettings();
258 if (w) {
INFO_LOG(
"Written new config file"); }
261 static const char *introspection_service = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
262 #include "org.swift_project.xswiftbus.service.xml"
268 const std::string sender = message.
getSender();
269 const dbus_uint32_t serial = message.
getSerial();
301 else if (message.
getMethodName() ==
"getOwnAircraftSituationData")
304 const double lat = m_latitude.
get();
305 const double lon = m_longitude.
get();
306 const double alt = m_elevation.
get();
307 const double gs = m_groundSpeed.get();
308 const double pitch = m_pitch.
get();
309 const double roll = m_roll.
get();
310 const double trueHeading = m_heading.
get();
311 const double qnh = m_qnhInhg.
get();
325 else if (message.
getMethodName() ==
"getOwnAircraftVelocityData")
328 const double velocityX = m_velocityX.
get();
329 const double velocityY = m_velocityY.
get();
330 const double velocityZ = m_velocityZ.
get();
331 const double pitchVelocity = m_pitchVelocity.
get();
332 const double rollVelocity = m_rollVelocity.
get();
333 const double headingVelocity = m_headingVelocity.
get();
345 else if (message.
getMethodName() ==
"getOwnAircraftCom1Data")
348 const int active = m_com1Active.
get();
349 const int standby = m_com1Standby.
get();
350 const double volume = m_com1Volume.
get();
363 else if (message.
getMethodName() ==
"getOwnAircraftCom2Data")
366 const int active = m_com2Active.
get();
367 const int standby = m_com2Standby.
get();
368 const double volume = m_com2Volume.
get();
384 const int code = m_xpdrCode.
get();
385 const int mode = m_xpdrMode.
get();
386 const bool id = m_xpdrIdent.
get();
398 const bool beaconLightsOn = m_beaconLightsOn.
get();
399 const bool landingLightsOn = m_landingLightsOn.
get();
400 const bool navLightsOn = m_navLightsOn.
get();
401 const bool strobeLightsOn = m_strobeLightsOn.
get();
402 const bool taxiLightsOn = m_taxiLightsOn.
get();
416 const double flapsReployRatio = m_flapsReployRatio.
get();
417 const double gearReployRatio = m_gearReployRatio.
getAt(0);
418 const double speedBrakeRatio = m_speedBrakeRatio.
get();
429 else if (message.
getMethodName() ==
"getOwnAircraftModelData")
445 else if (message.
getMethodName() ==
"getAircraftModelFilename")
449 else if (message.
getMethodName() ==
"getAircraftModelString")
465 else if (message.
getMethodName() ==
"getAircraftDescription")
477 else if (message.
getMethodName() ==
"getXPlaneInstallationPath")
481 else if (message.
getMethodName() ==
"getXPlanePreferencesPath")
535 else if (message.
getMethodName() ==
"getIndicatedAirspeedKias")
753 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
756 return DBUS_HANDLER_RESULT_HANDLED;
761 if (m_sceneryIsLoading.
get() != m_sceneryWasLoading)
764 m_sceneryWasLoading = m_sceneryIsLoading.
get();
769 if (m_disappearMessageWindowTime != std::chrono::system_clock::time_point() &&
770 std::chrono::system_clock::now() > m_disappearMessageWindowTime && m_messages.
isVisible())
773 m_disappearMessageWindowTime = std::chrono::system_clock::time_point();
779 void CService::emitAircraftModelChanged(
const std::string &path,
const std::string &filename,
780 const std::string &livery,
const std::string &icao,
781 const std::string &modelString,
const std::string &name,
782 const std::string &description)
785 XSWIFTBUS_SERVICE_OBJECTPATH, XSWIFTBUS_SERVICE_INTERFACENAME,
"aircraftModelChanged");
797 void CService::emitSceneryLoaded()
799 CDBusMessage signal =
804 void CService::updateMessageBoxFromSettings()
808 if (values.size() >= 6)
810 m_messages.
setValues(values[0], values[1], values[2], values[3], values[4], values[5]);
DataRefType getAt(int index) const
Get the value of a single element.
bool wantsReply() const
Does this message want a reply?
void appendArgument(bool value)
Append argument. Make sure to call.
void getArgument(int &value)
Read single argument. Make sure to call.
std::string getSender() const
Get the message sender.
std::string_view getMethodName() const
Get the called method name.
dbus_uint32_t getSerial() const
Get the message serial. This is usally required for reply message.
std::string_view getInterfaceName() const
Get the called interface name.
void beginArgumentRead()
Begin reading arguments.
void beginArgumentWrite()
Begin writing argument.
static CDBusMessage createReply(const std::string &destination, dbus_uint32_t serial)
Creates a DBus message containing a DBus reply.
static CDBusMessage createSignal(const std::string &path, const std::string &interfaceName, const std::string &signalName)
Creates a DBus message containing a DBus signal.
void queueDBusCall(const std::function< void()> &func)
Queue a DBus call to be executed in a different thread.
void maybeSendEmptyDBusReply(bool wantsReply, const std::string &destination, dbus_uint32_t serial)
Maybe sends an empty DBus reply (acknowledgement)
void sendDBusMessage(const CDBusMessage &message)
Send DBus message.
void invokeQueuedDBusCalls()
Invoke all pending DBus calls. They will be executed in the calling thread.
void sendDBusReply(const std::string &destination, dbus_uint32_t serial, const T &argument)
Send DBus reply.
bool isVisible() const
Is message box currently visible?
void addMessage(const CMessage &message)
Add a new message to the bottom of the list.
int maxLineLength() const
Returns the maximum number of characters per line.
void setValues(int leftPx, int topPx, int rightPx, int bottomPx, int lines, int durationMs)
Set margin values.
void toggle()
Toggles the visibility of the message box.
int getXPlaneVersionMinor() const
Get minor version number.
bool isCom1Transmitting() const
Is COM1 transmitting?
std::string getAircraftName() const
Get name of current aircraft model.
double getRollDeg() const
Get aircraft roll in degrees.
float getCom1Volume() const
Get the COM1 volume 0..1.
double getFlapsDeployRatio() const
Get flaps deploy ratio, where 0.0 is flaps fully retracted, and 1.0 is flaps fully extended.
float getCom2Volume() const
Get the COM2 volume 0..1.
int getCom1ActiveKhz() const
Get the current COM1 active frequency in kHz.
virtual ~CService()
Destructor.
double getLongitudeDeg() const
Get aircraft longitude in degrees.
double getAltitudeMslM() const
Get aircraft altitude in meters.
double getGroundSpeedMps() const
Get aircraft groundspeed in meters per second.
std::string getAircraftIcaoCode() const
Get the ICAO code of the current aircraft model.
std::string getAircraftModelString() const
Get canonical swift model string of current aircraft model.
bool isPaused() const
True if sim is paused.
int getCom2StandbyKhz() const
Get the current COM2 standby frequency in kHz.
double getTrueAirspeedKias() const
Get aircraft TAS in meters per second.
double getRollRadPerSec() const
Get aircraft angular velocity in radians per second.
int getXPlaneVersionMajor() const
Get major version number.
bool isCom2Receiving() const
Is COM2 receiving?
std::tuple< double, double, double, double > getFrameStats()
Frames-per-second, averaged over the last 500 frames, or since this function was last called,...
void resetFrameTotals()
Reset the monitoring of total miles and minutes lost due to low frame rate.
double getLocalZVelocityMps() const
Get aircraft local velocity in world coordinates meters per second.
DBusHandlerResult dbusMessageHandler(const CDBusMessage &message)
DBus message handler.
bool getTaxiLightsOn() const
Get whether taxi lights are on.
double getPitchRadPerSec() const
Get aircraft angular velocity in radians per second.
double getSpeedBrakeRatio() const
Get the ratio how much the speedbrakes surfaces are extended (0.0 is fully retracted,...
double getHeadingRadPerSec() const
Get aircraft angular velocity in radians per second.
double getPitchDeg() const
Get aircraft pitch in degrees above horizon.
std::string getXPlaneInstallationPath() const
Get root of X-Plane install path.
std::string getCommitHash() const
Returns the SHA1 of the last commit that could influence xswiftbus.
void onAircraftModelChanged()
Called by XPluginReceiveMessage when the model changes.
int getTransponderCode() const
Get the current transponder code in decimal.
std::string getXPlanePreferencesPath() const
Get full path to X-Plane preferences file.
double getGearDeployRatio() const
Get gear deploy ratio, where 0 is up and 1 is down.
double getLocalYVelocityMps() const
Get aircraft local velocity in world coordinates meters per second.
bool getTransponderIdent() const
Get whether we are currently squawking ident.
int getCom1StandbyKhz() const
Get the current COM1 standby frequency in kHz.
bool getAnyWheelOnGround() const
Get whether any wheel is on the ground.
void setTransponderMode(int mode)
Set the current transponder mode (depends on the aircraft, 0 and 1 usually mean standby,...
void setCom1StandbyKhz(int freq)
Set the current COM1 standby frequency in kHz.
std::string getVersionNumber() const
Returns the xswiftbus version number.
bool getLandingLightsOn() const
Get whether landing lights are on.
bool isCom1Receiving() const
Is COM1 receiving?
void onSceneryLoaded()
Called by XPluginReceiveMessage when some scenery is loaded.
double getHeightAglM() const
Get aircraft height in meters.
std::string getAircraftDescription() const
Get the description of the current aircraft model.
void setTransponderCode(int code)
Set the current transponder code in decimal.
void setDisappearMessageWindowTimeMs(int durationMs)
Enable/disable message window disappearing after x ms.
double getIndicatedAirspeedKias() const
Get aircraft IAS in knots.
void setCom2ActiveKhz(int freq)
Set the current COM2 active frequency in kHz.
double getLocalXVelocityMps() const
Get aircraft local velocity in world coordinates meters per second.
bool getBeaconLightsOn() const
Get whether beacon lights are on.
int process()
Perform generic processing.
double getPressureAltitudeFt() const
Get aircraft pressure altitude in feet in standard atmosphere in X-Plane 12. NaN in earlier versions ...
bool getStrobeLightsOn() const
Get whether strobe lights are on.
std::string getAircraftModelPath() const
Get full path to current aircraft model.
void addTextMessage(const std::string &text, double red, double green, double blue)
Add a text message to the on-screen display, with RGB components in the range [0,1].
double getLatitudeDeg() const
Get aircraft latitude in degrees.
int getCom2ActiveKhz() const
Get the current COM2 active frequency in kHz.
bool isCom2Transmitting() const
Is COM2 transmitting?
double getTrueHeadingDeg() const
Get aircraft true heading in degrees.
std::string getAircraftLivery() const
Get current aircraft livery.
double getQNHInHg() const
Get barometric pressure at sea level in inches of mercury.
void setCom1ActiveKhz(int freq)
Set the current COM1 active frequency in kHz.
void setCom2StandbyKhz(int freq)
Set the current COM2 standby frequency in kHz.
int getTransponderMode() const
Get the current transponder mode (depends on the aircraft, 0 and 1 usually mean standby,...
int getNumberOfEngines() const
Get the number of engines of current aircraft.
std::string getSettingsJson() const
Get settings in JSON format.
bool isUsingRealTime() const
True if sim time is tracking operating system time.
double getGroundElevation() const
Get elevation of ground under the plane in meters.
std::vector< double > getEngineN1Percentage() const
Get the N1 speed as percent of max (per engine)
std::string getAircraftModelFilename() const
Get base filename of current aircraft model.
void setSettingsJson(const std::string &jsonString)
Set settings.
bool getAllWheelsOnGround() const
Get whether all wheels are on the ground.
bool getNavLightsOn() const
Get whether nav lights are on.
void setSettings(const CSettings &settings)
Set settings.
CSettings getSettings() const
Get settings.
bool writeConfig(bool tcas, bool debug)
Write a config file with these new values.
xswiftbus/swift side settings class, JSON capable, shared among all services
Something owning the settings.
DataRefType get() const
Get the value of the dataref.
std::string get() const
Get the value of the whole string.
std::vector< int > getMessageBoxValuesVector() const
Left, top, right, bottom, lines, duration, color(freq, priv, serv, stat, sup)
bool isLogRenderPhases() const
Debug messages?
bool isTcasEnabled() const
TCAS functionality?
std::string convertToString() const
Convert to string.
std::string toXSwiftBusJsonString() const
As JSON string.
bool parseXSwiftBusString(const std::string &json)
Load and parse config file.
Plugin loaded by X-Plane which publishes a DBus service.
T::const_iterator begin(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
T::const_iterator end(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
AcfProperties extractAcfProperties(const std::string &filePath)
Extract ACF properties from an aircraft file.
std::string getFileName(const std::string &filePath)
Get filename (including all extensions) from a filePath.
decltype(Private::empty_u8string()) string
String type.
std::string modelString
Generated model string.
std::string modelName
Model name.
Encoding-aware iterator adaptor for std::u8string.
#define INFO_LOG(msg)
Logger convenience macros.
#define WARNING_LOG(msg)
Logger convenience macros.