refs #396, move subproject BlackSim into BlackMisc::Simulation

* removed unused samples / tests
* fixed found Doxygen issues
* removed blacksimfreefunctions, now in BlackMisc::Simulation::registerMetadata()
* samples_vetcor_geo to samples_geo
This commit is contained in:
Klaus Basan
2015-04-03 18:17:54 +02:00
committed by Roland Winklmeier
parent a6ca57265e
commit 32f60722c8
148 changed files with 2577 additions and 2792 deletions

View File

@@ -1,7 +1,7 @@
include (../../config.pri)
include (../../build.pri)
QT += network dbus
QT += network dbus xml
TARGET = blackmisc
TEMPLATE = lib
@@ -27,13 +27,15 @@ HEADERS += *.h \
$$PWD/aviation/*.h \
$$PWD/math/*.h \
$$PWD/simulation/*.h \
$$PWD/simulation/fscommon\*.h \
$$PWD/simulation/fsx\*.h
SOURCES += *.cpp \
$$PWD/aviation/*.cpp \
$$PWD/math/*.cpp \
$$PWD/simulation/*.cpp \
$$PWD/simulation/fscommon\*.cpp \
$$PWD/simulation/fsx\*.cpp
DESTDIR = ../../lib
OTHER_FILES += $$TRANSLATIONS readme.txt

View File

@@ -8,7 +8,18 @@
*/
#include "blackmiscfreefunctions.h"
#include "blackmisc/simulation/simulationallclasses.h"
#include "blackmisc/simulation/aircraftmodellist.h"
#include "blackmisc/simulation/simulatedaircraftlist.h"
#include "blackmisc/simulation/simulatorinfolist.h"
#include "blackmisc/simulation/setsimulator.h"
#include "blackmisc/simulation/fsx/simconnectutilities.h"
#include "blackmisc/simulation/fscommon/aircraftcfgentrieslist.h"
using namespace BlackMisc::Simulation;
using namespace BlackMisc::Simulation::Fsx;
using namespace BlackMisc::Simulation::FsCommon;
using namespace BlackMisc::Simulation::Settings;
/*
* Metadata for simulation
@@ -18,6 +29,12 @@
*/
void BlackMisc::Simulation::registerMetadata()
{
CSimulatorPluginInfo::registerMetadata();
CSimulatorPluginInfoList::registerMetadata();
CSettingsSimulator::registerMetadata();
FsCommon::CAircraftCfgEntries::registerMetadata();
FsCommon::CAircraftCfgEntriesList::registerMetadata();
Fsx::CSimConnectUtilities::registerMetadata();
CAircraftModel::registerMetadata();
CAircraftModelList::registerMetadata();
CSimulatedAircraft::registerMetadata();

View File

@@ -76,7 +76,7 @@ namespace BlackMisc
BlackMisc::Aviation::CAircraftIcao m_icao; //!< ICAO code
BlackMisc::Simulation::CAircraftModel m_model; //!< aircraft model
// BlackSim::CSimulatorPluginInfo m_simulatorInfo; //!< Mapping is for simulator
// BlackMisc::Simulation::CSimulatorPluginInfo m_simulatorInfo; //!< Mapping is for simulator
};
}
}

View File

@@ -9,8 +9,8 @@
//! \file
#ifndef BLACKMISC_AIRCRAFTMODEL_H
#define BLACKMISC_AIRCRAFTMODEL_H
#ifndef BLACKMISC_SIMULATION_AIRCRAFTMODEL_H
#define BLACKMISC_SIMULATION_AIRCRAFTMODEL_H
#include "blackmisc/aviation/aircraft.h"
#include "blackmisc/aviation/aircrafticao.h"

View File

@@ -9,8 +9,8 @@
//! \file
#ifndef BLACKMISC_AIRCRAFTMODELLIST_H
#define BLACKMISC_AIRCRAFTMODELLIST_H
#ifndef BLACKMISC_SIMULATION_AIRCRAFTMODELLIST_H
#define BLACKMISC_SIMULATION_AIRCRAFTMODELLIST_H
#include "blackmisc/simulation/aircraftmodel.h"
#include "blackmisc/collection.h"

View File

@@ -0,0 +1,156 @@
/* 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 "aircraftcfgentries.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/variant.h"
using namespace BlackMisc;
using namespace BlackMisc::Simulation;
using namespace BlackMisc::Network;
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
/*
* Constructor
*/
CAircraftCfgEntries::CAircraftCfgEntries(const QString &filePath, qint32 index, const QString &title, const QString &atcType, const QString &atcModel, const QString &atcParkingCode, const QString &description) :
m_index(index), m_fileName(filePath), m_title(title.trimmed()), m_atcType(atcType.trimmed()),
m_atcModel(atcModel.trimmed()), m_atcParkingCode(atcParkingCode.trimmed()), m_description(description.trimmed())
{
// void
}
/*
* String representation
*/
QString CAircraftCfgEntries::convertToQString(bool) const
{
QString s = "{%1, %2, %3, %4, %5, %6}";
s = s.arg(this->m_fileName).arg(this->m_index).arg(this->m_title)
.arg(this->m_atcModel).arg(this->m_atcType).arg(this->m_atcParkingCode);
return s;
}
/*
* Aircraft model
*/
QString CAircraftCfgEntries::getFileDirectory() const
{
if (this->m_fileName.isEmpty()) { return ""; }
QFileInfo fi(this->m_fileName);
return fi.absolutePath();
}
QString CAircraftCfgEntries::getUiCombinedDescription() const
{
QString d(this->m_uiManufacturer);
if (m_uiType.isEmpty()) { return d; }
if (d.isEmpty()) { return m_uiType; }
d += " ";
d += m_uiType;
return d;
}
/*
* Convert
*/
CAircraftModel CAircraftCfgEntries::toAircraftModel() const
{
CAircraftModel model(this->getTitle(), CAircraftModel::TypeModelMapping);
model.setDescription(this->getUiCombinedDescription());
model.setFileName(this->getFileName());
return model;
}
QString CAircraftCfgEntries::getThumbnailFileName() const
{
if (this->m_texture.isEmpty()) { return ""; }
if (this->m_fileName.isEmpty()) { return ""; }
QString fn = QDir::cleanPath(this->getFileDirectory() + QDir::separator() + "texture." + this->m_texture + QDir::separator() + "thumbnail.jpg");
return fn;
}
/*
* Get particular column
*/
CVariant CAircraftCfgEntries::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return this->toCVariant(); }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexFileName:
return CVariant::from(this->m_fileName);
case IndexTitle:
return CVariant::from(this->m_title);
case IndexAtcType:
return CVariant::from(this->m_atcType);
case IndexAtcModel:
return CVariant::from(this->m_atcModel);
case IndexParkingCode:
return CVariant::from(this->m_atcParkingCode);
case IndexEntryIndex:
return CVariant::from(this->m_index);
case IndexTexture:
return CVariant::from(this->m_texture);
case IndexDescription:
return CVariant::from(this->m_description);
default:
return CValueObject::propertyByIndex(index);
}
}
/*
* Set property as index
*/
void CAircraftCfgEntries::setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index)
{
if (index.isMyself()) { this->convertFromCVariant(variant); return; }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexAtcModel:
this->setAtcModel(variant.toQString());
break;
case IndexAtcType:
this->setAtcType(variant.toQString());
break;
case IndexEntryIndex:
this->setIndex(variant.toInt());
break;
case IndexFileName:
this->setFileName(variant.toQString());
break;
case IndexParkingCode:
this->setAtcParkingCode(variant.toQString());
break;
case IndexTitle:
this->setTitle(variant.toQString());
break;
case IndexDescription:
this->setDescription(variant.toQString());
break;
case IndexTexture:
this->setTexture(variant.toQString());
break;
default:
CValueObject::setPropertyByIndex(variant, index);
break;
}
}
} // namespace
} // namespace
} // namespace

View File

