Refactor shared X-Plane model parser in common header only functions

ref T290
This commit is contained in:
Roland Winklmeier
2018-08-21 15:04:05 +02:00
parent 597283dde1
commit a19ccabf35
8 changed files with 204 additions and 367 deletions

View File

@@ -1,89 +0,0 @@
/* Copyright (C) 2018
* 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 BLACKSIM_XSWIFTBUS_AIRCRAFTMODEL_H
#define BLACKSIM_XSWIFTBUS_AIRCRAFTMODEL_H
#include <string>
namespace XSwiftBus
{
//! Simplified implementation of \sa BlackMisc::Simulation::CDistributor
class CDistributor
{
public:
//! Default constructor
CDistributor() = default;
//! Constructor
CDistributor(const std::string &description) : m_description(description) {}
//! \copydoc BlackMisc::Simulation::CDistributor::hasDescription
bool hasDescription() const { return !m_description.empty(); }
//! \copydoc BlackMisc::Simulation::CDistributor::getDescription
std::string getDescription() const { return m_description; }
private:
std::string m_description;
};
//! Simplified implementation of \sa BlackMisc::Simulation::CAircraftModel
class CAircraftModel
{
public:
CAircraftModel() = default;
//! \copydoc BlackMisc::Simulation::CAircraftModel::hasDescription
bool hasDescription() const { return !m_description.empty(); }
//! \copydoc BlackMisc::Simulation::CAircraftModel::hasAircraftDesignator
bool hasAircraftDesignator() const { return !m_icao.empty(); }
//! \copydoc BlackMisc::Simulation::CAircraftModel::getName
std::string getName() const { return m_name; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::getDistributor
CDistributor getDistributor() const { return m_distributor; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::getAircraftIcaoCodeDesignator
std::string getAircraftIcaoCodeDesignator() const { return m_icao; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::getModelString
std::string getModelString() const { return m_modelString; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::setAircraftIcaoCode
void setAircraftIcaoCode(const std::string &icao) { m_icao = icao; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::setDescription
void setDescription(const std::string &description) { m_description = description; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::setName
void setName(const std::string &name) { m_name = name; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::setDistributor
void setDistributor(const CDistributor &distributor) { m_distributor = distributor; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::setModelString
void setModelString(const std::string &modelString) { m_modelString = modelString; }
private:
std::string m_name;
std::string m_icao;
std::string m_description;
CDistributor m_distributor;
std::string m_modelString;
};
}
#endif // guard

View File

@@ -8,13 +8,15 @@
*/
#include "service.h"
#include "utils.h"
#include <XPLM/XPLMPlanes.h>
#include <XPLM/XPLMUtilities.h>
#include <fstream>
#include "utils.h"
#include "blackmisc/simulation/xplane/qtfreeutils.h"
// clazy:excludeall=reserve-candidates
using namespace BlackMisc::Simulation::XPlane::QtFreeUtils;
namespace XSwiftBus
{
@@ -29,8 +31,8 @@ namespace XSwiftBus
char filename[256];
char path[512];
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
const auto model = extractAcfProperties(path);
emitAircraftModelChanged(path, filename, getAircraftLivery(), getAircraftIcaoCode(), model.getModelString(), model.getName(), getAircraftDescription());
AcfProperties acfProperties = extractAcfProperties(path);
emitAircraftModelChanged(path, filename, getAircraftLivery(), getAircraftIcaoCode(), acfProperties.modelString, acfProperties.modelName, getAircraftDescription());
}
void CService::addTextMessage(const std::string &text, double red, double green, double blue)
@@ -81,8 +83,8 @@ namespace XSwiftBus
char filename[256];
char path[512];
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
const auto model = extractAcfProperties(path);
return model.getModelString();
const AcfProperties acfProperties = extractAcfProperties(path);
return acfProperties.modelString;
}
std::string CService::getAircraftName() const
@@ -90,8 +92,8 @@ namespace XSwiftBus
char filename[256];
char path[512];
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
const auto model = extractAcfProperties(path);
return model.getName();
const AcfProperties acfProperties = extractAcfProperties(path);
return acfProperties.modelName;
}
int CService::getXPlaneVersionMajor() const
@@ -672,117 +674,4 @@ namespace XSwiftBus
return closestAirports;
}
//! Qt free version of BlackMisc::Simulation::XPlane::descriptionForFlyableModel()
std::string descriptionForFlyableModel(const CAircraftModel &model)
{
if (!model.getName().empty())
{
if (model.getDistributor().hasDescription() && model.getName().find(model.getDistributor().getDescription()) == std::string::npos)
{
return std::string("[ACF] ") + model.getName() + " by " + model.getDistributor().getDescription();
}
else
{
return std::string("[ACF] ") + model.getName();
}
}
else if (model.hasAircraftDesignator())
{
if (model.getDistributor().hasDescription())
{
return std::string("[ACF] ") + model.getAircraftIcaoCodeDesignator() + " by " + model.getDistributor().getDescription();
}
else
{
return std::string("[ACF] ") + model.getAircraftIcaoCodeDesignator();
}
}
return std::string("[ACF]");
}
//! Qt free version of BlackMisc::Simulation::XPlane::stringForFlyableModel()
std::string stringForFlyableModel(const CAircraftModel &model, const std::string &acfFile)
{
if (model.getDistributor().hasDescription())
{
if (!model.getName().empty())
{
if (model.getName().find(model.getDistributor().getDescription()) != std::string::npos)
{
return model.getName();
}
else
{
return model.getDistributor().getDescription() + ' ' + model.getName();
}
}
else if (model.hasAircraftDesignator())
{
return model.getDistributor().getDescription() + ' ' + model.getAircraftIcaoCodeDesignator();
}
}
return getDirName(acfFile) + ' ' + getBaseName(acfFile);
}
CAircraftModel CService::extractAcfProperties(const std::string &filePath)
{
CAircraftModel model;
std::ifstream fs(filePath, std::ios::in | std::ios::binary);
if (!fs.is_open()) { return model; }
std::string i;
std::string version;
std::string acf;
std::getline(fs, i);
std::getline(fs, version);
std::getline(fs, acf);
if (i == "I" && version.find("version") != std::string::npos && acf == "ACF")
{
std::string line;
while (std::getline(fs, line))
{
auto tokens = split(line, 2);
if (tokens.size() < 3 || tokens.at(0) != "P") { continue; }
if (tokens.at(1) == "acf/_ICAO")
{
const std::string icao(tokens.at(2));
model.setAircraftIcaoCode(icao);
}
else if (tokens.at(1) == "acf/_descrip")
{
const std::string desc(tokens.at(2));
model.setDescription("[ACF] " + desc);
}
else if (tokens.at(1) == "acf/_name")
{
const std::string name(tokens.at(2));
model.setName(name);
}
else if (tokens.at(1) == "acf/_studio")
{
const CDistributor dist(tokens.at(2));
model.setDistributor(dist);
}
else if (tokens.at(1) == "acf/_author")
{
if (model.getDistributor().hasDescription()) { continue; }
std::string author = tokens.at(2);
size_t pos = author.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_");
author = author.substr(0, pos);
if (author.empty()) { continue; }
const CDistributor dist(author);
model.setDistributor(dist);
}
}
}
fs.close();
model.setModelString(stringForFlyableModel(model, filePath));
if (!model.hasDescription()) { model.setDescription(descriptionForFlyableModel(model)); }
return model;
}
}

