refs #358, created a mapper class (links mappings with existing models)

* read models and mappings / in background if required
* provides functions to access read mappings and models
This commit is contained in:
Klaus Basan
2014-12-15 11:54:00 +01:00
parent de3fcf4332
commit c285ac4098
4 changed files with 278 additions and 79 deletions

View File

@@ -1,23 +0,0 @@
#include "aircraftindexer.h"
namespace BlackSim
{
namespace FsCommon
{
CAircraftIndexer::CAircraftIndexer(QObject *parent) : QObject(parent) {}
int CAircraftIndexer::read(const QString directory)
{
if (!directory.isEmpty()) indexer().m_entries.changeDirectory(directory);
int n = indexer().m_entries.read();
emit indexer().entriesRead(n);
return n;
}
QFuture<int> CAircraftIndexer::readInBackground(const QString directory)
{
QFuture<int> f = QtConcurrent::run(CAircraftIndexer::read, directory);
return f;
}
}
}

View File

@@ -1,56 +0,0 @@
/* 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 BLACKSIM_FSCOMMON_AIRCRAFTINDEXER_H
#define BLACKSIM_FSCOMMON_AIRCRAFTINDEXER_H
#include "aircraftcfgentrieslist.h"
#include <QObject>
#include <QtConcurrent/QtConcurrent>
namespace BlackSim
{
namespace FsCommon
{
//! Indexer for all models
//! \sa CAircraftCfgEntries
//! \sa CAircraftCfgEntriesList
class CAircraftIndexer : QObject
{
Q_OBJECT
signals:
//! Number of entries read
void entriesRead(int number);
public:
//! Single entity indexer
static CAircraftIndexer &indexer()
{
static CAircraftIndexer indexer;
return indexer;
}
//! Read for directory or re-read
static int read(const QString directory = "");
//! Read in background
static QFuture<int> readInBackground(const QString directory = "");
private:
//! Constructor
CAircraftIndexer(QObject *parent = nullptr);
CAircraftCfgEntriesList m_entries; //!< all entries
};
} // namespace
} // namespace
#endif // guard

View File

@@ -0,0 +1,164 @@
/* 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 <utility>
using namespace BlackMisc;
using namespace BlackMisc::Network;
namespace BlackSim
{
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;
}
QFuture<int> &CAircraftMapper::readInBackground(const QString &simObjectDir)
{
if (!isRunningInBackground())
{
this->m_backgroundRead = QtConcurrent::run(this, &CAircraftMapper::readSimObjects, simObjectDir);
}
return this->m_backgroundRead;
}
QFuture<bool> &CAircraftMapper::initCompletelyInBackground(const QString &simObjectDir)
{
if (!isRunningInBackground())
{
this->m_backgroundInit = QtConcurrent::run(this, &CAircraftMapper::initCompletely, simObjectDir);
}
return this->m_backgroundInit;
}
bool CAircraftMapper::isRunningInBackground() const
{
return this->m_backgroundInit.isRunning() || this->m_backgroundRead.isRunning();
}
bool CAircraftMapper::isInitialized() const
{
return m_init;
}
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(); }
return el.front().toAircraftModel();
}
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
if (isRunningInBackground())
{
m_init = false;
this->m_entries.cancelRead();
this->m_backgroundInit.cancel();
this->m_backgroundRead.cancel();
}
}
bool CAircraftMapper::initCompletely(QString simObjectDir)
{
if (this->m_init) { return true; }
if (!this->m_mappings)
{
CLogMessage(this).error("Missing mapping defintions");
emit initCompleted(false);
return false;
}
if (!m_entries.existsDir(simObjectDir))
{
CLogMessage(this).error("Mapping engine, cannot read Flight Simulator directory: %1") << simObjectDir;
emit initCompleted(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);
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);
return false;
}
}
simObjectsSize = this->m_entries.size();
CLogMessage(this).info("Read %1 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_init = true;
return true;
}
} // namespace
} // namespace

View File

@@ -0,0 +1,114 @@
/* 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 BLACKSIM_FSCOMMON_AIRCRAFTMAPPER_H
#define BLACKSIM_FSCOMMON_AIRCRAFTMAPPER_H
#include "aircraftcfgentrieslist.h"
#include "../simulatormodelmappings.h"
#include <QObject>
#include <QScopedPointer>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
#include <QReadWriteLock>
#include <memory>
namespace BlackSim
{
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 : 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 = "");
//! Read in background
QFuture<int> &readInBackground(const QString &simObjectDir = "");
//! Init in background
QFuture<bool> &initCompletelyInBackground(const QString &simObjectDir = "");
//! Running in background
bool isRunningInBackground() const;
//! 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(); }
//! 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::Network::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();
private:
QScopedPointer<BlackSim::ISimulatorModelMappings> m_mappings; //!< all mapping definitions
CAircraftCfgEntriesList m_entries; //!< all entries
QFuture<bool> m_backgroundInit;
QFuture<int> m_backgroundRead;
bool m_init = false;
};
} // namespace
} // namespace
#endif // guard