@@ -0,0 +1,154 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_FSCOMMON_AIRCRAFTCFGENTRY_H
#define BLACKMISC_SIMULATION_FSCOMMON_AIRCRAFTCFGENTRY_H
#include "blackmisc/simulation/aircraftmodel.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/variant.h"
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
/*!
* Set of aircraft.cfg entries representing an aircraft (FSX)
* \remarks an entry in the aircraft.cfg is title, atc type, ... This class already bundles
* relevant entries, hence the class is named Entries (plural)
*/
class CAircraftCfgEntries: public BlackMisc::CValueObject<CAircraftCfgEntries>
{
public:
//! Properties by index
enum ColumnIndex
{
IndexEntryIndex = BlackMisc::CPropertyIndex::GlobalIndexCAircraftCfgEntries,
IndexFileName,
IndexTitle,
IndexAtcType,
IndexAtcModel,
IndexParkingCode,
IndexDescription,
IndexTexture
};
//! Default constructor
CAircraftCfgEntries() = default;
//! Entries representing an aircraft
CAircraftCfgEntries(const QString &filePath, int index, const QString &title, const QString &atcType, const QString &atcModel, const QString &atcParkingCode, const QString &description);
//! File name
QString getFileName() const { return this->m_fileName; }
//! Directory of entry
QString getFileDirectory() const;
//! Title
QString getTitle() const { return this->m_title; }
//! Index
int getIndex() const { return this->m_index; }
//! ATC model
QString getAtcModel() const { return this->m_atcModel; }
//! ATC type
QString getAtcType() const { return this->m_atcType; }
//! Description
QString getDescription() const { return this->m_description; }
//! ATC parking code
QString getAtcParkingCode() const { return this->m_atcParkingCode; }
//! UI type (e.g. A321-231 IAE)
QString getUiType() const { return this->m_uiType; }
//! UI manufacturer (e.g. Airbus)
QString getUiManufacturer() const { return this->m_uiManufacturer; }
//! Texture
QString getTexture() const { return this->m_texture; }
//! Manufacturer + type
QString getUiCombinedDescription() const;
//! Filepath
void setFileName(const QString &filePath) { this->m_fileName = filePath; }
//! Title
void setTitle(const QString &title) { this->m_title = title; }
//! Index
void setIndex(int index) { this->m_index = index; }
//! ATC model
void setAtcModel(const QString &atcModel) { this->m_atcModel = atcModel.trimmed(); }
//! ATC type
void setAtcType(const QString &atcType) { this->m_atcType = atcType.trimmed(); }
//! Parking code
void setAtcParkingCode(const QString &parkingCode) { this->m_atcParkingCode = parkingCode.trimmed(); }
//! Description
void setDescription(const QString &description) { this->m_description = description.trimmed(); }
//! Texture
void setTexture(const QString &texture) { this->m_texture = texture; }
//! UI type (e.g. A321-231 IAE)
void setUiType(const QString &type) { this->m_uiType = type.trimmed(); }
//! UI manufacturer (e.g. Airbus)
void setUiManufacturer(const QString &manufacturer) { this->m_uiManufacturer = manufacturer.trimmed(); }
//! To aircraft model
BlackMisc::Simulation::CAircraftModel toAircraftModel() const;
//! Thumbnail.jpg path if possible
QString getThumbnailFileName() const;
//! \copydoc CValueObject::propertyByIndex
virtual BlackMisc::CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const override;
//! \copydoc CValueObject::setPropertyByIndex
virtual void setPropertyByIndex(const BlackMisc::CVariant &variant, const BlackMisc::CPropertyIndex &index) override;
protected:
//! \copydoc CValueObject::convertToQString
virtual QString convertToQString(bool i18n = false) const override;
private:
BLACK_ENABLE_TUPLE_CONVERSION(CAircraftCfgEntries)
int m_index; //!< current index in given config
QString m_fileName; //!< file name of aircraft.cfg
QString m_title; //!< Title in aircraft.cfg
QString m_atcType; //!< ATC type
QString m_atcModel; //!< ATC model
QString m_atcParkingCode; //!< ATC parking code
QString m_description; //!< descriptive text
QString m_uiType; //!< e.g. A321-231 IAE
QString m_uiManufacturer; //!< e.g. Airbus
QString m_texture; //!< texture, needed to identify thumbnail.jpg
};
}
}
}
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Simulation::FsCommon::CAircraftCfgEntries, (o.m_index, o.m_fileName, o.m_title, o.m_atcType, o.m_atcModel, o.m_atcParkingCode))
Q_DECLARE_METATYPE(BlackMisc::Simulation::FsCommon::CAircraftCfgEntries)
#endif // guard

View File

@@ -0,0 +1,235 @@
/* 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 "aircraftcfgentrieslist.h"
#include "blackmisc/predicates.h"
#include "blackmisc/logmessage.h"
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
using namespace BlackMisc;
using namespace BlackMisc::Simulation;
using namespace BlackMisc::Network;
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
/*
* Does the directory exist?
*/
bool CAircraftCfgEntriesList::existsDir(const QString &directory) const
{
QString d = directory.isEmpty() ? this->m_rootDirectory : directory;
if (d.isEmpty()) { return false; }
QDir dir(d);
//! \todo not available network dir can make this hang here
return dir.exists();
}
/*
* Model for title
*/
bool CAircraftCfgEntriesList::containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity)
{
if (title.isEmpty()) { return false; }
return this->containsBy(
[ = ](const CAircraftCfgEntries & entries) -> bool { return title.compare(entries.getTitle(), caseSensitivity) == 0; }
);
}
/*
* Double titles
*/
QStringList CAircraftCfgEntriesList::detectAmbiguousTitles() const
{
QStringList titles = this->getTitles(true);
QStringList ambiguousTitles;
QString last;
for (const QString &title : titles)
{
if (title.isEmpty()) { continue; }
if (title.compare(last, Qt::CaseInsensitive) == 0)
{
if (!ambiguousTitles.contains(title, Qt::CaseInsensitive))
{
ambiguousTitles.append(title);
}
}
last = title;
}
return ambiguousTitles;
}
/*
* All titles
*/
QStringList CAircraftCfgEntriesList::getTitles(bool sorted) const
{
QStringList titles = this->transform(Predicates::MemberTransform(&CAircraftCfgEntries::getTitle));
if (sorted) { titles.sort(Qt::CaseInsensitive); }
return titles;
}
/*
* As model list
*/
CAircraftModelList CAircraftCfgEntriesList::toAircraftModelList() const
{
CAircraftModelList ml;
for (auto it = this->begin() ; it != this->end(); ++it)
{
ml.push_back(it->toAircraftModel());
}
return ml;
}
/*
* Models for title
*/
CAircraftCfgEntriesList CAircraftCfgEntriesList::findByTitle(const QString &title, Qt::CaseSensitivity caseSensitivity) const
{
return this->findBy([ = ](const CAircraftCfgEntries & entries) -> bool
{ return title.compare(entries.getTitle(), caseSensitivity) == 0; });
}
/*
* Read all entrities in given directory
*/
int CAircraftCfgEntriesList::read(const QString &directory, const QStringList &excludeDirectories)
{
if (m_cancelRead) { return -1; }
// excluded?
for (const QString &excludeDir : excludeDirectories)
{
if (directory.contains(excludeDir, Qt::CaseInsensitive))
{
CLogMessage(this).debug() << "Skipping directory " << directory;
return 0;
}
}
// set directory with name filters, get aircraft.cfg and sub directories
QDir dir(directory, "aircraft.cfg", QDir::Name, QDir::Files | QDir::AllDirs);
if (!dir.exists()) return 0; // can happen if there are shortcuts or linked dirs not available
int counter = 0;
QString currentDir = dir.absolutePath();
// Dirs last is crucial,since I will break recursion on "aircraft.cfg" level
QFileInfoList files = dir.entryInfoList(QDir::Files | QDir::AllDirs, QDir::DirsLast);
for (const QFileInfo &file : files)
{
if (m_cancelRead) { return -1; }
if (file.isDir())
{
QString nextDir = file.absoluteFilePath();
if (currentDir.startsWith(nextDir, Qt::CaseInsensitive)) continue; // do not go up
if (dir == currentDir) { continue; } // do not recursively call same directory
counter += CAircraftCfgEntriesList::read(nextDir, excludeDirectories);
}
else
{
// due to the filter we expect only "aircraft.cfg" here
QString path = file.absoluteFilePath();
// I abuse the QSettings as ini-file reader
QSettings aircraftCfg(path, QSettings::IniFormat);
// from the general section
const QString atcType = aircraftCfg.value("atc_type").toString();
const QString atcModel = aircraftCfg.value("atc_model").toString();
int index = 0;
while (index >= 0)
{
if (m_cancelRead) { return -1; }
QString group = QString("fltsim.%1").arg(index);
aircraftCfg.beginGroup(group);
// does group exist?
if (aircraftCfg.contains("title"))
{
QString title = fixedStringContent(aircraftCfg, "title");
if (!title.isEmpty())
{
CAircraftCfgEntries entry(path, index, title, atcType, atcModel, "", "");
entry.setAtcParkingCode(fixedStringContent(aircraftCfg, "atc_parking_codes"));
entry.setDescription(fixedStringContent(aircraftCfg, "description"));
entry.setUiManufacturer(fixedStringContent(aircraftCfg, "ui_manufacturer"));
entry.setUiType(fixedStringContent(aircraftCfg, "ui_type"));
entry.setTexture(fixedStringContent(aircraftCfg, "texture"));
this->push_back(entry);
}
else
{
CLogMessage(this).info("FSX model in %1, index %2 has no title") << path << index;
}
++index;
++counter;
}
else
{
// marks end of the "fltsim.x" groups
index = -1;
}
aircraftCfg.endGroup();
}
break;
}
}
return counter;
}
QString CAircraftCfgEntriesList::fixedStringContent(const QSettings &settings, const QString &key)
{
return fixedStringContent(settings.value(key));
}
QString CAircraftCfgEntriesList::fixedStringContent(const QVariant &qv)
{
if (qv.isNull() || !qv.isValid())
{
return ""; // normal when there is no settings value
}
else if (static_cast<QMetaType::Type>(qv.type()) == QMetaType::QStringList)
{
QStringList l = qv.toStringList();
return l.join(",").trimmed();
}
else if (static_cast<QMetaType::Type>(qv.type()) == QMetaType::QString)
{
return qv.toString().trimmed();
}
Q_ASSERT(false);
return "";
}
/*
* Register metadata
*/
void CAircraftCfgEntriesList::registerMetadata()
{
qRegisterMetaType<BlackMisc::CSequence<CAircraftCfgEntries>>();
qDBusRegisterMetaType<BlackMisc::CSequence<CAircraftCfgEntries>>();
qRegisterMetaType<BlackMisc::CCollection<CAircraftCfgEntries>>();
qDBusRegisterMetaType<BlackMisc::CCollection<CAircraftCfgEntries>>();
qRegisterMetaType<CAircraftCfgEntriesList>();
qDBusRegisterMetaType<CAircraftCfgEntriesList>();
BlackMisc::registerMetaValueType<CAircraftCfgEntriesList>();
}
} // namespace
} // namespace
} // namespace

