Files
pilotclient/src/xswiftbus/plugin.cpp
Roland Winklmeier 9bb75a6f2e Rotate camera in follow plane view only if space key is pressed
This commits merges the two orbit plane functions together in CTraffic.
The separation was necessary since XSwiftBus needed to be started manually
and until started, the pointer to CTraffic was invalid. Since XSwiftBus
is started automatically, it can be merged into one function again.
This commit also adds the feature to rotate the camera only if the space key
is pressed. This is equal to how FSX/P3D do it. Using the right mouse was
not possible, since X-Plane SDK does not offer that option.

ref T360
2018-11-04 17:42:42 +01:00

185 lines
6.5 KiB
C++

/* Copyright (C) 2013
* swift Project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "plugin.h"
#include "service.h"
#include "traffic.h"
#include "weather.h"
#include "utils.h"
#include "XPLM/XPLMProcessing.h"
#include <cmath>
#include <functional>
#include <thread>
namespace {
inline std::string xswiftbusServiceName() {
return std::string("org.swift-project.xswiftbus");
}
}
namespace XSwiftBus
{
CPlugin::CPlugin()
: m_dbusConnection(std::make_shared<CDBusConnection>()), m_menu(CMenu::mainMenu().subMenu("XSwiftBus"))
{
// m_startServerMenuItem = m_menu.item("Start XSwiftBus", [this]{ startServer(CDBusConnection::SessionBus); });
m_showHideLabelsMenuItem = m_menu.item("Show/Hide Aircraft Labels", [this]
{
m_traffic->setDrawingLabels(!m_traffic->isDrawingLabels());
});
m_messageWindowSubMenu = m_menu.subMenu("Message Window");
m_toggleMessageWindowMenuItem = m_messageWindowSubMenu.item("Show/Hide", [this]
{
m_service->toggleMessageBoxVisibility();
});
m_popupMessageWindowMenuItem = m_messageWindowSubMenu.checkableItem("Pop up Window on new Nessage", true, [this] (bool checked)
{
m_popupMessageWindowMenuItem.setChecked(!checked);
m_service->setPopupMessageWindow(!checked);
});
m_disappearMessageWindowMenuItem = m_messageWindowSubMenu.checkableItem("Hide Message Window after 5s", true, [this] (bool checked)
{
m_disappearMessageWindowMenuItem.setChecked(!checked);
m_service->setDisappearMessageWindow(!checked);
});
m_planeViewSubMenu = m_menu.subMenu("Follow Plane View");
planeViewOwnAircraftMenuItem = m_planeViewSubMenu.item("Own Aircraft", [this]
{
m_traffic->setFollowedAircraft(m_traffic->ownAircraftString());
});
/*m_dbusThread = std::thread([this]()
{
while(!m_shouldStop)
{
m_dbusConnection->runBlockingEventLoop();
}
});*/
// Delay the start of XSwiftBus.
// http://www.xsquawkbox.net/xpsdk/mediawiki/DeferredInitialization
XPLMRegisterFlightLoopCallback(startServerDeferred, -1, this);
}
CPlugin::~CPlugin()
{
XPLMUnregisterFlightLoopCallback(flightLoopCallback, this);
m_dbusConnection->close();
m_shouldStop = true;
if (m_dbusThread.joinable()) { m_dbusThread.join(); }
}
void CPlugin::readConfig()
{
initXPlanePath();
auto configFilePath = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep + "xswiftbus.conf";
m_pluginConfig.setFilePath(configFilePath);
m_pluginConfig.parse();
m_pluginConfig.print();
}
void CPlugin::startServer()
{
XPLMRegisterFlightLoopCallback(flightLoopCallback, -1, this);
readConfig();
m_service = std::make_unique<CService>();
m_traffic = std::make_unique<CTraffic>();
m_weather = std::make_unique<CWeather>();
m_traffic->setPlaneViewMenu(m_planeViewSubMenu);
if (m_pluginConfig.getDBusMode() == CConfig::DBusP2P)
{
m_dbusP2PServer = std::make_unique<CDBusServer>();
// FIXME: make listen address configurable
std::string listenAddress = "tcp:host=" + m_pluginConfig.getDBusAddress() + ",port=" + std::to_string(m_pluginConfig.getDBusPort());
m_dbusP2PServer->listen(listenAddress);
m_dbusP2PServer->setDispatcher(&m_dbusDispatcher);
m_dbusP2PServer->setNewConnectionFunc([this](const std::shared_ptr<CDBusConnection> &conn)
{
m_dbusConnection = conn;
m_dbusConnection->setDispatcher(&m_dbusDispatcher);
m_service->setDBusConnection(m_dbusConnection);
m_service->registerDBusObjectPath(m_service->InterfaceName(), m_service->ObjectPath());
m_traffic->setDBusConnection(m_dbusConnection);
m_traffic->registerDBusObjectPath(m_traffic->InterfaceName(), m_traffic->ObjectPath());
m_weather->setDBusConnection(m_dbusConnection);
m_weather->registerDBusObjectPath(m_weather->InterfaceName(), m_weather->ObjectPath());
});
}
else
{
// Todo: retry if it fails
bool success = m_dbusConnection->connect(CDBusConnection::SessionBus);
if (!success)
{
// Print error
return;
}
m_dbusConnection->setDispatcher(&m_dbusDispatcher);
m_dbusConnection->requestName(xswiftbusServiceName());
m_service->setDBusConnection(m_dbusConnection);
m_service->registerDBusObjectPath(m_service->InterfaceName(), m_service->ObjectPath());
m_traffic->setDBusConnection(m_dbusConnection);
m_traffic->registerDBusObjectPath(m_traffic->InterfaceName(), m_traffic->ObjectPath());
m_weather->setDBusConnection(m_dbusConnection);
m_weather->registerDBusObjectPath(m_weather->InterfaceName(), m_weather->ObjectPath());
}
INFO_LOG("XSwiftBus started.");
}
void CPlugin::onAircraftModelChanged()
{
if (m_service)
{
m_service->onAircraftModelChanged();
}
}
void CPlugin::onAircraftRepositioned()
{
if (m_service)
{
m_service->updateAirportsInRange();
}
}
float CPlugin::startServerDeferred(float, float, int, void *refcon)
{
auto *plugin = static_cast<CPlugin *>(refcon);
if (! plugin->m_isRunning)
{
plugin->startServer();
plugin->m_isRunning = true;
}
return 0;
}
float CPlugin::flightLoopCallback(float, float, int, void *refcon)
{
auto *plugin = static_cast<CPlugin *>(refcon);
plugin->m_dbusDispatcher.runOnce();
if (plugin->m_service) { plugin->m_service->process(); }
if (plugin->m_weather) { plugin->m_weather->process(); }
if (plugin->m_traffic) { plugin->m_traffic->process(); }
return -1;
}
}