View File

@@ -20,7 +20,6 @@
#include "datarefs.h"
#include "messages.h"
#include "navdatareference.h"
#include "aircraftmodel.h"
#include <XPLM/XPLMNavigation.h>
#include <string>
@@ -246,8 +245,6 @@ namespace XSwiftBus
std::vector<CNavDataReference> findClosestAirports(int number, double latitude, double longitude);
static CAircraftModel extractAcfProperties(const std::string &filePath);
StringDataRef<xplane::data::sim::aircraft::view::acf_livery_path> m_liveryPath;
StringDataRef<xplane::data::sim::aircraft::view::acf_ICAO> m_icao;
StringDataRef<xplane::data::sim::aircraft::view::acf_descrip> m_descrip;

View File

@@ -43,66 +43,6 @@ namespace XSwiftBus
g_xplanePath = xplanePath;
}
std::string getDirName(const std::string &filePath)
{
std::string seperator = "/\\";
std::size_t sepPos = filePath.find_last_of(seperator);
if (sepPos != std::string::npos)
{
std::string dirPath = filePath.substr(0, sepPos);
return getFileName(dirPath);
}
else
{
return {};
}
}
std::string getFileName(const std::string &filePath)
{
std::string seperator = "/\\";
std::size_t sepPos = filePath.find_last_of(seperator);
if (sepPos != std::string::npos)
{
return filePath.substr(sepPos + 1, filePath.size() - 1);
}
else
{
return filePath;
}
}
std::string getBaseName(const std::string &filePath)
{
std::string seperator = ".";
std::string fileName = getFileName(filePath);
std::size_t sepPos = fileName.find(seperator);
if (sepPos != std::string::npos)
{
return fileName.substr(0, sepPos);
}
else
{
return fileName;
}
}
std::vector<std::string> split(const std::string &str, size_t maxSplitCount)
{
std::string s(str);
std::string delimiter = " ";
size_t pos = 0;
std::vector<std::string> tokens;
while ((pos = s.find(delimiter)) != std::string::npos)
{
tokens.push_back(s.substr(0, pos));
s.erase(0, pos + delimiter.length());
if (tokens.size() == maxSplitCount) { break; }
}
tokens.push_back(s);
return tokens;
}
void Logger::print(const std::string &filePath, int line, MsgType type, const std::string &message)
{
(void) line;

View File

@@ -26,19 +26,6 @@ namespace XSwiftBus
//! Init global xplane path
void initXPlanePath();
//! Returns the directory name of a given file path
std::string getDirName(const std::string &filePath);
//! Returns the filename (including extension) of a given file path
std::string getFileName(const std::string &filePath);
//! Returns the filename without extension of a given file path
std::string getBaseName(const std::string &filePath);
//! Splits the given string maximal maxSplitCount times and returns the tokens
//! The size of the returned vector is up to maxSplitCount + 1 or less
std::vector<std::string> split(const std::string &str, size_t maxSplitCount = 0);
//! Simple logger class.
//! Don't use it directly, but the _LOG macros instead
class Logger