View File

@@ -0,0 +1,136 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_FSCOMMON_AIRCRAFTCFGLIST_H
#define BLACKMISC_SIMULATION_FSCOMMON_AIRCRAFTCFGLIST_H
#include "blackmisc/simulation/fscommon/aircraftcfgentries.h"
#include "blackmisc/simulation/aircraftmodellist.h"
#include "blackmisc/sequence.h"
#include "blackmisc/collection.h"
#include <QDir>
#include <QVector>
#include <QDebug>
#include <QSettings>
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
//! Utility, providing FS aircraft.cfg entries
class CAircraftCfgEntriesList : public BlackMisc::CSequence<CAircraftCfgEntries>
{
public:
//! Constructor
CAircraftCfgEntriesList(const QString &rootDirectory = "") : m_rootDirectory(rootDirectory) {}
//! Read all aircraft.cfg files starting from root directory
int read()
{
if (this->m_readForDirectory) { return this->size(); }
// not read so far, read it
this->clear();
this->m_readForDirectory = true;
return this->read(this->m_rootDirectory, excludeDirectories());
}
//! Change the directory
bool changeDirectory(const QString &directory)
{
if (this->m_rootDirectory != directory)
{
this->m_rootDirectory = directory;
this->m_readForDirectory = false;
}
return (!directory.isEmpty() && this->existsDir(directory));
}
//! Virtual destructor
virtual ~CAircraftCfgEntriesList() {}
//! Does the directory exist?
bool existsDir(const QString &directory = "") const;
//! Has current directory been read?
bool hasReadDirectory() const { return this->m_readForDirectory; }
//! Cancel read
void cancelRead() { m_cancelRead = true; }
//! Current root directory
QString getRootDirectory() const { return this->m_rootDirectory; }
//! Contains model with title?
bool containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive);
//! All titles (aka model names)
QStringList getTitles(bool sorted = false) const;
//! As aircraft models
BlackMisc::Simulation::CAircraftModelList toAircraftModelList() const;
//! Ambiguous titles
QStringList detectAmbiguousTitles() const;
//! Find by title
CAircraftCfgEntriesList findByTitle(const QString &title, Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive) const;
//! \copydoc CValueObject::toQVariant
virtual QVariant toQVariant() const override { return QVariant::fromValue(*this); }
//! \copydoc CValueObject::convertFromQVariant
virtual void convertFromQVariant(const QVariant &variant) override { BlackMisc::setFromQVariant(this, variant); }
//! Do not include the following directories for FS
static const QStringList &excludeDirectories()
{
static const QStringList exclude
{
"SimObjects/Animals",
"SimObjects/Misc",
"SimObjects/GroundVehicles",
"SimObjects/Boats"
};
return exclude;
}
//! Register metadata
static void registerMetadata();
private:
QString m_rootDirectory; //!< root directory reading aircraft.cfg files
bool m_readForDirectory = false; //!< valid read for given directory
bool m_cancelRead = false;
//! Read all entries in one directory
int read(const QString &directory, const QStringList &excludeDirectories = QStringList());
//! Fix the content read
static QString fixedStringContent(const QVariant &qv);
//! Value from settings, fixed string
static QString fixedStringContent(const QSettings &settings, const QString &key);
};
} // namespace
} // namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Simulation::FsCommon::CAircraftCfgEntriesList)
Q_DECLARE_METATYPE(BlackMisc::CCollection<BlackMisc::Simulation::FsCommon::CAircraftCfgEntries>)
Q_DECLARE_METATYPE(BlackMisc::CSequence<BlackMisc::Simulation::FsCommon::CAircraftCfgEntries>)
#endif // guard

View File

