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();
105 XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
106 if (std::strlen(filename) < 1 || std::strlen(path) < 1)
108 WARNING_LOG(
"Aircraft changed, but NO path or file name");
124 if (!m_framePeriodSampler) {
return {}; }
125 const auto result = m_framePeriodSampler->getFrameStats();
126 return std::make_tuple(
static_cast<double>(std::get<0>(result)),
static_cast<double>(std::get<1>(result)),
127 static_cast<double>(std::get<2>(result)),
static_cast<double>(std::get<3>(result)));
132 if (m_framePeriodSampler)
134 m_framePeriodSampler->m_totalMetersShort = 0;
135 m_framePeriodSampler->m_totalSecondsLate = 0;
141 if (text.empty()) {
return; }
146 U8It
begin(text.begin(), text.end());
147 auto characters = std::distance(
begin, U8It(text.end(), text.end()));
148 std::vector<CMessage::string> wrappedLines;
150 for (; characters > lineLength; characters -= lineLength)
152 auto end = std::next(
begin, lineLength);
153 wrappedLines.emplace_back(
begin.base,
end.base);
154 wrappedLines.back() += ellipsis;
157 if (characters > 0) { wrappedLines.emplace_back(
begin.base, text.end()); }
158 for (
const auto &line : wrappedLines)
161 { line,
static_cast<float>(red),
static_cast<float>(green),
static_cast<float>(blue) });
164 if (!m_messages.
isVisible() && m_popupMessageWindow) { m_messages.
toggle(); }
166 if (m_disappearMessageWindow)
168 m_disappearMessageWindowTime = std::chrono::system_clock::now() +
169 std::chrono::milliseconds(std::max(m_disapperMessageWindowTimeMs, 1500));
177 XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
185 XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
193 XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
202 XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
209 std::string liveryPath = m_liveryPath.
get();
210 if (liveryPath.empty()) {
return {}; }
213 liveryPath.pop_back();
220 XPLMGetVersions(&version,
nullptr,
nullptr);
221 if (version > 5000) { version /= 10; }
222 return version / 100;
228 XPLMGetVersions(&version,
nullptr,
nullptr);
229 if (version > 5000) { version /= 10; }
230 return version % 100;
236 XPLMGetSystemPath(path);
243 XPLMGetPrefsPath(path);
257 this->updateMessageBoxFromSettings();
259 if (w) {
INFO_LOG(
"Written new config file"); }
262 static const char *introspection_service = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
263 #include "org.swift_project.xswiftbus.service.xml"
269 const std::string sender = message.
getSender();
270 const dbus_uint32_t serial = message.
getSerial();
302 else if (message.
getMethodName() ==
"getOwnAircraftSituationData")
305 const double lat = m_latitude.
get();
306 const double lon = m_longitude.
get();
307 const double alt = m_elevation.
get();
308 const double gs = m_groundSpeed.get();
309 const double pitch = m_pitch.
get();
310 const double roll = m_roll.
get();
311 const double trueHeading = m_heading.
get();
312 const double qnh = m_qnhInhg.
get();
326 else if (message.
getMethodName() ==
"getOwnAircraftVelocityData")
329 const double velocityX = m_velocityX.
get();
330 const double velocityY = m_velocityY.
get();
331 const double velocityZ = m_velocityZ.
get();
332 const double pitchVelocity = m_pitchVelocity.
get();
333 const double rollVelocity = m_rollVelocity.
get();
334 const double headingVelocity = m_headingVelocity.
get();
346 else if (message.
getMethodName() ==
"getOwnAircraftCom1Data")
349 const int active = m_com1Active.
get();
350 const int standby = m_com1Standby.
get();
351 const double volume = m_com1Volume.
get();
364 else if (message.
getMethodName() ==
"getOwnAircraftCom2Data")
367 const int active = m_com2Active.
get();
368 const int standby = m_com2Standby.
get();
369 const double volume = m_com2Volume.
get();
385 const int code = m_xpdrCode.
get();
386 const int mode = m_xpdrMode.
get();
387 const bool id = m_xpdrIdent.
get();
399 const bool beaconLightsOn = m_beaconLightsOn.
get();
400 const bool landingLightsOn = m_landingLightsOn.
get();
401 const bool navLightsOn = m_navLightsOn.
get();
402 const bool strobeLightsOn = m_strobeLightsOn.
get();
403 const bool taxiLightsOn = m_taxiLightsOn.
get();
417 const double flapsReployRatio = m_flapsReployRatio.
get();
418 const double gearReployRatio = m_gearReployRatio.
getAt(0);
419 const double speedBrakeRatio = m_speedBrakeRatio.
get();
430 else if (message.
getMethodName() ==
"getOwnAircraftModelData")
446 else if (message.
getMethodName() ==
"getAircraftModelFilename")
450 else if (message.
getMethodName() ==
"getAircraftModelString")
466 else if (message.
getMethodName() ==
"getAircraftDescription")
478 else if (message.
getMethodName() ==
"getXPlaneInstallationPath")
482 else if (message.
getMethodName() ==
"getXPlanePreferencesPath")
536 else if (message.
getMethodName() ==
"getIndicatedAirspeedKias")
754 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
757 return DBUS_HANDLER_RESULT_HANDLED;
762 if (m_sceneryIsLoading.
get() != m_sceneryWasLoading)
765 m_sceneryWasLoading = m_sceneryIsLoading.
get();
770 if (m_disappearMessageWindowTime != std::chrono::system_clock::time_point() &&
771 std::chrono::system_clock::now() > m_disappearMessageWindowTime && m_messages.
isVisible())
774 m_disappearMessageWindowTime = std::chrono::system_clock::time_point();
780 void CService::emitAircraftModelChanged(
const std::string &path,
const std::string &filename,
781 const std::string &livery,
const std::string &icao,
782 const std::string &modelString,
const std::string &name,
783 const std::string &description)
786 XSWIFTBUS_SERVICE_OBJECTPATH, XSWIFTBUS_SERVICE_INTERFACENAME,
"aircraftModelChanged");
798 void CService::emitSceneryLoaded()
800 CDBusMessage signal =
805 void CService::updateMessageBoxFromSettings()
809 if (values.size() >= 6)
811 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.