swift
Loading...
Searching...
No Matches
plugin.cpp
1// SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3
4#include "plugin.h"
5
6#include <cmath>
7#include <functional>
8#include <thread>
9
10#include "XPLM/XPLMProcessing.h"
11#include "service.h"
12#include "traffic.h"
13#include "utils.h"
14
15namespace
16{
17 inline std::string xswiftbusServiceName() { return std::string("org.swift-project.xswiftbus"); }
18} // namespace
19
20namespace XSwiftBus
21{
23 : m_dbusConnection(std::make_shared<CDBusConnection>()), m_menu(CMenu::mainMenu().subMenu("xswiftbus"))
24 {
25 m_showHideLabelsMenuItem = m_menu.appendItem(
26 "Show/Hide Aircraft Labels", [this] { m_traffic->setDrawingLabels(!m_traffic->isDrawingLabels()); });
27 m_enableDisableXPlaneAtisMenuItem = m_menu.appendItem(
28 "Enable/Disable X-Plane ATIS", [this] { m_atisEnabled.set(m_atisEnabled.get() ? 0 : 1); });
29 m_messageWindowSubMenu = m_menu.subMenu("Message Window");
30 m_toggleMessageWindowMenuItem =
31 m_messageWindowSubMenu.appendItem("Show/Hide", [this] { m_service->toggleMessageBoxVisibility(); });
32 m_popupMessageWindowMenuItem =
33 m_messageWindowSubMenu.checkableItem("Pop up Window on new Message", true, [this](bool checked) {
34 m_popupMessageWindowMenuItem.setChecked(!checked);
35 m_service->setPopupMessageWindow(!checked);
36 });
37 m_disappearMessageWindowMenuItem =
38 m_messageWindowSubMenu.checkableItem("Hide Message Window automatically", true, [this](bool checked) {
39 m_disappearMessageWindowMenuItem.setChecked(!checked);
40 m_service->setDisappearMessageWindow(!checked);
41 });
42 m_planeViewSubMenu = m_menu.subMenu("Follow Plane View");
43 m_planeViewOwnAircraftMenuItem = m_planeViewSubMenu.appendItem(
44 "Own Aircraft", [this] { m_traffic->setFollowedAircraft(CTraffic::ownAircraftString()); });
45
46 /*m_dbusThread = std::thread([this]()
47 {
48 while(!m_shouldStop)
49 {
50 m_dbusConnection->runBlockingEventLoop();
51 }
52 });*/
53
54 // Delay the start of xswiftbus.
55 // http://www.xsquawkbox.net/xpsdk/mediawiki/DeferredInitialization
56 XPLMRegisterFlightLoopCallback(startServerDeferred, -1, this);
57
58 m_atisSaved = m_atisEnabled.get();
59 m_atisEnabled.set(0);
60 }
61
63 {
64 m_atisEnabled.set(m_atisSaved);
65
66 XPLMUnregisterFlightLoopCallback(flightLoopCallback, this);
67 m_dbusConnection->close();
68 m_shouldStop = true;
69 if (m_dbusThread.joinable())
70 {
71 m_dbusThread.join();
72 }
73 }
74
75 void CPlugin::readConfig()
76 {
78 const std::string configFilePath =
79 g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep + "xswiftbus.conf";
80 m_pluginConfig.setFilePath(configFilePath);
81 m_pluginConfig.parse();
82 m_pluginConfig.print();
83 }
84
85 void CPlugin::startServer()
86 {
87 XPLMRegisterFlightLoopCallback(flightLoopCallback, -1, this);
88
89 readConfig();
90
91 m_service = std::make_unique<CService>(this);
92 m_traffic = std::make_unique<CTraffic>(this);
93
94 m_traffic->setPlaneViewMenu(m_planeViewSubMenu);
95
96 if (m_pluginConfig.getDBusMode() == CConfig::DBusP2P)
97 {
98 m_dbusP2PServer = std::make_unique<CDBusServer>();
99
100 // FIXME: make listen address configurable
101 std::string listenAddress =
102 "tcp:host=" + m_pluginConfig.getDBusAddress() + ",port=" + std::to_string(m_pluginConfig.getDBusPort());
103 if (!m_dbusP2PServer->listen(listenAddress))
104 {
105 m_service->addTextMessage("xswiftbus startup failed!", 255, 0, 0);
106 return;
107 }
108 m_dbusP2PServer->setDispatcher(&m_dbusDispatcher);
109
110 m_dbusP2PServer->setNewConnectionFunc([this](const std::shared_ptr<CDBusConnection> &conn) {
111 m_dbusConnection = conn;
112 m_dbusConnection->setDispatcher(&m_dbusDispatcher);
113 m_service->setDBusConnection(m_dbusConnection);
114 m_service->registerDBusObjectPath(m_service->InterfaceName(), m_service->ObjectPath());
115 m_traffic->setDBusConnection(m_dbusConnection);
116 m_traffic->registerDBusObjectPath(m_traffic->InterfaceName(), m_traffic->ObjectPath());
117 });
118 }
119 else
120 {
121 // Todo: retry if it fails
122 bool success = m_dbusConnection->connect(CDBusConnection::SessionBus);
123
124 if (!success)
125 {
126 // Print error
127 return;
128 }
129
130 m_dbusConnection->setDispatcher(&m_dbusDispatcher);
131 m_dbusConnection->requestName(xswiftbusServiceName());
132
133 m_service->setDBusConnection(m_dbusConnection);
134 m_service->registerDBusObjectPath(m_service->InterfaceName(), m_service->ObjectPath());
135 m_traffic->setDBusConnection(m_dbusConnection);
136 m_traffic->registerDBusObjectPath(m_traffic->InterfaceName(), m_traffic->ObjectPath());
137 }
138
140 const std::string msg = "xswiftbus " + m_service->getVersionNumber() + " started.";
141 INFO_LOG(msg);
142 m_service->addTextMessage(msg, 0, 255, 255);
143 }
144
146 {
147 if (m_service)
148 {
149 m_service->onAircraftModelChanged();
150 m_service->resetFrameTotals();
151 }
152 }
153
155 {
156 if (m_service)
157 {
158 m_service->resetFrameTotals();
159 }
160 }
161
163 {
164 if (m_service)
165 {
166 m_service->onSceneryLoaded();
167 }
168 }
169
170 float CPlugin::startServerDeferred(float, float, int, void *refcon)
171 {
172 auto *plugin = static_cast<CPlugin *>(refcon);
173 if (!plugin->m_isRunning)
174 {
175 plugin->startServer();
176 plugin->m_isRunning = true;
177 INFO_LOG("xswiftbus plugin started (deferred)");
178 }
179 return 0;
180 }
181
182 float CPlugin::flightLoopCallback(float, float, int, void *refcon)
183 {
184 auto *plugin = static_cast<CPlugin *>(refcon);
185
186 plugin->m_dbusDispatcher.runOnce();
187 if (plugin->m_service)
188 {
189 plugin->m_service->process();
190 }
191 if (plugin->m_traffic)
192 {
193 plugin->m_traffic->process();
194 }
195 return -1;
196 }
197} // namespace XSwiftBus
int getDBusPort() const
Get current DBus server port.
Definition config.h:46
void setFilePath(const std::string &filePath)
Set config file path.
Definition config.h:31
const std::string & getDBusAddress() const
Get current DBus server address.
Definition config.h:43
void print()
Print the current configuration to the X-Plane log.
Definition config.cpp:93
DBusMode getDBusMode() const
Get current DBus mode.
Definition config.h:40
void parse()
Load and parse config file.
Definition config.cpp:25
Class-based interface to X-Plane SDK menus.
Definition menus.h:63
Main plugin class.
Definition plugin.h:42
CPlugin()
Constructor.
Definition plugin.cpp:22
void onSceneryLoaded()
Called by XPluginReceiveMessage when some scenery is loaded.
Definition plugin.cpp:162
void onAircraftRepositioned()
Called by XPluginReceiveMessage when the aircraft is positioned at an airport.
Definition plugin.cpp:154
void onAircraftModelChanged()
Called by XPluginReceiveMessage when the model is changed.
Definition plugin.cpp:145
~CPlugin()
Destructor.
Definition plugin.cpp:62
static const std::string & ownAircraftString()
Returns the own aircraft string to be used as callsign for setFollowedAircraft().
Definition traffic.h:135
Plugin loaded by X-Plane which publishes a DBus service.
Definition command.h:14
std::string g_xplanePath
Absolute xplane path.
std::string g_sep
Platform specific dir separator.
void initXPlanePath()
Init global xplane path.
#define INFO_LOG(msg)
Logger convenience macros.
Definition utils.h:49