@@ -0,0 +1,186 @@
/* 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 "aircraftmapper.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/worker.h"
#include <utility>
using namespace BlackMisc;
using namespace BlackMisc::Simulation;
using namespace BlackMisc::Network;
using namespace BlackMisc::Aviation;
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
CAircraftMapper::CAircraftMapper(QObject *parent) : QObject(parent) { }
CAircraftMapper::CAircraftMapper(std::unique_ptr<ISimulatorModelMappings> mappings, QObject *parent) :
QObject(parent), m_mappings(mappings.release())
{ }
CAircraftMapper::CAircraftMapper(std::unique_ptr<ISimulatorModelMappings> mappings, const QString &simObjectsDir, QObject *parent) :
QObject(parent), m_mappings(mappings.release())
{
this->m_entries.changeDirectory(simObjectsDir);
}
CAircraftMapper::~CAircraftMapper()
{
this->gracefulShutdown();
}
int CAircraftMapper::readSimObjects(const QString &simObjectDir)
{
if (!simObjectDir.isEmpty()) { m_entries.changeDirectory(simObjectDir); }
int n = m_entries.read();
emit entriesRead(n);
return n;
}
void CAircraftMapper::initCompletelyInBackground(const QString &simObjectDir)
{
if (this->m_initWorker) { return; }
this->m_initWorker = BlackMisc::CWorker::fromTask(this, "CAircraftMapper::initCompletely", [this, simObjectDir]()
{
this->initCompletely(simObjectDir);
});
}
bool CAircraftMapper::isInitialized() const
{
return m_init;
}
CAircraftIcao CAircraftMapper::getIcaoForModelString(const QString &modelString) const
{
if (modelString.isEmpty() || !this->isInitialized()) { return CAircraftIcao(); }
CAircraftMappingList mappings = this->m_mappings->getMappingList().findByModelString(modelString);
if (mappings.isEmpty()) { return CAircraftIcao(); }
return mappings.front().getIcao();
}
bool CAircraftMapper::containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity)
{
return this->m_entries.containsModelWithTitle(title, caseSensitivity);
}
CAircraftModel CAircraftMapper::getModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity) const
{
CAircraftCfgEntriesList el = this->m_entries.findByTitle(title, caseSensitivity);
if (el.isEmpty()) { return CAircraftModel(); }
CAircraftModel model = el.front().toAircraftModel();
CAircraftIcao icao = this->getIcaoForModelString(model.getModelString());
model.setIcao(icao);
return model;
}
int CAircraftMapper::synchronize()
{
Q_ASSERT(this->m_mappings);
if (!this->m_mappings) { return 0; }
return this->m_mappings->synchronizeWithExistingModels(this->m_entries.getTitles(true));
}
void CAircraftMapper::gracefulShutdown()
{
// when running, force re-init
this->m_entries.cancelRead();
this->m_initInProgress = false;
this->m_init = false;
}
void CAircraftMapper::markUninitialized()
{
this->m_init = false;
}
const CAircraftModel &CAircraftMapper::getDefaultModel()
{
static const CAircraftModel aircraftModel(
"Boeing 737-800 Paint1",
CAircraftModel::TypeModelMatchingDefaultModel,
"B737-800 default model",
CAircraftIcao("B738", "L2J", "", "", "FFFFFF")
);
return aircraftModel;
}
bool CAircraftMapper::initCompletely(QString simObjectDir)
{
if (this->m_init) { return true; }
if (this->m_initInProgress) { return false; }
this->m_initInProgress = true;
if (!this->m_mappings)
{
CLogMessage(this).error("Missing mapping defintions");
emit initCompleted(false);
this->m_initInProgress = false;
return false;
}
if (!m_entries.existsDir(simObjectDir))
{
CLogMessage(this).error("Mapping engine, cannot read Flight Simulator directory: %1") << simObjectDir;
emit initCompleted(false);
this->m_initInProgress = false;
return false;
}
// read the defintions (if required)
int mappingSize = this->m_mappings->size();
if (mappingSize < 1)
{
this->m_mappings->read();
mappingSize = this->m_mappings->size();
if (mappingSize < 1)
{
CLogMessage(this).error("Reading mapping rules failed or empty");
emit initCompleted(false);
this->m_initInProgress = false;
return false;
}
}
CLogMessage(this).debug() << "Mapping definitions" << mappingSize;
// read sim objects, can take a while
int simObjectsSize = this->m_entries.size();
if (simObjectsSize < 1)
{
simObjectsSize = this->readSimObjects(simObjectDir);
if (simObjectsSize < 1)
{
CLogMessage(this).error("No SimObjects found in %1") << simObjectDir;
emit initCompleted(false);
this->m_initInProgress = false;
return false;
}
}
simObjectsSize = this->m_entries.size();
CLogMessage(this).info("Read %1 SimObjects from %2") << simObjectsSize << m_entries.getRootDirectory();
// sync
this->synchronize();
CLogMessage(this).debug() << "Mapping definitions after sync" << this->m_mappings->size();
// finish
CLogMessage(this).info("Mapping system: %1 definitions for %2 entries") << this->m_mappings->size() << this->m_entries.size();
emit initCompleted(true);
this->m_initInProgress = false;
this->m_init = true;
return true;
}
} // namespace
} // namespace
} // namespace

View File

@@ -0,0 +1,120 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_FSCOMMON_AIRCRAFTMAPPER_H
#define BLACKMISC_SIMULATION_FSCOMMON_AIRCRAFTMAPPER_H
#include "aircraftcfgentrieslist.h"
#include "../simulatormodelmappings.h"
#include "blackmisc/worker.h"
#include <QObject>
#include <QScopedPointer>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
#include <QReadWriteLock>
#include <memory>
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
//! Mapper for all models (works for FS9/FSX).
//! \details Reads all the mapping rules and all the available flight simulator models.
//! Then all rules for models not existing are eliminated ( \sa synchronize ).
//! Thereafter all existing models and mappings can be obtained from here.
//! \sa CAircraftCfgEntries
//! \sa CAircraftCfgEntriesList
class CAircraftMapper : public QObject
{
Q_OBJECT
signals:
//! Number of entries read
void entriesRead(int number);
//! Full init completed
void initCompleted(bool success);
public:
//! Default constructor
CAircraftMapper(QObject *parent = nullptr);
//! Constructor, handing over ownership or mappings object
CAircraftMapper(std::unique_ptr<ISimulatorModelMappings> mappings, QObject *parent = nullptr);
//! Constructor, handing over ownership or mappings object
CAircraftMapper(std::unique_ptr<ISimulatorModelMappings> mappings, const QString &simObjectsDir, QObject *parent = nullptr);
//! Destructor
~CAircraftMapper();
//! Completely init
bool initCompletely(QString simObjectDir);
//! Read for directory or re-read
int readSimObjects(const QString &simObjectDir = "");
//! Init in background
void initCompletelyInBackground(const QString &simObjectDir = "");
//! Init completed?
bool isInitialized() const;
//! Get all aircraft entries (aka models available)
const CAircraftCfgEntriesList &getAircraftCfgEntriesList() const { return m_entries; }
//! Get all mappings
const BlackMisc::Network::CAircraftMappingList &getAircraftMappingList() const { return m_mappings->getMappingList(); }
//! Inverse lookup
BlackMisc::Aviation::CAircraftIcao getIcaoForModelString(const QString &modelString) const;
//! Number of aircraft entries
int countAircraftCfgEntries() const { return m_entries.size(); }
//! Number of mapping definitions
int countMappingRules() const { return m_mappings ? m_mappings->size() : 0; }
//! Set the directory
bool changeCAircraftCfgEntriesDirectory(const QString &directory) { return this->m_entries.changeDirectory(directory); }
//! Contains model with title?
bool containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive);
//! Model with title
BlackMisc::Simulation::CAircraftModel getModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive) const;
//! Synchronize models and mappings
//! \remarks after this step, we only have mappings for which we have models
int synchronize();
//! Shutdown
void gracefulShutdown();
//! To force reload
void markUninitialized();
//! default model
static const BlackMisc::Simulation::CAircraftModel &getDefaultModel();
private:
QScopedPointer<BlackMisc::Simulation::ISimulatorModelMappings> m_mappings; //!< all mapping definitions
CAircraftCfgEntriesList m_entries; //!< all entries
bool m_init = false;
bool m_initInProgress = false;
BlackMisc::CWorker *m_initWorker = nullptr;
};
} // namespace
} // namespace
} // namespace
#endif // guard

View File

@@ -0,0 +1,53 @@
/* 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 "bcdconversions.h"
using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Aviation;
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
quint32 CBcdConversions::comFrequencyToBcdHz(const BlackMisc::PhysicalQuantities::CFrequency &comFrequency)
{
// FSX documentation is wrong, we need to use kHz + 2 digits, not Hz
quint32 f = comFrequency.valueRounded(CFrequencyUnit::kHz(), 0) / 10;
f = dec2Bcd(f);
return f;
}
quint32 CBcdConversions::transponderCodeToBcd(const BlackMisc::Aviation::CTransponder &transponder)
{
// FSX documentation is wrong, we need to use kHz + 2 digits, not Hz
quint32 t = transponder.getTransponderCode();
t = dec2Bcd(t);
return t;
}
quint32 CBcdConversions::hornerScheme(quint32 num, quint32 divider, quint32 factor)
{
quint32 remainder = 0, quotient = 0, result = 0;
remainder = num % divider;
quotient = num / divider;
if (!(quotient == 0 && remainder == 0))
{
result += hornerScheme(quotient, divider, factor) * factor + remainder;
}
return result;
}
} // namespace
} // namespace
} // namespacee

View File

@@ -0,0 +1,54 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_FSCOMMON_BCDCONVERSIONS_H
#define BLACKMISC_SIMULATION_FSCOMMON_BCDCONVERSIONS_H
#include "blackmisc/pqfrequency.h"
#include "blackmisc/aviation/transponder.h"
#include <QtGlobal>
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
//! BCD conversions for FS
class CBcdConversions
{
public:
//! BCD -> decimal
static quint32 bcd2Dec(quint32 bcdNum) { return hornerScheme(bcdNum, 0x10, 10); }
//! Decimal -> BCD
static quint32 dec2Bcd(quint32 decNum) { return hornerScheme(decNum, 10, 0x10); }
//! COM Frequency to BCD
static quint32 comFrequencyToBcdHz(const BlackMisc::PhysicalQuantities::CFrequency &comFrequency);
//! Transponder code to BCD
static quint32 transponderCodeToBcd(const BlackMisc::Aviation::CTransponder &transponder);
private:
//! Constructor, only static methods
CBcdConversions() {}
//! Horner scheme
static quint32 hornerScheme(quint32 num, quint32 divider, quint32 factor);
};
} // ns
} // ns
} // ns
#endif // guard

View File

@@ -0,0 +1,12 @@
#ifndef BLACKMISC_SIMULATION_FSCOMMON_NAMESPACES_H
#define BLACKMISC_SIMULATION_FSCOMMON_NAMESPACES_H
// just a dummy header, namespace documentation will go here
/*! \file */
/*!
* \namespace FsCommon
* \brief Utility classes for FSX, P3D and FS9, OS and driver independent code
*/
#endif // guard

View File

@@ -0,0 +1,52 @@
/* 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 "blackmisc/project.h"
#include "fscommonutil.h"
#include <QSettings>
#include <QDir>
using namespace BlackMisc;
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
QString CFsCommonUtil::fsxDirFromRegistry()
{
QString fsxPath;
if (CProject::isCompiledWithFsxSupport())
{
// set FSX path
QSettings fsxRegistry("HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft Games\\Flight Simulator\\10.0", QSettings::NativeFormat);
fsxPath = fsxRegistry.value("AppPath").toString().trimmed();
if (fsxPath.isEmpty())
{
// another trial
QSettings fsxRegistry("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Microsoft Games\\Flight Simulator\\10.0", QSettings::NativeFormat);
fsxPath = fsxRegistry.value("SetupPath").toString().trimmed();
}
}
return fsxPath;
}
QString CFsCommonUtil::fsxSimObjectsDirFromRegistry()
{
QString fsxPath = fsxDirFromRegistry();
if (fsxPath.isEmpty()) { return ""; }
fsxPath = QDir(fsxPath).filePath("SimObjects");
return fsxPath;
}
} // namespace
} // namespace
} // namespace

View File

@@ -0,0 +1,41 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_FSCOMMONUTIL_H
#define BLACKMISC_SIMULATION_FSCOMMONUTIL_H
#include <QString>
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
//! FS9/X utils
class CFsCommonUtil
{
public:
CFsCommonUtil();
//! FSX directory obtained from registry
static QString fsxDirFromRegistry();
//! FSX's simObject directory from registry
static QString fsxSimObjectsDirFromRegistry();
};
} // namespace
} // namespace
} // namespace
#endif // guard

View File

@@ -0,0 +1,133 @@
/* 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 "vpilotmodelmappings.h"
#include "blackmisc/nwaircraftmapping.h"
#include <QtXml/QDomElement>
#include <QFile>
#include <QDir>
#include <QStandardPaths>
using namespace BlackMisc::Network;
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
CVPilotModelMappings::CVPilotModelMappings(bool standardDirectory, QObject *parent) :
ISimulatorModelMappings(parent)
{
if (standardDirectory) { this->addDirectory(CVPilotModelMappings::standardMappingsDirectory()); }
}
void CVPilotModelMappings::addFilename(const QString &fileName)
{
if (this->m_fileList.contains(fileName)) return;
this->m_fileList.append(fileName);
}
void CVPilotModelMappings::addDirectory(const QString &directory)
{
QDir dir(directory);
if (!dir.exists()) return;
QStringList nameFilters({"*.vmr"});
QFileInfoList entries = dir.entryInfoList(nameFilters, QDir::Files | QDir::Readable);
for (const QFileInfo &file : entries)
{
this->addFilename(file.absoluteFilePath());
}
}
const QString &CVPilotModelMappings::standardMappingsDirectory()
{
static QString directory;
if (directory.isEmpty())
{
directory = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first();
if (!directory.endsWith('/')) directory.append('/');
directory.append("vPilot Files/Model Matching Rule Sets");
}
return directory;
}
bool CVPilotModelMappings::read()
{
bool success = true;
this->m_loadedFiles = 0;
this->m_fileListWithProblems.clear();
for (const QString &fn : this->m_fileList)
{
this->m_loadedFiles++;
bool s = this->loadFile(fn);
if (!s) { this->m_fileListWithProblems.append(fn); }
success = s && success;
}
return success;
}
bool CVPilotModelMappings::loadFile(const QString &fileName)
{
QFile f(fileName);
if (!f.exists()) { return false; }
if (!f.open(QFile::ReadOnly | QFile::Text)) { return false; }
QByteArray fc = f.readAll();
if (fc.isEmpty()) { return false; }
QDomDocument doc;
if (!doc.setContent(fc)) { return false; }
QDomNodeList rules = doc.elementsByTagName("ModelMatchRule");
if (rules.isEmpty()) { return false; }
QString folder;
QString updated;
QDomNodeList mmRuleSet = doc.elementsByTagName("ModelMatchRuleSet");
if (mmRuleSet.size() > 0)
{
QDomNamedNodeMap attributes = mmRuleSet.at(0).attributes();
folder = attributes.namedItem("Folder").nodeValue();
updated = attributes.namedItem("UpdatedOn").nodeValue();
}
int rulesSize = rules.size();
for (int i = 0; i < rulesSize; i++)
{
QDomNamedNodeMap attributes = rules.at(i).attributes();
const QString typeCode = attributes.namedItem("TypeCode").nodeValue();
const QString modelName = attributes.namedItem("ModelName").nodeValue();
// remark, callsign prefix is airline ICAO code
const QString airlineCode = attributes.namedItem("CallsignPrefix").nodeValue();
if (modelName.isEmpty()) { continue; }
// split if we have multiple models
if (modelName.contains("//"))
{
// multiple models
const QStringList models = modelName.split("//");
for (const QString &model : models)
{
if (model.isEmpty()) { continue; }
CAircraftMapping mapping("vpilot", folder, typeCode, airlineCode, model);
this->m_mappings.push_back(mapping);
}
}
else
{
// single model
CAircraftMapping mapping("vpilot", folder, typeCode, airlineCode, modelName);
this->m_mappings.push_back(mapping);
}
}
return true;
}
} // namespace
} // namespace
} // namespace

View File

@@ -0,0 +1,61 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_FSCOMMON_VPILOTMODELMAPPINGS_H
#define BLACKMISC_SIMULATION_FSCOMMON_VPILOTMODELMAPPINGS_H
#include "../simulatormodelmappings.h"
#include <QStringList>
namespace BlackMisc
{
namespace Simulation
{
namespace FsCommon
{
//! Model mappings
class CVPilotModelMappings : public ISimulatorModelMappings
{
public:
//! Constructor
CVPilotModelMappings(bool standardDirectory, QObject *parent = nullptr);
//! Destructor
virtual ~CVPilotModelMappings() {}
//! File names
void addFilename(const QString &fileName);
//! Directory with .vmr files
void addDirectory(const QString &directory);
//! Loaded files (number)
int countFilesLoaded() const { return m_loadedFiles; }
//! The standard directory for vPilot mappings
static const QString &standardMappingsDirectory();
public slots:
//! Load data
virtual bool read() override;
private:
QStringList m_fileList; //!< list of file names
QStringList m_fileListWithProblems; //!< problems during parsing
int m_loadedFiles = 0; //!< loaded files
//! Single file read and parsing
bool loadFile(const QString &fileName);
};
} // namespace
} // namespace
} // namespace
#endif // guard

View File

@@ -0,0 +1,21 @@
/* 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.
*/
#ifndef BLACKMISC_SIMULATION_FSX_NAMESPACES_H
#define BLACKMISC_SIMULATION_FSX_NAMESPACES_H
// just a dummy header, namespace documentation will go here
//! \file
/*!
* \namespace FSX
* \brief Utility classes for FSX, OS and driver independent code
*/
#endif // guard

View File

@@ -0,0 +1,41 @@
/* 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 "fsxsimulatorsetup.h"
#include "blackmisc/project.h"
#include "blackmisc/simulation/fscommon/fscommonutil.h"
#include "blackmisc/simulation/fsx/simconnectutilities.h"
#include <QSettings>
using namespace BlackMisc;
using namespace BlackMisc::Simulation::FsCommon;
namespace BlackMisc
{
namespace Simulation
{
namespace Fsx
{
void CFsxSimulatorSetup::init()
{
CSimulatorSetup::init();
this->m_setup.addValue(SetupSimConnectCfgFile, CSimConnectUtilities::getLocalSimConnectCfgFilename());
if (CProject::isCompiledWithFsxSupport())
{
// set FSX path
QString fsxPath = CFsCommonUtil::fsxDirFromRegistry();
if (!fsxPath.isEmpty()) this->m_setup.value(CSimulatorSetup::SetupSimPath, CVariant(fsxPath));
}
}
} // namespace
} // namespace
} // namespace

View File

@@ -0,0 +1,51 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_FSX_SIMSETUP_H
#define BLACKMISC_SIMULATION_FSX_SIMSETUP_H
#include "../simulatorsetup.h"
#include <QString>
namespace BlackMisc
{
namespace Simulation
{
namespace Fsx
{
/*!
* Simulator settings for FSX Flight simulators
*/
class CFsxSimulatorSetup : public BlackMisc::Simulation::CSimulatorSetup
{
public:
//! Setup values
enum
{
SetupSimConnectCfgFile = (BlackMisc::CPropertyIndex::GlobalIndexAbuseMode + 100), //!< location of simconnect.cfg file
};
//! Default constructor
CFsxSimulatorSetup() : BlackMisc::Simulation::CSimulatorSetup() {}
//! Constructor
CFsxSimulatorSetup(const BlackMisc::CPropertyIndexVariantMap &map) : BlackMisc::Simulation::CSimulatorSetup(map) {}
//! Init, to be used where FSX runs
void init();
};
} // namespace
} // namespace
} // namespace
#endif // guard

View File

@@ -0,0 +1,96 @@
/* 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 "simconnectutilities.h"
#include <QFile>
#include <QTextStream>
#include <QCoreApplication>
namespace BlackMisc
{
namespace Simulation
{
namespace Fsx
{
CSimConnectUtilities::CSimConnectUtilities() { }
//
// Filename / path of a "local" SimConnect.cfg file
//
QString CSimConnectUtilities::getLocalSimConnectCfgFilename()
{
return QCoreApplication::applicationDirPath() + "/SimConnect.cfg";
}
//
// Create a very simple SimConnect.cfg
//
bool CSimConnectUtilities::writeSimConnectCfg(const QString &fileName, const QString &ip, int port)
{
QString sc = CSimConnectUtilities::simConnectCfg(ip, port);
QFile file(fileName);
bool success = false;
if ((success = file.open(QIODevice::WriteOnly | QIODevice::Text)))
{
QTextStream out(&file);
out << sc;
file.close();
}
return success;
}
//
// simconnect.cfg file
//
QString CSimConnectUtilities::simConnectCfg(const QString &ip, int port)
{
QString sc = QString("[SimConnect]\nProtocol=Ipv4\nAddress=%1\nPort=%2\n"
"MaxReceiveSize=4096\nDisableNagle=0").arg(ip).arg(port);
return sc;
}
//
// Resolve enum id to string
// http://labs.qt.nokia.com/2008/10/09/coding-tip-pretty-printing-enum-values/
//
const QString CSimConnectUtilities::resolveEnumToString(const DWORD id, const char *enumName)
{
int i = CSimConnectUtilities::staticMetaObject.indexOfEnumerator(enumName);
if (i < 0) return QString("No enumerator for %1").arg(enumName);
QMetaEnum m = CSimConnectUtilities::staticMetaObject.enumerator(i);
const char *k = m.valueToKey(id);
return (k) ? QLatin1String(k) : QString("Id %1 not found for %2").arg(id).arg(enumName);
}
//
// Exception id to something human readible
//
const QString CSimConnectUtilities::simConnectExceptionToString(const DWORD id)
{
return CSimConnectUtilities::resolveEnumToString(id, "SIMCONNECT_EXCEPTION");
}
//
// The surface types
//
const QString CSimConnectUtilities::simConnectSurfaceTypeToString(const DWORD type, bool beautify)
{
QString sf = CSimConnectUtilities::resolveEnumToString(type, "SIMCONNECT_SURFACE");
return beautify ? sf.replace('_', ' ') : sf;
}
void CSimConnectUtilities::registerMetadata()
{
qRegisterMetaType<CSimConnectUtilities::SIMCONNECT_EXCEPTION>();
qRegisterMetaType<CSimConnectUtilities::SIMCONNECT_SURFACE>();
}
} // namespace
} // namespace
} // namespace

View File

@@ -0,0 +1,176 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_FSX_SIMCONNECTUTILITIES_H
#define BLACKMISC_SIMULATION_FSX_SIMCONNECTUTILITIES_H
#include <QString>
#include <QMetaEnum>
// Apart from the below definitions, the following code is OS independent,
// though it does not make sense to be used on non WIN machines.
// But it allows such parts to compile on all platforms.
#ifdef Q_OS_WIN
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <Windows.h>
#else
typedef unsigned long DWORD; //!< Fake Windows DWORD
#endif
namespace BlackMisc
{
namespace Simulation
{
namespace Fsx
{
//! Utilities for SimConnect
class CSimConnectUtilities : public QObject
{
Q_OBJECT
Q_ENUMS(SIMCONNECT_EXCEPTION)
Q_ENUMS(SIMCONNECT_SURFACE)
public:
//! Path to local config file
static QString getLocalSimConnectCfgFilename();
/*!
* Content for FSX simconnect.cfg file
* \param ip IP address of FSX
* \param port Port of FSX (e.g. 500)
* \return content for simconnect.cfg
*/
static QString simConnectCfg(const QString &ip, int port = 500);
/*!
* Create a FSX simconnect.cfg file
* \param fileName and path
* \param ip IP address of FSX
* \param port Port of FSX (e.g. 500)
* \return success
*/
static bool writeSimConnectCfg(const QString &fileName, const QString &ip, int port = 500);
/*!
* Resolve SimConnect exception (based on Qt metadata).
* \param id enum element
* \return enum element's name
*/
static const QString simConnectExceptionToString(const DWORD id);
/*!
* Resolve SimConnect surface (based on Qt metadata).
* \param type enum element
* \param beautify remove "_"
* \return
*/
static const QString simConnectSurfaceTypeToString(const DWORD type, bool beautify = true);
//! SimConnect surfaces.
// http://msdn.microsoft.com/en-us/library/cc526981.aspx#AircraftFlightInstrumentationData
enum SIMCONNECT_SURFACE
{
Concrete,
Grass,
Water,
Grass_bumpy,
Asphalt,
Short_grass,
Long_grass,
Hard_turf,
Snow,
Ice,
Urban,
Forest,
Dirt,
Coral,
Gravel,
Oil_treated,
Steel_mats,
Bituminus,
Brick,
Macadam,
Planks,
Sand,
Shale,
Tarmac,
Wright_flyer_track
};
//! SimConnect exceptions.
enum SIMCONNECT_EXCEPTION
{
SIMCONNECT_EXCEPTION_NONE,
SIMCONNECT_EXCEPTION_ERROR,
SIMCONNECT_EXCEPTION_SIZE_MISMATCH,
SIMCONNECT_EXCEPTION_UNRECOGNIZED_ID,
SIMCONNECT_EXCEPTION_UNOPENED,
SIMCONNECT_EXCEPTION_VERSION_MISMATCH,
SIMCONNECT_EXCEPTION_TOO_MANY_GROUPS,
SIMCONNECT_EXCEPTION_NAME_UNRECOGNIZED,
SIMCONNECT_EXCEPTION_TOO_MANY_EVENT_NAMES,
SIMCONNECT_EXCEPTION_EVENT_ID_DUPLICATE,
SIMCONNECT_EXCEPTION_TOO_MANY_MAPS,
SIMCONNECT_EXCEPTION_TOO_MANY_OBJECTS,
SIMCONNECT_EXCEPTION_TOO_MANY_REQUESTS,
SIMCONNECT_EXCEPTION_WEATHER_INVALID_PORT,
SIMCONNECT_EXCEPTION_WEATHER_INVALID_METAR,
SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_GET_OBSERVATION,
SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_CREATE_STATION,
SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_REMOVE_STATION,
SIMCONNECT_EXCEPTION_INVALID_DATA_TYPE,
SIMCONNECT_EXCEPTION_INVALID_DATA_SIZE,
SIMCONNECT_EXCEPTION_DATA_ERROR,
SIMCONNECT_EXCEPTION_INVALID_ARRAY,
SIMCONNECT_EXCEPTION_CREATE_OBJECT_FAILED,
SIMCONNECT_EXCEPTION_LOAD_FLIGHTPLAN_FAILED,
SIMCONNECT_EXCEPTION_OPERATION_INVALID_FOR_OBJECT_TYPE,
SIMCONNECT_EXCEPTION_ILLEGAL_OPERATION,
SIMCONNECT_EXCEPTION_ALREADY_SUBSCRIBED,
SIMCONNECT_EXCEPTION_INVALID_ENUM,
SIMCONNECT_EXCEPTION_DEFINITION_ERROR,
SIMCONNECT_EXCEPTION_DUPLICATE_ID,
SIMCONNECT_EXCEPTION_DATUM_ID,
SIMCONNECT_EXCEPTION_OUT_OF_BOUNDS,
SIMCONNECT_EXCEPTION_ALREADY_CREATED,
SIMCONNECT_EXCEPTION_OBJECT_OUTSIDE_REALITY_BUBBLE,
SIMCONNECT_EXCEPTION_OBJECT_CONTAINER,
SIMCONNECT_EXCEPTION_OBJECT_AI,
SIMCONNECT_EXCEPTION_OBJECT_ATC,
SIMCONNECT_EXCEPTION_OBJECT_SCHEDULE
};
//! Register metadata
static void registerMetadata();
private:
/*!
* Resolve enum value to its cleartext (based on Qt metadata).
* \param id enum element
* \param enumName name of the resolved enum
* \return enum element's name
*/
static const QString resolveEnumToString(const DWORD id, const char *enumName);
//! Hidden constructor
CSimConnectUtilities();
};
} // namespace
} // namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Simulation::Fsx::CSimConnectUtilities::SIMCONNECT_EXCEPTION)
Q_DECLARE_METATYPE(BlackMisc::Simulation::Fsx::CSimConnectUtilities::SIMCONNECT_SURFACE)
#endif // guard

View File

@@ -7,7 +7,7 @@
* contained in the LICENSE file.
*/
#include "simdirectaccessownaircraft.h"
#include "ownaircraftprovider.h"
#include "blackmisc/aviation/aircraft.h"
using namespace BlackMisc::Aviation;

View File

@@ -9,8 +9,8 @@
//! \file
#ifndef BLACKMISC_SIMDIRECTACCESSOWNAIRCRAFT_H
#define BLACKMISC_SIMDIRECTACCESSOWNAIRCRAFT_H
#ifndef BLACKMISC_SIMULATION_OWNAIRCRAFTPROVIDER_H
#define BLACKMISC_SIMULATION_OWNAIRCRAFTPROVIDER_H
#include "blackmisc/simulation/simulatedaircraft.h"

View File

@@ -7,7 +7,7 @@
* contained in the LICENSE file.
*/
#include "simdirectaccessremoteaircraft.h"
#include "remoteaircraftprovider.h"
using namespace BlackMisc::Aviation;

View File

@@ -9,8 +9,8 @@
//! \file
#ifndef BLACKMISC_SIMDIRECTACCESSREMOTEAIRCRAFT_H
#define BLACKMISC_SIMDIRECTACCESSREMOTEAIRCRAFT_H
#ifndef BLACKMISC_SIMULATION_REMOTEAIRCRAFTPROVIDER_H
#define BLACKMISC_SIMULATION_REMOTEAIRCRAFTPROVIDER_H
#include "blackmisc/simulation/simulatedaircraftlist.h"
#include "blackmisc/aviation/aircraftsituationlist.h"

View File

@@ -7,7 +7,7 @@
* contained in the LICENSE file.
*/
#include "simdirectaccessremoteaircraftdummy.h"
#include "remoteaircraftproviderdummy.h"
using namespace BlackMisc::Aviation;

View File

@@ -9,10 +9,10 @@
//! \file
#ifndef BLACKMISC_SIMDIRECTACCESSREMOTEAIRCRAFTDUMMY_H
#define BLACKMISC_SIMDIRECTACCESSREMOTEAIRCRAFTDUMMY_H
#ifndef BLACKMISC_SIMULATION_REMOTEAIRCRAFTPROVIDERDUMMY_H
#define BLACKMISC_SIMULATION_REMOTEAIRCRAFTPROVIDERDUMMY_H
#include "blackmisc/simulation/simdirectaccessremoteaircraft.h"
#include "blackmisc/simulation/remoteaircraftprovider.h"
namespace BlackMisc
{

View File

@@ -0,0 +1,87 @@
/* 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 "setsimulator.h"
#include "blackmisc/logmessage.h"
using namespace BlackMisc;
using namespace BlackMisc::Settings;
using namespace BlackMisc::PhysicalQuantities;
namespace BlackMisc
{
namespace Simulation
{
namespace Settings
{
CSettingsSimulator::CSettingsSimulator()
{
this->initDefaultValues();
}
QString CSettingsSimulator::convertToQString(bool i18n) const
{
Q_UNUSED(i18n);
QString s("Sel.driver:");
s.append(" ").append(m_selectedPlugin.toQString(i18n));
return s;
}
void CSettingsSimulator::initDefaultValues()
{
this->m_timeSyncOffset = CTime(0, CTimeUnit::hrmin());
this->m_timeSync = false;
}
BlackMisc::CStatusMessage CSettingsSimulator::value(const QString &path, const QString &command, const CVariant &value, bool &changedFlag)
{
// TODO: This needs to be refactored to a smarter way to delegate commands
changedFlag = false;
if (path == CSettingsSimulator::ValueSelectedDriver())
{
if (command == CSettingUtilities::CmdAdd() || command == CSettingUtilities::CmdUpdate())
{
CSimulatorPluginInfo v = value.value<CSimulatorPluginInfo>();
changedFlag = (v != this->m_selectedPlugin);
this->m_selectedPlugin = v;
return CLogMessage(CLogCategory::settingsUpdate()).info("selected driver%1 changed") << (changedFlag ? "" : " not");
}
return CLogMessage(CLogCategory::validation()).error("wrong command: %1") << command;
}
else if (path == CSettingsSimulator::ValueSyncTime())
{
if (command == CSettingUtilities::CmdAdd() || command == CSettingUtilities::CmdUpdate())
{
bool v = value.value<bool>();
changedFlag = (v != this->m_timeSync);
this->m_timeSync = v;
return CLogMessage(CLogCategory::settingsUpdate()).info("time synchronization%1 changed") << (changedFlag ? "" : " not");
}
return CLogMessage(CLogCategory::validation()).error("wrong command: %1") << command;
}
else if (path == CSettingsSimulator::ValueSyncTimeOffset())
{
if (command == CSettingUtilities::CmdAdd() || command == CSettingUtilities::CmdUpdate())
{
CTime v = value.value<CTime>();
changedFlag = (v != this->m_timeSyncOffset);
this->m_timeSyncOffset = v;
return CLogMessage(CLogCategory::settingsUpdate()).info("time synchronization offset%1 changed") << (changedFlag ? "" : " not");
}
return CLogMessage(CLogCategory::validation()).error("wrong command: %1") << command;
}
else
{
return CLogMessage(CLogCategory::validation()).error("wrong path: %1") << path;
}
}
} // namespace
} // namespace
} // namespace

View File

@@ -0,0 +1,97 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SETTINGS_SIMULATOR_H
#define BLACKMISC_SETTINGS_SIMULATOR_H
#include "blackmisc/valueobject.h"
#include "blackmisc/statusmessagelist.h"
#include "blackmisc/settingutilities.h"
#include "blackmisc/pqtime.h"
#include "simulatorplugininfo.h"
namespace BlackMisc
{
namespace Simulation
{
namespace Settings
{
//! Value object encapsulating information of simulator related settings.
class CSettingsSimulator : public BlackMisc::CValueObject<CSettingsSimulator>
{
public:
//! Default constructor.
CSettingsSimulator();
//! Path
static const QString &ValueSelectedDriver()
{
static const QString value("selecteddriver");
return value;
}
//! Path
static const QString &ValueSyncTimeOffset()
{
static const QString value("synctimeoffset");
return value;
}
//! Path
static const QString &ValueSyncTime()
{
static const QString value("synctime");
return value;
}
//! Selected driver
const BlackMisc::Simulation::CSimulatorPluginInfo &getSelectedPlugin() const { return this->m_selectedPlugin; }
//! Selected driver
void setSelectedPlugin(const BlackMisc::Simulation::CSimulatorPluginInfo &plugin) { this->m_selectedPlugin = plugin; }
//! Time synchronization offset time
const BlackMisc::PhysicalQuantities::CTime &getSyncTimeOffset() const { return this->m_timeSyncOffset;}
//! Set time synchronization offset time
void setSyncTimeOffset(const BlackMisc::PhysicalQuantities::CTime &offset) { this->m_timeSyncOffset = offset; this->m_timeSyncOffset.switchUnit(BlackMisc::PhysicalQuantities::CTimeUnit::hrmin());}
//! Time syncronization enabled?
bool isTimeSyncEnabled() const { return this->m_timeSync;}
//! Set time synchronization
void setTimeSyncEnabled(bool enabled) { this->m_timeSync = enabled; }
//! Init with meaningful default values
void initDefaultValues();
//! \copydoc BlackCore::IContextSettings::value
virtual BlackMisc::CStatusMessage value(const QString &path, const QString &command, const BlackMisc::CVariant &value, bool &changedFlag);
protected:
//! \copydoc CValueObject::convertToQString
virtual QString convertToQString(bool i18n = false) const override;
private:
BLACK_ENABLE_TUPLE_CONVERSION(CSettingsSimulator)
BlackMisc::Simulation::CSimulatorPluginInfo m_selectedPlugin;
bool m_timeSync = false;
BlackMisc::PhysicalQuantities::CTime m_timeSyncOffset;
};
} // namespace
} // namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Simulation::Settings::CSettingsSimulator)
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Simulation::Settings::CSettingsSimulator, (o.m_selectedPlugin, o.m_timeSync, o.m_timeSyncOffset))
#endif // guard

View File

@@ -9,8 +9,8 @@
//! \file
#ifndef BLACKMISC_SIMULATEDAIRCRAFT_H
#define BLACKMISC_SIMULATEDAIRCRAFT_H
#ifndef BLACKMISC_SIMULATION_SIMULATEDAIRCRAFT_H
#define BLACKMISC_SIMULATION_SIMULATEDAIRCRAFT_H
#include "blackmisc/aviation/aircraft.h"
#include "aircraftmodel.h"

View File

@@ -21,21 +21,13 @@ namespace BlackMisc
{
namespace Simulation
{
/*
* Default constructor
*/
CSimulatedAircraftList::CSimulatedAircraftList() { }
/*
* Construct from base class object
*/
CSimulatedAircraftList::CSimulatedAircraftList(const CSequence<CSimulatedAircraft> &other) :
CSequence<CSimulatedAircraft>(other)
{ }
/*
* Register metadata
*/
void CSimulatedAircraftList::registerMetadata()
{
qRegisterMetaType<BlackMisc::CSequence<CSimulatedAircraft>>();
@@ -47,9 +39,6 @@ namespace BlackMisc
registerMetaValueType<CSimulatedAircraftList>();
}
/*
* All pilots
*/
CUserList CSimulatedAircraftList::getPilots() const
{
return this->findBy(Predicates::MemberValid(&CSimulatedAircraft::getPilot)).transform(Predicates::MemberTransform(&CSimulatedAircraft::getPilot));

View File

@@ -9,8 +9,8 @@
//! \file
#ifndef BLACKMISC_SIMULATEDNAIRCRAFTLIST_H
#define BLACKMISC_SIMULATEDNAIRCRAFTLIST_H
#ifndef BLACKMISC_SIMULATION_SIMULATEDNAIRCRAFTLIST_H
#define BLACKMISC_SIMULATION_SIMULATEDNAIRCRAFTLIST_H
#include "blackmisc/simulation/simulatedaircraft.h"
#include "blackmisc/aviation/callsignobjectlist.h"

View File

@@ -0,0 +1,44 @@
/* 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 "simulatorinfolist.h"
namespace BlackMisc
{
namespace Simulation
{
CSimulatorPluginInfoList::CSimulatorPluginInfoList() { }
bool CSimulatorPluginInfoList::supportsSimulator(const QString &simulator)
{
return std::find_if(begin(), end(), [&simulator](const CSimulatorPluginInfo & info)
{
return info.getSimulator() == simulator;
}) != end();
}
QStringList CSimulatorPluginInfoList::toStringList(bool i18n) const
{
return this->transform([i18n](const CSimulatorPluginInfo & info) { return info.toQString(i18n); });
}
void CSimulatorPluginInfoList::registerMetadata()
{
qRegisterMetaType<BlackMisc::CSequence<CSimulatorPluginInfo>>();
qDBusRegisterMetaType<BlackMisc::CSequence<CSimulatorPluginInfo>>();
qRegisterMetaType<BlackMisc::CCollection<CSimulatorPluginInfo>>();
qDBusRegisterMetaType<BlackMisc::CCollection<CSimulatorPluginInfo>>();
qRegisterMetaType<CSimulatorPluginInfoList>();
qDBusRegisterMetaType<CSimulatorPluginInfoList>();
BlackMisc::registerMetaValueType<CSimulatorPluginInfoList>();
}
} // namespace
} // namespace

View File

@@ -0,0 +1,54 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_SIMULATORINFOLIST_H
#define BLACKMISC_SIMULATION_SIMULATORINFOLIST_H
#include "simulatorplugininfo.h"
#include "blackmisc/sequence.h"
#include "blackmisc/collection.h"
#include <QStringList>
namespace BlackMisc
{
namespace Simulation
{
//! Value object encapsulating a list of SimulatorInfo objects.
class CSimulatorPluginInfoList : public BlackMisc::CSequence<CSimulatorPluginInfo>
{
public:
//! Default constructor
CSimulatorPluginInfoList();
//! Construct from a base class object.
CSimulatorPluginInfoList(const CSequence<CSimulatorPluginInfo> &other);
//! \copydoc CValueObject::toQVariant
virtual QVariant toQVariant() const { return QVariant::fromValue(*this); }
//! Is simulator supported
bool supportsSimulator(const QString &simulator);
//! String list with meaningful representations
QStringList toStringList(bool i18n = false) const;
//! Register the metatypes
static void registerMetadata();
};
} // ns
} // ns
Q_DECLARE_METATYPE(BlackMisc::Simulation::CSimulatorPluginInfoList)
Q_DECLARE_METATYPE(BlackMisc::CCollection<BlackMisc::Simulation::CSimulatorPluginInfo>)
Q_DECLARE_METATYPE(BlackMisc::CSequence<BlackMisc::Simulation::CSimulatorPluginInfo>)
#endif // guard

View File

@@ -0,0 +1,54 @@
/* 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 "simulatormodelmappings.h"
using namespace BlackMisc;
using namespace BlackMisc::Network;
namespace BlackMisc
{
namespace Simulation
{
ISimulatorModelMappings::ISimulatorModelMappings(QObject *parent) : QObject(parent) {}
int ISimulatorModelMappings::size() const
{
return this->m_mappings.size();
}
bool ISimulatorModelMappings::isEmpty() const
{
return this->m_mappings.isEmpty();
}
const CAircraftMappingList &ISimulatorModelMappings::getMappingList() const
{
return this->m_mappings;
}
int ISimulatorModelMappings::synchronizeWithExistingModels(const QStringList &modelNames, Qt::CaseSensitivity cs)
{
if (modelNames.isEmpty() || this->m_mappings.isEmpty()) { return this->m_mappings.size(); }
CAircraftMappingList newList;
for (const CAircraftMapping &mapping : this->m_mappings)
{
QString modelString = mapping.getModel().getModelString();
if (modelString.isEmpty()) { continue; }
if (modelNames.contains(modelString, cs))
{
newList.push_back(mapping);
}
}
this->m_mappings = newList;
return this->m_mappings.size();
}
} // namespace
} // namespace

View File

@@ -0,0 +1,56 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_MODELMAPPINGS_H
#define BLACKMISC_SIMULATION_MODELMAPPINGS_H
#include "blackmisc/nwaircraftmappinglist.h"
#include <QObject>
namespace BlackMisc
{
namespace Simulation
{
//! Model mappings interface, different mapping readers (e.g. from database, from vPilot data files)
//! can implement this, but provide the same mapping list.
class ISimulatorModelMappings : public QObject
{
Q_OBJECT
public:
//! Constructor
ISimulatorModelMappings(QObject *parent = nullptr);
//! Destructor
virtual ~ISimulatorModelMappings() {}
//! Load data
virtual bool read() = 0;
//! Empty
bool isEmpty() const;
//! Size
int size() const;
//! Get list
const BlackMisc::Network::CAircraftMappingList &getMappingList() const;
//! Synchronize with existing model names, remove unneeded models
int synchronizeWithExistingModels(const QStringList &modelNames, Qt::CaseSensitivity cs = Qt::CaseInsensitive);
protected:
BlackMisc::Network::CAircraftMappingList m_mappings; //!< Mappings
};
} // ns
} // ns
#endif // guard

View File

@@ -0,0 +1,70 @@
/* 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 "simulatorplugininfo.h"
#include "blackmisc/blackmiscfreefunctions.h"
using namespace BlackMisc;
namespace BlackMisc
{
namespace Simulation
{
void CSimulatorPluginInfo::convertFromJson(const QJsonObject &json)
{
if (json["IID"].toString() != QStringLiteral("org.swift.pilotclient.BlackCore.SimulatorInterface"))
{
return;
}
if (!json["MetaData"].isObject())
{
return;
}
QJsonObject data = json["MetaData"].toObject();
if (data["name"].isUndefined() || data["simulator"].isUndefined())
{
return;
}
CValueObject::convertFromJson(data);
m_valid = true;
}
bool CSimulatorPluginInfo::isUnspecified() const
{
return m_name.isEmpty();
}
CVariant CSimulatorPluginInfo::getSimulatorSetupValue(int index) const
{
return this->m_simsetup.value(index);
}
QString CSimulatorPluginInfo::getSimulatorSetupValueAsString(int index) const
{
CVariant qv = getSimulatorSetupValue(index);
Q_ASSERT(qv.canConvert<QString>());
return qv.toQString();
}
void CSimulatorPluginInfo::setSimulatorSetup(const BlackMisc::CPropertyIndexVariantMap &setup)
{
this->m_simsetup = setup;
}
QString CSimulatorPluginInfo::convertToQString(bool i18n) const
{
Q_UNUSED(i18n);
return QString("%1 (%2)").arg(m_name, m_simulator);
}
} // ns
} // ns

View File

@@ -0,0 +1,105 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_SIMULATORPLUGININFO_H
#define BLACKMISC_SIMULATION_SIMULATORPLUGININFO_H
#include "blackmisc/propertyindexvariantmap.h"
#include "blackmisc/valueobject.h"
namespace BlackMisc
{
namespace Simulation
{
//! Describing a simulator plugin
class CSimulatorPluginInfo : public BlackMisc::CValueObject<CSimulatorPluginInfo>
{
/**
* The _name_ property identifies the plugin itself and must be uniqe.
*/
Q_PROPERTY(QString getName READ getName)
/**
* The _simulator_ property specifies which simulator the plugin handles.
* There cannot be two plugins loaded for the same simulator.
* swift enables some features for particular simulators. Currently recognized are:
* fsx, fs9, xplane
*/
Q_PROPERTY(QString getSimulator READ getSimulator)
/**
* The _description_ property provides a short, human-readable description of the plugin.
*/
Q_PROPERTY(QString getDescription READ getDescription)
public:
//! Default constructor
CSimulatorPluginInfo() = default;
virtual void convertFromJson(const QJsonObject &json) override;
//! Unspecified simulator
bool isUnspecified() const;
//! Single setting value
BlackMisc::CVariant getSimulatorSetupValue(int index) const;
//! Single setting value
QString getSimulatorSetupValueAsString(int index) const;
//! Set single settings
void setSimulatorSetup(const BlackMisc::CPropertyIndexVariantMap &setup);
//! Check if the provided plugin metadata is valid.
//! Simulator plugin (driver) has to meet the following requirements:
//! * implements org.swift.pilotclient.BlackCore.SimulatorInterface;
//! * provides plugin name;
//! * specifies simulator it handles.
//! Unspecified sim is considered as invalid.
bool isValid() const { return m_valid; }
//! Equals
bool operator==(const CSimulatorPluginInfo &other) { return getName() == other.getName(); }
//! Name
const QString &getName() const { return m_name; }
//! Simulator
const QString &getSimulator() const { return m_simulator; }
//! Description
const QString &getDescription() const { return m_description; }
protected:
//! \copydoc CValueObject::convertToQString
virtual QString convertToQString(bool i18n = false) const override;
private:
BLACK_ENABLE_TUPLE_CONVERSION(CSimulatorPluginInfo)
QString m_name;
QString m_simulator;
QString m_description;
bool m_valid { false };
BlackMisc::CPropertyIndexVariantMap m_simsetup; //!< allows to access simulator keys requried on remote side
};
} // ns
} // ns
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Simulation::CSimulatorPluginInfo, (
attr(o.m_name),
attr(o.m_simulator),
attr(o.m_description),
attr(o.m_valid),
attr(o.m_simsetup, flags<DisabledForComparison>())
))
Q_DECLARE_METATYPE(BlackMisc::Simulation::CSimulatorPluginInfo)
#endif // guard

View File

@@ -7,14 +7,20 @@
* contained in the LICENSE file.
*/
//! \file
#include "simulatorsetup.h"
#ifndef BLACKMISC_SIMULATIONALLCLASSES_H
#define BLACKMISC_SIMULATIONALLCLASSES_H
namespace BlackMisc
{
namespace Simulation
{
void CSimulatorSetup::setSettings(const BlackMisc::CPropertyIndexVariantMap &map)
{
this->m_setup = map;
}
#include "blackmisc/simulation/simulatedaircraft.h"
#include "blackmisc/simulation/simulatedaircraftlist.h"
#include "blackmisc/simulation/aircraftmodel.h"
#include "blackmisc/simulation/aircraftmodellist.h"
#endif // guard
void CSimulatorSetup::init()
{
// void
}
} // ns
} // ns

View File

@@ -0,0 +1,60 @@
/* 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.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_SIMSETUP_H
#define BLACKMISC_SIMULATION_SIMSETUP_H
#include "blackmisc/propertyindexvariantmap.h"
#include <QMap>
#include <QString>
namespace BlackMisc
{
namespace Simulation
{
/*!
* \brief Simulator settings for flight simulators
* \details Represents the generic part of a simulator setup ("common denominator"),
* details kept in specialized classes
*/
class CSimulatorSetup
{
protected:
BlackMisc::CPropertyIndexVariantMap m_setup; //!< values describing the simulator setup (path, config files)
protected:
//! Default constructor
CSimulatorSetup() {}
//! Constructor
CSimulatorSetup(const BlackMisc::CPropertyIndexVariantMap &map) : m_setup(map) {}
public:
//! Specific values
enum
{
SetupSimPath = BlackMisc::CPropertyIndex::GlobalIndexAbuseMode
};
//! Settings
BlackMisc::CPropertyIndexVariantMap getSettings() const { return this->m_setup;}
//! Settings
void setSettings(const BlackMisc::CPropertyIndexVariantMap &map);
//! Init, to be used where simulator runs
void init();
};
} // namespace
} // namespace
#endif // guard