<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <gl-platform/GLPlatform.hpp>

#include <Interface/Modules/Render/ViewScenePlatformCompatibility.h>
#include <Interface/Modules/Render/ES/SRInterface.h>
#include <Interface/Modules/Render/GLWidget.h>
#include <Core/Application/Preferences/Preferences.h>
#include <Core/Logging/Log.h>
#include <Modules/Render/ViewScene.h>

using namespace SCIRun::Gui;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Thread;
using namespace SCIRun::Core::Algorithms::Render;

//------------------------------------------------------------------------------
ViewSceneDialog::ViewSceneDialog(const std::string& name, ModuleStateHandle state,
  QWidget* parent /* = 0 */)
  : ModuleDialogGeneric(state, parent), shown_(false), itemManager_(new ViewSceneItemManager)
{
  setupUi(this);
  setWindowTitle(QString::fromStdString(name));

  addToolBar();

  // Setup Qt OpenGL widget.
  QGLFormat fmt;
  fmt.setAlpha(true);
  fmt.setRgba(true);
  mGLWidget = new GLWidget(new QtGLContext(fmt));

  if (mGLWidget->isValid())
  {
    // Hook up the GLWidget
    glLayout->addWidget(mGLWidget);
    glLayout->update();

    // Set spire transient value (should no longer be used).
    mSpire = std::weak_ptr<Render::SRInterface>(mGLWidget->getSpire());
  }
  else
  {
    /// \todo Display dialog.
    delete mGLWidget;
  }

  {
    std::shared_ptr<Render::SRInterface> spire = mSpire.lock();
    if (spire == nullptr)
      return;
    if (SCIRun::Core::Preferences::Instance().useNewViewSceneMouseControls)
    {
      spire->setMouseMode(Render::SRInterface::MOUSE_NEWSCIRUN);
    }
    else
    {
      spire->setMouseMode(Render::SRInterface::MOUSE_OLDSCIRUN);
    }
  }

  state->connect_state_changed(boost::bind(&ViewSceneDialog::newGeometryValueForwarder, this));
  connect(this, SIGNAL(newGeometryValueForwarder()), this, SLOT(newGeometryValue()));
}

//------------------------------------------------------------------------------
ViewSceneDialog::~ViewSceneDialog()
{
}

//------------------------------------------------------------------------------
void ViewSceneDialog::closeEvent(QCloseEvent *evt)
{
  // NOTE: At one point this was required because the renderer was
  // multi-threaded. It is likely we will run into the same issue in the
  // future. Kept for future reference.
  //glLayout->removeWidget(mGLWidget);
}

//------------------------------------------------------------------------------
void ViewSceneDialog::newGeometryValue()
{
  LOG_DEBUG("ViewSceneDialog::asyncExecute before locking");

  Guard lock(SCIRun::Modules::Render::ViewScene::mutex_.get());

  LOG_DEBUG("ViewSceneDialog::asyncExecute after locking");

  itemManager_->removeAll();
  // Grab the geomData transient value.
  auto geomDataTransient = state_->getTransientValue(Parameters::GeomData);
  if (geomDataTransient && !geomDataTransient->empty())
  {
    auto geomData = optional_any_cast_or_default<SCIRun::Modules::Render::ViewScene::GeomListPtr>(geomDataTransient);
    if (!geomData)
    {
      LOG_DEBUG("Logical error: ViewSceneDialog received an empty list.");
      return;
    }
    std::shared_ptr<Render::SRInterface> spire = mSpire.lock();
    if (spire == nullptr)
    {
      LOG_DEBUG("Logical error: Spire lock not acquired.");
      return;
    }

    std::vector<std::string> validObjects;
    for (auto it = geomData->begin(); it != geomData->end(); ++it)
    {
      boost::shared_ptr<Core::Datatypes::GeometryObject> obj = *it;
      spire->handleGeomObject(obj);
      validObjects.push_back(obj->objectName);
      itemManager_->addItem(QString::fromStdString(obj->objectName));
    }
    spire->gcInvalidObjects(validObjects);
  }
  else
  {
    std::shared_ptr<Render::SRInterface> spire = mSpire.lock();
    if (spire == nullptr)
      return;
    spire->removeAllGeomObjects();
  }
  //TODO IMPORTANT: we need some call somewhere to clear the transient geometry list once spire/ES has received the list of objects. They take up lots of memory...
  //state_->setTransientValue(Parameters::GeomData, boost::shared_ptr<std::list<boost::shared_ptr<Core::Datatypes::GeometryObject>>>(), false);
}

//------------------------------------------------------------------------------
void ViewSceneDialog::menuMouseControlChanged(int index)
{
  std::shared_ptr<Render::SRInterface> spire = mSpire.lock();
  if (spire == nullptr)
    return;

  if (index == 0)
  {
    spire->setMouseMode(SRInterface::MOUSE_OLDSCIRUN);
    SCIRun::Core::Preferences::Instance().useNewViewSceneMouseControls.setValue(false);
  }
  else
  {
    spire->setMouseMode(SRInterface::MOUSE_NEWSCIRUN);
    SCIRun::Core::Preferences::Instance().useNewViewSceneMouseControls.setValue(true);
  }
}

//------------------------------------------------------------------------------
void ViewSceneDialog::autoViewClicked()
{
  std::shared_ptr<Render::SRInterface> spireLock = mSpire.lock();
  spireLock->doAutoView();
}

//------------------------------------------------------------------------------
void ViewSceneDialog::addToolBar()
{
  mToolBar = new QToolBar(this);

  addMouseMenu();
  addAutoViewButton();
  addObjectToggleMenu();

  glLayout->addWidget(mToolBar);
}

void ViewSceneDialog::addMouseMenu()
{
  auto menu = new QComboBox(this);
  menu->addItem("Legacy Mouse Control");
  menu->addItem("New Mouse Control");
  connect(menu, SIGNAL(currentIndexChanged(int)),this, SLOT(menuMouseControlChanged(int)));
  menu->setCurrentIndex(SCIRun::Core::Preferences::Instance().useNewViewSceneMouseControls ? 1 : 0);
  mToolBar->addWidget(menu);
  mToolBar->addSeparator();
}

void ViewSceneDialog::addAutoViewButton()
{
  QPushButton* autoViewBtn = new QPushButton(this);
  autoViewBtn->setText("Auto View");
  autoViewBtn->setAutoDefault(false);
  autoViewBtn->setDefault(false);
  autoViewBtn->setShortcut(Qt::Key_0);
  connect(autoViewBtn, SIGNAL(clicked(bool)), this, SLOT(autoViewClicked()));
  mToolBar->addWidget(autoViewBtn);
  mToolBar->addSeparator();
}

class FixMacCheckBoxes : public QStyledItemDelegate
{
public:
  void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
  {
    QStyleOptionViewItem& refToNonConstOption = const_cast<QStyleOptionViewItem&>(option);
    refToNonConstOption.showDecorationSelected = false;
    QStyledItemDelegate::paint(painter, refToNonConstOption, index);
  }
};

void ViewSceneDialog::addObjectToggleMenu()
{
  QComboBox* combo = new QComboBox();
  combo->setItemDelegate(new FixMacCheckBoxes);
  combo->setModel(itemManager_->model());
  mToolBar->addWidget(combo);
  mToolBar->addSeparator();
}

void ViewSceneDialog::showEvent(QShowEvent *evt)
{
  ModuleDialogGeneric::showEvent(evt);
  if (!shown_)
  {
    autoViewClicked();
    shown_ = true;
  }
}

ViewSceneItemManager::ViewSceneItemManager() : model_(new QStandardItemModel(3,1))
{
  model_->setItem(0, 0, new QStandardItem(QString("Object Selection")));
  connect(model_, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(slotChanged(const QModelIndex&, const QModelIndex&)));

#if 0
  //fill with dummy items for testing:
  for (int r = 0; r < 3; ++r)
  {
    QStandardItem* item = new QStandardItem(QString("Item %0").arg(r));

    item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
    item->setData(Qt::Unchecked, Qt::CheckStateRole);
    items_.push_back(item);

    model_->setItem(r+1, item);
  }
#endif
}

void ViewSceneItemManager::addItem(const QString& name)
{
  QStandardItem* item = new QStandardItem(name);

  item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
  item->setData(Qt::Unchecked, Qt::CheckStateRole);
  items_.push_back(item);

  model_->appendRow(item);
}

void ViewSceneItemManager::removeItem(const QString& name)
{
  auto items = model_->findItems(name);
  Q_FOREACH(QStandardItem* item, items)
  {
    model_->removeRow(item->row());
  }
  items_.erase(std::remove_if(items_.begin(), items_.end(), [&](QStandardItem* item) { return item->text() == name; } ), items_.end());
}

void ViewSceneItemManager::removeAll()
{
  if (model_->rowCount() > 1)
  {
    LOG_DEBUG("ViewScene items cleared" << std::endl);
    model_->removeRows(1, model_->rowCount() - 1);
    items_.clear();
  }
}

void ViewSceneItemManager::slotChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
  auto index = topLeft.row() - 1;
  QStandardItem* item = items_[index];
  if (item->checkState() == Qt::Unchecked)
  {
    LOG_DEBUG("Item " << item->text().toStdString() << " Unchecked!" << std::endl);
    Q_EMIT itemUnselected(item->text());
  }
  else if (item->checkState() == Qt::Checked)
  {
    LOG_DEBUG("Item " << item->text().toStdString() << " Checked!" << std::endl);
    Q_EMIT itemSelected(item->text());
  }
}<commit_msg>Fix small merge error<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <gl-platform/GLPlatform.hpp>

#include <Interface/Modules/Render/ViewScenePlatformCompatibility.h>
#include <Interface/Modules/Render/ES/SRInterface.h>
#include <Interface/Modules/Render/GLWidget.h>
#include <Core/Application/Preferences/Preferences.h>
#include <Core/Logging/Log.h>
#include <Modules/Render/ViewScene.h>

using namespace SCIRun::Gui;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Thread;
using namespace SCIRun::Core::Algorithms::Render;
using namespace SCIRun::Render;

//------------------------------------------------------------------------------
ViewSceneDialog::ViewSceneDialog(const std::string& name, ModuleStateHandle state,
  QWidget* parent /* = 0 */)
  : ModuleDialogGeneric(state, parent), shown_(false), itemManager_(new ViewSceneItemManager)
{
  setupUi(this);
  setWindowTitle(QString::fromStdString(name));

  addToolBar();

  // Setup Qt OpenGL widget.
  QGLFormat fmt;
  fmt.setAlpha(true);
  fmt.setRgba(true);
  mGLWidget = new GLWidget(new QtGLContext(fmt));

  if (mGLWidget->isValid())
  {
    // Hook up the GLWidget
    glLayout->addWidget(mGLWidget);
    glLayout->update();

    // Set spire transient value (should no longer be used).
    mSpire = std::weak_ptr<Render::SRInterface>(mGLWidget->getSpire());
  }
  else
  {
    /// \todo Display dialog.
    delete mGLWidget;
  }

  {
    std::shared_ptr<Render::SRInterface> spire = mSpire.lock();
    if (spire == nullptr)
      return;
    if (SCIRun::Core::Preferences::Instance().useNewViewSceneMouseControls)
    {
      spire->setMouseMode(Render::SRInterface::MOUSE_NEWSCIRUN);
    }
    else
    {
      spire->setMouseMode(Render::SRInterface::MOUSE_OLDSCIRUN);
    }
  }

  state->connect_state_changed(boost::bind(&ViewSceneDialog::newGeometryValueForwarder, this));
  connect(this, SIGNAL(newGeometryValueForwarder()), this, SLOT(newGeometryValue()));
}

//------------------------------------------------------------------------------
ViewSceneDialog::~ViewSceneDialog()
{
}

//------------------------------------------------------------------------------
void ViewSceneDialog::closeEvent(QCloseEvent *evt)
{
  // NOTE: At one point this was required because the renderer was
  // multi-threaded. It is likely we will run into the same issue in the
  // future. Kept for future reference.
  //glLayout->removeWidget(mGLWidget);
}

//------------------------------------------------------------------------------
void ViewSceneDialog::newGeometryValue()
{
  LOG_DEBUG("ViewSceneDialog::asyncExecute before locking");

  Guard lock(SCIRun::Modules::Render::ViewScene::mutex_.get());

  LOG_DEBUG("ViewSceneDialog::asyncExecute after locking");

  itemManager_->removeAll();
  // Grab the geomData transient value.
  auto geomDataTransient = state_->getTransientValue(Parameters::GeomData);
  if (geomDataTransient && !geomDataTransient->empty())
  {
    auto geomData = optional_any_cast_or_default<SCIRun::Modules::Render::ViewScene::GeomListPtr>(geomDataTransient);
    if (!geomData)
    {
      LOG_DEBUG("Logical error: ViewSceneDialog received an empty list.");
      return;
    }
    std::shared_ptr<Render::SRInterface> spire = mSpire.lock();
    if (spire == nullptr)
    {
      LOG_DEBUG("Logical error: Spire lock not acquired.");
      return;
    }

    std::vector<std::string> validObjects;
    for (auto it = geomData->begin(); it != geomData->end(); ++it)
    {
      boost::shared_ptr<Core::Datatypes::GeometryObject> obj = *it;
      spire->handleGeomObject(obj);
      validObjects.push_back(obj->objectName);
      itemManager_->addItem(QString::fromStdString(obj->objectName));
    }
    spire->gcInvalidObjects(validObjects);
  }
  else
  {
    std::shared_ptr<Render::SRInterface> spire = mSpire.lock();
    if (spire == nullptr)
      return;
    spire->removeAllGeomObjects();
  }
  //TODO IMPORTANT: we need some call somewhere to clear the transient geometry list once spire/ES has received the list of objects. They take up lots of memory...
  //state_->setTransientValue(Parameters::GeomData, boost::shared_ptr<std::list<boost::shared_ptr<Core::Datatypes::GeometryObject>>>(), false);
}

//------------------------------------------------------------------------------
void ViewSceneDialog::menuMouseControlChanged(int index)
{
  std::shared_ptr<Render::SRInterface> spire = mSpire.lock();
  if (spire == nullptr)
    return;

  if (index == 0)
  {
    spire->setMouseMode(SRInterface::MOUSE_OLDSCIRUN);
    SCIRun::Core::Preferences::Instance().useNewViewSceneMouseControls.setValue(false);
  }
  else
  {
    spire->setMouseMode(SRInterface::MOUSE_NEWSCIRUN);
    SCIRun::Core::Preferences::Instance().useNewViewSceneMouseControls.setValue(true);
  }
}

//------------------------------------------------------------------------------
void ViewSceneDialog::autoViewClicked()
{
  std::shared_ptr<Render::SRInterface> spireLock = mSpire.lock();
  spireLock->doAutoView();
}

//------------------------------------------------------------------------------
void ViewSceneDialog::addToolBar()
{
  mToolBar = new QToolBar(this);

  addMouseMenu();
  addAutoViewButton();
  addObjectToggleMenu();

  glLayout->addWidget(mToolBar);
}

void ViewSceneDialog::addMouseMenu()
{
  auto menu = new QComboBox(this);
  menu->addItem("Legacy Mouse Control");
  menu->addItem("New Mouse Control");
  connect(menu, SIGNAL(currentIndexChanged(int)),this, SLOT(menuMouseControlChanged(int)));
  menu->setCurrentIndex(SCIRun::Core::Preferences::Instance().useNewViewSceneMouseControls ? 1 : 0);
  mToolBar->addWidget(menu);
  mToolBar->addSeparator();
}

void ViewSceneDialog::addAutoViewButton()
{
  QPushButton* autoViewBtn = new QPushButton(this);
  autoViewBtn->setText("Auto View");
  autoViewBtn->setAutoDefault(false);
  autoViewBtn->setDefault(false);
  autoViewBtn->setShortcut(Qt::Key_0);
  connect(autoViewBtn, SIGNAL(clicked(bool)), this, SLOT(autoViewClicked()));
  mToolBar->addWidget(autoViewBtn);
  mToolBar->addSeparator();
}

class FixMacCheckBoxes : public QStyledItemDelegate
{
public:
  void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
  {
    QStyleOptionViewItem& refToNonConstOption = const_cast<QStyleOptionViewItem&>(option);
    refToNonConstOption.showDecorationSelected = false;
    QStyledItemDelegate::paint(painter, refToNonConstOption, index);
  }
};

void ViewSceneDialog::addObjectToggleMenu()
{
  QComboBox* combo = new QComboBox();
  combo->setItemDelegate(new FixMacCheckBoxes);
  combo->setModel(itemManager_->model());
  mToolBar->addWidget(combo);
  mToolBar->addSeparator();
}

void ViewSceneDialog::showEvent(QShowEvent *evt)
{
  ModuleDialogGeneric::showEvent(evt);
  if (!shown_)
  {
    autoViewClicked();
    shown_ = true;
  }
}

ViewSceneItemManager::ViewSceneItemManager() : model_(new QStandardItemModel(3,1))
{
  model_->setItem(0, 0, new QStandardItem(QString("Object Selection")));
  connect(model_, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(slotChanged(const QModelIndex&, const QModelIndex&)));

#if 0
  //fill with dummy items for testing:
  for (int r = 0; r < 3; ++r)
  {
    QStandardItem* item = new QStandardItem(QString("Item %0").arg(r));

    item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
    item->setData(Qt::Unchecked, Qt::CheckStateRole);
    items_.push_back(item);

    model_->setItem(r+1, item);
  }
#endif
}

void ViewSceneItemManager::addItem(const QString& name)
{
  QStandardItem* item = new QStandardItem(name);

  item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
  item->setData(Qt::Unchecked, Qt::CheckStateRole);
  items_.push_back(item);

  model_->appendRow(item);
}

void ViewSceneItemManager::removeItem(const QString& name)
{
  auto items = model_->findItems(name);
  Q_FOREACH(QStandardItem* item, items)
  {
    model_->removeRow(item->row());
  }
  items_.erase(std::remove_if(items_.begin(), items_.end(), [&](QStandardItem* item) { return item->text() == name; } ), items_.end());
}

void ViewSceneItemManager::removeAll()
{
  if (model_->rowCount() > 1)
  {
    LOG_DEBUG("ViewScene items cleared" << std::endl);
    model_->removeRows(1, model_->rowCount() - 1);
    items_.clear();
  }
}

void ViewSceneItemManager::slotChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
  auto index = topLeft.row() - 1;
  QStandardItem* item = items_[index];
  if (item->checkState() == Qt::Unchecked)
  {
    LOG_DEBUG("Item " << item->text().toStdString() << " Unchecked!" << std::endl);
    Q_EMIT itemUnselected(item->text());
  }
  else if (item->checkState() == Qt::Checked)
  {
    LOG_DEBUG("Item " << item->text().toStdString() << " Checked!" << std::endl);
    Q_EMIT itemSelected(item->text());
  }
}<|endoftext|>


<commit_before>// $Id: RegularData1D_test.C,v 1.4 2001/07/09 22:04:21 amoll Exp $
#include <BALL/CONCEPT/classTest.h>

///////////////////////////

#include <BALL/DATATYPE/regularData1D.h>

///////////////////////////

START_TEST(class_name, "$Id: RegularData1D_test.C,v 1.4 2001/07/09 22:04:21 amoll Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

using namespace BALL;
using namespace std;

RegularData1D* rd_ptr;
CHECK(TRegularData1D::TRegularData1D())
	rd_ptr = new RegularData1D;
	TEST_NOT_EQUAL(rd_ptr, 0)
RESULT

CHECK(TRegularData1D::~TRegularData1D())
  delete rd_ptr;
RESULT

CHECK(TRegularData1D::BALL_CREATE(RegularData1D<T>))

RESULT

RegularData1D rd;
CHECK(TRegularData1D::TRegularData1D(const TRegularData1D& data))
	rd.setBoundaries(1.1, 2.1);
	rd.resize(1);
	rd[0] = 1.2;
	RegularData1D rd2(rd);
	TEST_REAL_EQUAL(rd2.getLowerBound(), 1.1)
	TEST_REAL_EQUAL(rd2.getUpperBound(), 2.1)
	TEST_REAL_EQUAL(rd2[0], 1.2)
	TEST_EQUAL(rd2.getSize(), 1)
RESULT

CHECK(TRegularData1D::clear())
	rd.clear();
	TEST_REAL_EQUAL(rd.getLowerBound(), 1.1)
	TEST_REAL_EQUAL(rd.getUpperBound(), 2.1)
	TEST_EQUAL(rd.getSize(), 1)
	TEST_REAL_EQUAL(rd[0], 0.0)
RESULT

CHECK(TRegularData1D::destroy())
	rd[0] = 2.3;
	rd.destroy();
	TEST_REAL_EQUAL(rd.getLowerBound(), 0.0)
	TEST_REAL_EQUAL(rd.getUpperBound(), 0.0)
	TEST_EQUAL(rd.getSize(), 0)
RESULT

CHECK(TRegularData1D::TRegularData1D& operator = (const TRegularData1D& data))
	rd.setBoundaries(1.1, 2.1);
	rd.resize(1);
	rd[0] = 1.2;
	RegularData1D rd2 = rd;
	TEST_REAL_EQUAL(rd2.getLowerBound(), 1.1)
	TEST_REAL_EQUAL(rd2.getUpperBound(), 2.1)
	TEST_REAL_EQUAL(rd2[0], 1.2)
	TEST_EQUAL(rd2.getSize(), 1)
RESULT

CHECK(TRegularData1D::TRegularData1D& operator = (const VectorType& data))
	RegularData1D::VectorType v;
	v.push_back(1.1);
	v.push_back(1.2);
	v.push_back(1.3);
	v.push_back(1.4);
	RegularData1D rd2 = v;
	TEST_REAL_EQUAL(rd2.getLowerBound(), 1.1)
	TEST_REAL_EQUAL(rd2.getUpperBound(), 1.4)
	TEST_EQUAL(rd2.getSize(), 4)
RESULT

CHECK(TRegularData1D::bool operator == (const TRegularData1D& data) const )
	rd.destroy();
	rd.resize(4);
	rd[0] = 1.1;
	rd[1] = 1.2;
	rd[2] = 1.3;
	rd[3] = 1.4;
	RegularData1D rd2 = rd;
	TEST_EQUAL(rd == rd2, true)
	rd2[3] = 1.41;
	TEST_EQUAL(rd == rd2, false)
	rd2[3] = 1.4;
	TEST_EQUAL(rd == rd2, true)
	rd.setBoundaries(1.1, 1.4);
	TEST_EQUAL(rd == rd2, false)
	rd2.setBoundaries(1.1, 1.4);
	TEST_EQUAL(rd == rd2, true)
RESULT

CHECK(TRegularData1D::T& operator [] (Position index) const )
  TEST_REAL_EQUAL(rd[3], 1.4)
	TEST_EXCEPTION(Exception::IndexOverflow, rd[4])
RESULT

CHECK(TRegularData1D::T& operator [] (Position index))
  rd[3] = 1.5;
	TEST_REAL_EQUAL(rd[3], 1.5)
	TEST_EXCEPTION(Exception::IndexOverflow, rd[4] = 44.4)
RESULT

RegularData1D rd2;
CHECK(TRegularData1D::getSize() const )
  TEST_EQUAL(rd.getSize(), 4)
	TEST_EQUAL(rd2.getSize(), 0)
RESULT

CHECK(TRegularData1D::getLowerBound() const )
	rd.setBoundaries(1.1, 1.5);
	TEST_REAL_EQUAL(rd.getLowerBound(), 1.1)
	TEST_REAL_EQUAL(rd2.getLowerBound(), 0.0)
RESULT

CHECK(TRegularData1D::getUpperBound() const )
	TEST_REAL_EQUAL(rd.getUpperBound(), 1.5)
	TEST_REAL_EQUAL(rd2.getUpperBound(), 0.0)
RESULT

CHECK(TRegularData1D::setLowerBound())
	rd.setBoundaries(-99.9, 99.9);
	TEST_REAL_EQUAL(rd.getLowerBound(), -99.9)
	TEST_REAL_EQUAL(rd.getUpperBound(), 99.9)
	rd.setBoundaries(99.9, -99.9);
	TEST_REAL_EQUAL(rd.getLowerBound(), -99.9)
	TEST_REAL_EQUAL(rd.getUpperBound(), 99.9)
RESULT

CHECK(TRegularData1D::resize(Size new_size))
	TEST_EQUAL(rd.getSize(), 4)
	rd.resize(99);
	TEST_EQUAL(rd.getSize(), 99)
	TEST_REAL_EQUAL(rd[98], 0.0)
	rd.resize(3);
	TEST_EQUAL(rd.getSize(), 3)
	TEST_REAL_EQUAL(rd[2], 1.3)
	TEST_EXCEPTION(Exception::IndexOverflow, rd[3])
RESULT

CHECK(TRegularData1D::rescale(Size new_size))
	TRegularData1D<float>	data;
	TEST_EQUAL(data.getSize(), 0)
	data.rescale(1);
	TEST_EQUAL(data.getSize(), 1)
	TEST_EQUAL(data[0], 0.0)
	data[0] = 2.0;
	data.rescale(2);
	TEST_EQUAL(data.getSize(), 2)
	TEST_EQUAL(data[0], 2.0)
	TEST_EQUAL(data[0], 2.0)
	data[0] = 1.0;
	data.rescale(3);
	TEST_EQUAL(data.getSize(), 3)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.5)
	TEST_REAL_EQUAL(data[2], 2.0)
	data.rescale(4);
	TEST_EQUAL(data.getSize(), 4)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.3333333)
	TEST_REAL_EQUAL(data[2], 1.6666667)
	TEST_REAL_EQUAL(data[3], 2.0)
RESULT

CHECK(TRegularData1D::rescale(double lower, double upper, Size new_size))
	TRegularData1D<float>	data;
	data.resize(2);
	data.setBoundaries(0.0, 1.0);
	data[0] = 1.0;
	data[1] = 2.0;
	data.rescale(0.0, 1.0, 3);
	TEST_EQUAL(data.getSize(), 3)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.5)
	TEST_REAL_EQUAL(data[2], 2.0)
	data.rescale(0.0, 1.0, 4);
	TEST_EQUAL(data.getSize(), 4)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.3333333)
	TEST_REAL_EQUAL(data[2], 1.6666667)
	TEST_REAL_EQUAL(data[3], 2.0)
	data.rescale(0.0, 1.0, 4);
	TEST_EQUAL(data.getSize(), 4)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.3333333)
	TEST_REAL_EQUAL(data[2], 1.6666667)
	TEST_REAL_EQUAL(data[3], 2.0)
	data.rescale(-1.0, 2.0, 10);
	TEST_EQUAL(data.getSize(), 10)
	TEST_REAL_EQUAL(data[0], 0.0)
	TEST_REAL_EQUAL(data[1], 0.0)
	TEST_REAL_EQUAL(data[2], 0.0)
	TEST_REAL_EQUAL(data[3], 1.0)
	TEST_REAL_EQUAL(data[4], 1.3333333)
	TEST_REAL_EQUAL(data[5], 1.6666667)
	TEST_REAL_EQUAL(data[6], 2.0)
	TEST_REAL_EQUAL(data[7], 0.0)
	TEST_REAL_EQUAL(data[8], 0.0)
	TEST_REAL_EQUAL(data[9], 0.0)
	data.rescale(0.0, 1.0, 3);
	TEST_EQUAL(data.getSize(), 3)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.5)
	TEST_REAL_EQUAL(data[2], 2.0)
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<commit_msg>fixed: test for operator =<commit_after>// $Id: RegularData1D_test.C,v 1.5 2001/07/10 08:28:21 amoll Exp $
#include <BALL/CONCEPT/classTest.h>

///////////////////////////

#include <BALL/DATATYPE/regularData1D.h>

///////////////////////////

START_TEST(class_name, "$Id: RegularData1D_test.C,v 1.5 2001/07/10 08:28:21 amoll Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

using namespace BALL;
using namespace std;

RegularData1D* rd_ptr;
CHECK(TRegularData1D::TRegularData1D())
	rd_ptr = new RegularData1D;
	TEST_NOT_EQUAL(rd_ptr, 0)
RESULT

CHECK(TRegularData1D::~TRegularData1D())
  delete rd_ptr;
RESULT

CHECK(TRegularData1D::BALL_CREATE(RegularData1D<T>))

RESULT

RegularData1D rd;
CHECK(TRegularData1D::TRegularData1D(const TRegularData1D& data))
	rd.setBoundaries(1.1, 2.1);
	rd.resize(1);
	rd[0] = 1.2;
	RegularData1D rd2(rd);
	TEST_REAL_EQUAL(rd2.getLowerBound(), 1.1)
	TEST_REAL_EQUAL(rd2.getUpperBound(), 2.1)
	TEST_REAL_EQUAL(rd2[0], 1.2)
	TEST_EQUAL(rd2.getSize(), 1)
RESULT

CHECK(TRegularData1D::clear())
	rd.clear();
	TEST_REAL_EQUAL(rd.getLowerBound(), 1.1)
	TEST_REAL_EQUAL(rd.getUpperBound(), 2.1)
	TEST_EQUAL(rd.getSize(), 1)
	TEST_REAL_EQUAL(rd[0], 0.0)
RESULT

CHECK(TRegularData1D::destroy())
	rd[0] = 2.3;
	rd.destroy();
	TEST_REAL_EQUAL(rd.getLowerBound(), 0.0)
	TEST_REAL_EQUAL(rd.getUpperBound(), 0.0)
	TEST_EQUAL(rd.getSize(), 0)
RESULT

CHECK(TRegularData1D::TRegularData1D& operator = (const TRegularData1D& data))
	rd.setBoundaries(1.1, 2.1);
	rd.resize(1);
	rd[0] = 1.2;
	RegularData1D rd2 = rd;
	TEST_REAL_EQUAL(rd2.getLowerBound(), 1.1)
	TEST_REAL_EQUAL(rd2.getUpperBound(), 2.1)
	TEST_REAL_EQUAL(rd2[0], 1.2)
	TEST_EQUAL(rd2.getSize(), 1)
RESULT

CHECK(TRegularData1D::TRegularData1D& operator = (const VectorType& data))
	RegularData1D::VectorType v;
	v.push_back(1.1);
	v.push_back(1.2);
	v.push_back(1.3);
	v.push_back(1.4);
	RegularData1D rd2;// = v;
	rd2 = v;
	TEST_EQUAL(rd2.getSize(), 4)
	TEST_REAL_EQUAL(rd2[0], 1.1)
	TEST_REAL_EQUAL(rd2[1], 1.2)
	TEST_REAL_EQUAL(rd2[2], 1.3)
	TEST_REAL_EQUAL(rd2[3], 1.4)
RESULT

CHECK(TRegularData1D::bool operator == (const TRegularData1D& data) const )
	rd.destroy();
	rd.resize(4);
	rd[0] = 1.1;
	rd[1] = 1.2;
	rd[2] = 1.3;
	rd[3] = 1.4;
	RegularData1D rd2 = rd;
	TEST_EQUAL(rd == rd2, true)
	rd2[3] = 1.41;
	TEST_EQUAL(rd == rd2, false)
	rd2[3] = 1.4;
	TEST_EQUAL(rd == rd2, true)
	rd.setBoundaries(1.1, 1.4);
	TEST_EQUAL(rd == rd2, false)
	rd2.setBoundaries(1.1, 1.4);
	TEST_EQUAL(rd == rd2, true)
RESULT

CHECK(TRegularData1D::T& operator [] (Position index) const )
  TEST_REAL_EQUAL(rd[3], 1.4)
	TEST_EXCEPTION(Exception::IndexOverflow, rd[4])
RESULT

CHECK(TRegularData1D::T& operator [] (Position index))
  rd[3] = 1.5;
	TEST_REAL_EQUAL(rd[3], 1.5)
	TEST_EXCEPTION(Exception::IndexOverflow, rd[4] = 44.4)
RESULT

RegularData1D rd2;
CHECK(TRegularData1D::getSize() const )
  TEST_EQUAL(rd.getSize(), 4)
	TEST_EQUAL(rd2.getSize(), 0)
RESULT

CHECK(TRegularData1D::getLowerBound() const )
	rd.setBoundaries(1.1, 1.5);
	TEST_REAL_EQUAL(rd.getLowerBound(), 1.1)
	TEST_REAL_EQUAL(rd2.getLowerBound(), 0.0)
RESULT

CHECK(TRegularData1D::getUpperBound() const )
	TEST_REAL_EQUAL(rd.getUpperBound(), 1.5)
	TEST_REAL_EQUAL(rd2.getUpperBound(), 0.0)
RESULT

CHECK(TRegularData1D::setLowerBound())
	rd.setBoundaries(-99.9, 99.9);
	TEST_REAL_EQUAL(rd.getLowerBound(), -99.9)
	TEST_REAL_EQUAL(rd.getUpperBound(), 99.9)
	rd.setBoundaries(99.9, -99.9);
	TEST_REAL_EQUAL(rd.getLowerBound(), -99.9)
	TEST_REAL_EQUAL(rd.getUpperBound(), 99.9)
RESULT

CHECK(TRegularData1D::resize(Size new_size))
	TEST_EQUAL(rd.getSize(), 4)
	rd.resize(99);
	TEST_EQUAL(rd.getSize(), 99)
	TEST_REAL_EQUAL(rd[98], 0.0)
	rd.resize(3);
	TEST_EQUAL(rd.getSize(), 3)
	TEST_REAL_EQUAL(rd[2], 1.3)
	TEST_EXCEPTION(Exception::IndexOverflow, rd[3])
RESULT

CHECK(TRegularData1D::rescale(Size new_size))
	TRegularData1D<float>	data;
	TEST_EQUAL(data.getSize(), 0)
	data.rescale(1);
	TEST_EQUAL(data.getSize(), 1)
	TEST_EQUAL(data[0], 0.0)
	data[0] = 2.0;
	data.rescale(2);
	TEST_EQUAL(data.getSize(), 2)
	TEST_EQUAL(data[0], 2.0)
	TEST_EQUAL(data[0], 2.0)
	data[0] = 1.0;
	data.rescale(3);
	TEST_EQUAL(data.getSize(), 3)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.5)
	TEST_REAL_EQUAL(data[2], 2.0)
	data.rescale(4);
	TEST_EQUAL(data.getSize(), 4)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.3333333)
	TEST_REAL_EQUAL(data[2], 1.6666667)
	TEST_REAL_EQUAL(data[3], 2.0)
RESULT

CHECK(TRegularData1D::rescale(double lower, double upper, Size new_size))
	TRegularData1D<float>	data;
	data.resize(2);
	data.setBoundaries(0.0, 1.0);
	data[0] = 1.0;
	data[1] = 2.0;
	data.rescale(0.0, 1.0, 3);
	TEST_EQUAL(data.getSize(), 3)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.5)
	TEST_REAL_EQUAL(data[2], 2.0)
	data.rescale(0.0, 1.0, 4);
	TEST_EQUAL(data.getSize(), 4)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.3333333)
	TEST_REAL_EQUAL(data[2], 1.6666667)
	TEST_REAL_EQUAL(data[3], 2.0)
	data.rescale(0.0, 1.0, 4);
	TEST_EQUAL(data.getSize(), 4)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.3333333)
	TEST_REAL_EQUAL(data[2], 1.6666667)
	TEST_REAL_EQUAL(data[3], 2.0)
	data.rescale(-1.0, 2.0, 10);
	TEST_EQUAL(data.getSize(), 10)
	TEST_REAL_EQUAL(data[0], 0.0)
	TEST_REAL_EQUAL(data[1], 0.0)
	TEST_REAL_EQUAL(data[2], 0.0)
	TEST_REAL_EQUAL(data[3], 1.0)
	TEST_REAL_EQUAL(data[4], 1.3333333)
	TEST_REAL_EQUAL(data[5], 1.6666667)
	TEST_REAL_EQUAL(data[6], 2.0)
	TEST_REAL_EQUAL(data[7], 0.0)
	TEST_REAL_EQUAL(data[8], 0.0)
	TEST_REAL_EQUAL(data[9], 0.0)
	data.rescale(0.0, 1.0, 3);
	TEST_EQUAL(data.getSize(), 3)
	TEST_REAL_EQUAL(data[0], 1.0)
	TEST_REAL_EQUAL(data[1], 1.5)
	TEST_REAL_EQUAL(data[2], 2.0)
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<|endoftext|>


<commit_before>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "base/ipc/shared_memory.h"

#include "base/logging.h"
#include "base/ipc/shared_memory_factory_proxy.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"

#include <atomic>
#include <random>

#include <AclAPI.h>

namespace base {

namespace {

int randomInt()
{
    std::random_device device;
    std::mt19937 generator(device());

    std::uniform_int_distribution<> distance(0, std::numeric_limits<int>::max());
    return distance(generator);
}

int createUniqueId()
{
    static std::atomic_int last_id = randomInt();
    return last_id++;
}

std::u16string createFilePath(int id)
{
    static const char16_t kPrefix[] = u"Global\\aspia_";
    return kPrefix + numberToString16(id);
}

bool modeToDesiredAccess(SharedMemory::Mode mode, DWORD* desired_access)
{
    switch (mode)
    {
        case SharedMemory::Mode::READ_ONLY:
            *desired_access = FILE_MAP_READ;
            return true;

        case SharedMemory::Mode::READ_WRITE:
            *desired_access = FILE_MAP_WRITE;
            return true;

        default:
            NOTREACHED();
            return false;
    }
}

bool createFileMapping(SharedMemory::Mode mode, int id, size_t size, win::ScopedHandle* out)
{
    DWORD protect;

    switch (mode)
    {
        case SharedMemory::Mode::READ_ONLY:
            protect = PAGE_READONLY;
            break;

        case SharedMemory::Mode::READ_WRITE:
            protect = PAGE_READWRITE;
            break;

        default:
            NOTREACHED();
            return false;
    }

    const DWORD low = size & 0xFFFFFFFF;
    const DWORD high = static_cast<DWORD64>(size) >> 32 & 0xFFFFFFFF;

    std::u16string path = createFilePath(id);

    win::ScopedHandle file(CreateFileMappingW(
        INVALID_HANDLE_VALUE, nullptr, protect, high, low, asWide(path)));
    if (!file.isValid())
    {
        PLOG(LS_WARNING) << "CreateFileMappingW failed";
        return false;
    }

    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        LOG(LS_WARNING) << "Already exists shared memory: " << path;
        return false;
    }

    DWORD error_code = SetSecurityInfo(
        file, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, nullptr, nullptr);
    if (error_code != ERROR_SUCCESS)
    {
        LOG(LS_WARNING) << "SetSecurityInfo failed: " << SystemError::toString(error_code);
        return false;
    }

    out->swap(file);
    return true;
}

bool openFileMapping(SharedMemory::Mode mode, int id, win::ScopedHandle* out)
{
    DWORD desired_access;
    if (!modeToDesiredAccess(mode, &desired_access))
        return false;

    win::ScopedHandle file(OpenFileMappingW(desired_access, FALSE, asWide(createFilePath(id))));
    if (!file.isValid())
    {
        PLOG(LS_WARNING) << "OpenFileMappingW failed";
        return false;
    }

    out->swap(file);
    return true;
}

bool mapViewOfFile(SharedMemory::Mode mode, HANDLE file, void** memory)
{
    DWORD desired_access;
    if (!modeToDesiredAccess(mode, &desired_access))
        return false;

    *memory = MapViewOfFile(file, desired_access, 0, 0, 0);
    if (!*memory)
    {
        PLOG(LS_WARNING) << "MapViewOfFile failed";
        return false;
    }

    return true;
}

} // namespace

#if defined(OS_WIN)
const SharedMemory::Handle kInvalidHandle = nullptr;
#else
const SharedMemory::Handle kInvalidHandle = -1;
#endif

SharedMemory::SharedMemory(int id,
                           win::ScopedHandle&& handle,
                           void* data,
                           std::shared_ptr<SharedMemoryFactoryProxy> factory_proxy)
    : factory_proxy_(std::move(factory_proxy)),
      handle_(std::move(handle)),
      data_(data),
      id_(id)
{
    if (factory_proxy_)
        factory_proxy_->onSharedMemoryCreate(id_);
}

SharedMemory::~SharedMemory()
{
    if (factory_proxy_)
        factory_proxy_->onSharedMemoryDestroy(id_);

    UnmapViewOfFile(data_);
}

// static
std::unique_ptr<SharedMemory> SharedMemory::create(
    Mode mode, size_t size, std::shared_ptr<SharedMemoryFactoryProxy> factory_proxy)
{
    static const int kRetryCount = 10;

    win::ScopedHandle file;
    int id = -1;

    for (int i = 0; i < kRetryCount; ++i)
    {
        id = createUniqueId();
        if (createFileMapping(mode, id, size, &file))
            break;
    }

    if (!file.isValid())
        return nullptr;

    void* memory;
    if (!mapViewOfFile(mode, file, &memory))
        return nullptr;

    memset(memory, 0, size);

    return std::unique_ptr<SharedMemory>(
        new SharedMemory(id, std::move(file), memory, std::move(factory_proxy)));
}

// static
std::unique_ptr<SharedMemory> SharedMemory::open(
    Mode mode, int id, std::shared_ptr<SharedMemoryFactoryProxy> factory_proxy)
{
    win::ScopedHandle file;
    if (!openFileMapping(mode, id, &file))
        return nullptr;

    void* memory;
    if (!mapViewOfFile(mode, file, &memory))
        return nullptr;

    return std::unique_ptr<SharedMemory>(
        new SharedMemory(id, std::move(file), memory, std::move(factory_proxy)));
}

} // namespace base
<commit_msg>Initialize variables.<commit_after>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "base/ipc/shared_memory.h"

#include "base/logging.h"
#include "base/ipc/shared_memory_factory_proxy.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"

#include <atomic>
#include <random>

#include <AclAPI.h>

namespace base {

namespace {

int randomInt()
{
    std::random_device device;
    std::mt19937 generator(device());

    std::uniform_int_distribution<> distance(0, std::numeric_limits<int>::max());
    return distance(generator);
}

int createUniqueId()
{
    static std::atomic_int last_id = randomInt();
    return last_id++;
}

std::u16string createFilePath(int id)
{
    static const char16_t kPrefix[] = u"Global\\aspia_";
    return kPrefix + numberToString16(id);
}

bool modeToDesiredAccess(SharedMemory::Mode mode, DWORD* desired_access)
{
    switch (mode)
    {
        case SharedMemory::Mode::READ_ONLY:
            *desired_access = FILE_MAP_READ;
            return true;

        case SharedMemory::Mode::READ_WRITE:
            *desired_access = FILE_MAP_WRITE;
            return true;

        default:
            NOTREACHED();
            return false;
    }
}

bool createFileMapping(SharedMemory::Mode mode, int id, size_t size, win::ScopedHandle* out)
{
    DWORD protect;

    switch (mode)
    {
        case SharedMemory::Mode::READ_ONLY:
            protect = PAGE_READONLY;
            break;

        case SharedMemory::Mode::READ_WRITE:
            protect = PAGE_READWRITE;
            break;

        default:
            NOTREACHED();
            return false;
    }

    const DWORD low = size & 0xFFFFFFFF;
    const DWORD high = static_cast<DWORD64>(size) >> 32 & 0xFFFFFFFF;

    std::u16string path = createFilePath(id);

    win::ScopedHandle file(CreateFileMappingW(
        INVALID_HANDLE_VALUE, nullptr, protect, high, low, asWide(path)));
    if (!file.isValid())
    {
        PLOG(LS_WARNING) << "CreateFileMappingW failed";
        return false;
    }

    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        LOG(LS_WARNING) << "Already exists shared memory: " << path;
        return false;
    }

    DWORD error_code = SetSecurityInfo(
        file, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, nullptr, nullptr);
    if (error_code != ERROR_SUCCESS)
    {
        LOG(LS_WARNING) << "SetSecurityInfo failed: " << SystemError::toString(error_code);
        return false;
    }

    out->swap(file);
    return true;
}

bool openFileMapping(SharedMemory::Mode mode, int id, win::ScopedHandle* out)
{
    DWORD desired_access;
    if (!modeToDesiredAccess(mode, &desired_access))
        return false;

    win::ScopedHandle file(OpenFileMappingW(desired_access, FALSE, asWide(createFilePath(id))));
    if (!file.isValid())
    {
        PLOG(LS_WARNING) << "OpenFileMappingW failed";
        return false;
    }

    out->swap(file);
    return true;
}

bool mapViewOfFile(SharedMemory::Mode mode, HANDLE file, void** memory)
{
    DWORD desired_access;
    if (!modeToDesiredAccess(mode, &desired_access))
        return false;

    *memory = MapViewOfFile(file, desired_access, 0, 0, 0);
    if (!*memory)
    {
        PLOG(LS_WARNING) << "MapViewOfFile failed";
        return false;
    }

    return true;
}

} // namespace

#if defined(OS_WIN)
const SharedMemory::Handle kInvalidHandle = nullptr;
#else
const SharedMemory::Handle kInvalidHandle = -1;
#endif

SharedMemory::SharedMemory(int id,
                           win::ScopedHandle&& handle,
                           void* data,
                           std::shared_ptr<SharedMemoryFactoryProxy> factory_proxy)
    : factory_proxy_(std::move(factory_proxy)),
      handle_(std::move(handle)),
      data_(data),
      id_(id)
{
    if (factory_proxy_)
        factory_proxy_->onSharedMemoryCreate(id_);
}

SharedMemory::~SharedMemory()
{
    if (factory_proxy_)
        factory_proxy_->onSharedMemoryDestroy(id_);

    UnmapViewOfFile(data_);
}

// static
std::unique_ptr<SharedMemory> SharedMemory::create(
    Mode mode, size_t size, std::shared_ptr<SharedMemoryFactoryProxy> factory_proxy)
{
    static const int kRetryCount = 10;

    win::ScopedHandle file;
    int id = -1;

    for (int i = 0; i < kRetryCount; ++i)
    {
        id = createUniqueId();
        if (createFileMapping(mode, id, size, &file))
            break;
    }

    if (!file.isValid())
        return nullptr;

    void* memory = nullptr;
    if (!mapViewOfFile(mode, file, &memory))
        return nullptr;

    memset(memory, 0, size);

    return std::unique_ptr<SharedMemory>(
        new SharedMemory(id, std::move(file), memory, std::move(factory_proxy)));
}

// static
std::unique_ptr<SharedMemory> SharedMemory::open(
    Mode mode, int id, std::shared_ptr<SharedMemoryFactoryProxy> factory_proxy)
{
    win::ScopedHandle file;
    if (!openFileMapping(mode, id, &file))
        return nullptr;

    void* memory = nullptr;
    if (!mapViewOfFile(mode, file, &memory))
        return nullptr;

    return std::unique_ptr<SharedMemory>(
        new SharedMemory(id, std::move(file), memory, std::move(factory_proxy)));
}

} // namespace base
<|endoftext|>


<commit_before>/*!
    \file environment.cpp
    \brief Environment management implementation
    \author Ivan Shynkarenka
    \date 09.07.2015
    \copyright MIT License
*/

#include "benchmark/environment.h"

#include <chrono>
#include <sstream>

#if defined(__APPLE__)
#include <sys/sysctl.h>
#elif defined(__CYGWIN__)
#include <sys/utsname.h>
#elif defined(linux) || defined(__linux) || defined(__linux__)
#include <sys/stat.h>
#include <fstream>
#include <regex>
#endif
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#include <windows.h>
#endif

namespace CppBenchmark {

bool Environment::Is32BitOS()
{
    return !Is64BitOS();
}

bool Environment::Is64BitOS()
{
#if defined(__APPLE__)
    return true;
#elif defined(linux) || defined(__linux) || defined(__linux__)
    struct stat buffer;
    return (stat("/lib64/ld-linux-x86-64.so.2", &buffer) == 0);
#elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#if defined(_WIN64)
    return true;
#elif defined(_WIN32)
    BOOL bWow64Process = FALSE;
    return IsWow64Process(GetCurrentProcess(), &bWow64Process) && bWow64Process;
#endif
#else
    #error Unsupported platform
#endif
}

bool Environment::Is32BitProcess()
{
    return !Is64BitProcess();
}

bool Environment::Is64BitProcess()
{
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
#if defined(__x86_64__) || defined(__amd64__) || defined(__aarch64__) || defined(__ia64__) || defined(__ppc64__)
    return true;
#else
    return false;
#endif
#elif defined(_WIN32) || defined(_WIN64)
#if defined(_WIN64)
    return true;
#elif defined(_WIN32)
    return false;
#endif
#else
    #error Unsupported platform
#endif
}

bool Environment::IsDebug()
{
    return !IsRelease();
}

bool Environment::IsRelease()
{
#if defined(NDEBUG)
    return true;
#else
    return false;
#endif
}

bool Environment::IsBigEndian()
{
    char16_t test = 0x0102;
    return ((char*)&test)[0] == 0x01;
}

bool Environment::IsLittleEndian()
{
    char16_t test = 0x0102;
    return ((char*)&test)[0] == 0x02;
}

std::string Environment::OSVersion()
{
#if defined(__APPLE__)
    char result[1024];
    size_t size = sizeof(result);
    if (sysctlbyname("kern.osrelease", result, &size, nullptr, 0) == 0)
        return result;

    return "<apple>";
#elif defined(__CYGWIN__)
    struct utsname name;
    if (uname(&name) == 0)
    {
        std::string result(name.sysname);
        result.append(" ");
        result.append(name.release);
        result.append(" ");
        result.append(name.version);
        return result;
    }

    return "<cygwin>";
#elif defined(linux) || defined(__linux) || defined(__linux__)
    static std::regex pattern("DISTRIB_DESCRIPTION=\"(.*)\"");

    std::string line;
    std::ifstream stream("/etc/lsb-release");
    while (getline(stream, line))
    {
        std::smatch matches;
        if (std::regex_match(line, matches, pattern))
            return matches[1];
    }

    return "<linux>";
#elif defined(_WIN32) || defined(_WIN64)
    static void(__stdcall *GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall*)(LPSYSTEM_INFO))GetProcAddress(GetModuleHandle("kernel32.dll"), "GetNativeSystemInfo");
    static BOOL(__stdcall *GetProductInfo)(IN DWORD dwOSMajorVersion, IN DWORD dwOSMinorVersion, IN DWORD dwSpMajorVersion, IN DWORD dwSpMinorVersion, OUT PDWORD pdwReturnedProductType) = (BOOL(__stdcall*)(DWORD, DWORD, DWORD, DWORD, PDWORD))GetProcAddress(GetModuleHandle("kernel32.dll"), "GetProductInfo");

    OSVERSIONINFOEX osvi;
    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

    BOOL bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi);
    if (bOsVersionInfoEx == 0)
        return "<windows>";

    SYSTEM_INFO si;
    ZeroMemory(&si, sizeof(SYSTEM_INFO));

    if (GetNativeSystemInfo != nullptr)
        GetNativeSystemInfo(&si);
    else
        GetSystemInfo(&si);

    if ((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) || (osvi.dwMajorVersion <= 4))
    {
        return "<windows>";
    }

    std::stringstream os;

    // Windows version
    os << "Microsoft ";
    if (osvi.dwMajorVersion >= 6)
    {
        if (osvi.dwMajorVersion == 10)
        {
            if (osvi.dwMinorVersion == 0)
            {
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    os << "Windows 10 ";
                else
                    os << "Windows Server 2016 ";
            }
        }
        else if (osvi.dwMajorVersion == 6)
        {
            if (osvi.dwMinorVersion == 3)
            {
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    os << "Windows 8.1 ";
                else
                    os << "Windows Server 2012 R2 ";
            }
            else if (osvi.dwMinorVersion == 2)
            {
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    os << "Windows 8 ";
                else
                    os << "Windows Server 2012 ";
            }
            else if (osvi.dwMinorVersion == 1)
            {
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    os << "Windows 7 ";
                else
                    os << "Windows Server 2008 R2 ";
            }
            else if (osvi.dwMinorVersion == 0)
            {
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    os << "Windows Vista ";
                else
                    os << "Windows Server 2008 ";
            }
        }

        DWORD dwType;
        if ((GetProductInfo != nullptr) && GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType))
        {
            switch (dwType)
            {
                case PRODUCT_ULTIMATE:
                    os << "Ultimate Edition";
                    break;
                case PRODUCT_PROFESSIONAL:
                    os << "Professional";
                    break;
                case PRODUCT_HOME_PREMIUM:
                    os << "Home Premium Edition";
                    break;
                case PRODUCT_HOME_BASIC:
                    os << "Home Basic Edition";
                    break;
                case PRODUCT_ENTERPRISE:
                    os << "Enterprise Edition";
                    break;
                case PRODUCT_BUSINESS:
                    os << "Business Edition";
                    break;
                case PRODUCT_STARTER:
                    os << "Starter Edition";
                    break;
                case PRODUCT_CLUSTER_SERVER:
                    os << "Cluster Server Edition";
                    break;
                case PRODUCT_DATACENTER_SERVER:
                    os << "Datacenter Edition";
                    break;
                case PRODUCT_DATACENTER_SERVER_CORE:
                    os << "Datacenter Edition (core installation)";
                    break;
                case PRODUCT_ENTERPRISE_SERVER:
                    os << "Enterprise Edition";
                    break;
                case PRODUCT_ENTERPRISE_SERVER_CORE:
                    os << "Enterprise Edition (core installation)";
                    break;
                case PRODUCT_ENTERPRISE_SERVER_IA64:
                    os << "Enterprise Edition for Itanium-based Systems";
                    break;
                case PRODUCT_SMALLBUSINESS_SERVER:
                    os << "Small Business Server";
                    break;
                case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
                    os << "Small Business Server Premium Edition";
                    break;
                case PRODUCT_STANDARD_SERVER:
                    os << "Standard Edition";
                    break;
                case PRODUCT_STANDARD_SERVER_CORE:
                    os << "Standard Edition (core installation)";
                    break;
                case PRODUCT_WEB_SERVER:
                    os << "Web Server Edition";
                    break;
            }
        }
    }
    else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 2))
    {
        if (GetSystemMetrics(SM_SERVERR2))
            os << "Windows Server 2003 R2, ";
        else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER)
            os << "Windows Storage Server 2003";
        else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER)
            os << "Windows Home Server";
        else if ((osvi.wProductType == VER_NT_WORKSTATION) && (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64))
            os << "Windows XP Professional x64 Edition";
        else
            os << "Windows Server 2003, ";
        if (osvi.wProductType != VER_NT_WORKSTATION)
        {
            if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64)
            {
                if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter Edition for Itanium-based Systems";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise Edition for Itanium-based Systems";
            }
            else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
            {
                if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter x64 Edition";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise x64 Edition";
                else
                    os << "Standard x64 Edition";
            }
            else
            {
                if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
                    os << "Compute Cluster Edition";
                else if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter Edition";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise Edition";
                else if (osvi.wSuiteMask & VER_SUITE_BLADE)
                    os << "Web Edition";
                else
                    os << "Standard Edition";
            }
        }
    }
    else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 1))
    {
        os << "Windows XP ";
        if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
            os << "Home Edition";
        else
            os << "Professional";
    }
    else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0))
    {
        os << "Windows 2000 ";
        if (osvi.wProductType == VER_NT_WORKSTATION)
            os <<  "Professional";
        else
        {
            if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                os << "Datacenter Server";
            else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                os << "Advanced Server";
            else
                os << "Server";
        }
    }

    // Windows Service Pack version
    if (std::strlen(osvi.szCSDVersion) > 0)
        os << " " << osvi.szCSDVersion;

    // Windows build
    os << " (build " << osvi.dwBuildNumber << ")";

    // Windows architecture
    if ( osvi.dwMajorVersion >= 6 )
    {
        if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
            os <<  ", 64-bit";
        else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL)
            os << ", 32-bit";
    }

    return os.str();
#else
    #error Unsupported platform
#endif
}

std::string Environment::EndLine()
{
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
    return "\n";
#elif defined(_WIN32) || defined(_WIN64)
    return "\r\n";
#else
    #error Unsupported platform
#endif
}

time_t Environment::Timestamp()
{
    return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
}

} // namespace CppBenchmark
<commit_msg>build<commit_after>/*!
    \file environment.cpp
    \brief Environment management implementation
    \author Ivan Shynkarenka
    \date 09.07.2015
    \copyright MIT License
*/

#include "benchmark/environment.h"

#include <chrono>
#include <sstream>

#if defined(__APPLE__)
#include <sys/sysctl.h>
#elif defined(__CYGWIN__)
#include <sys/utsname.h>
#elif defined(linux) || defined(__linux) || defined(__linux__)
#include <sys/stat.h>
#include <fstream>
#include <regex>
#endif
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#include <windows.h>
#endif

namespace CppBenchmark {

bool Environment::Is32BitOS()
{
    return !Is64BitOS();
}

bool Environment::Is64BitOS()
{
#if defined(__APPLE__)
    return true;
#elif defined(linux) || defined(__linux) || defined(__linux__)
    struct stat buffer;
    return (stat("/lib64/ld-linux-x86-64.so.2", &buffer) == 0);
#elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#if defined(_WIN64)
    return true;
#elif defined(_WIN32) || defined(__CYGWIN__)
    BOOL bWow64Process = FALSE;
    return IsWow64Process(GetCurrentProcess(), &bWow64Process) && bWow64Process;
#endif
#else
    #error Unsupported platform
#endif
}

bool Environment::Is32BitProcess()
{
    return !Is64BitProcess();
}

bool Environment::Is64BitProcess()
{
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
#if defined(__x86_64__) || defined(__amd64__) || defined(__aarch64__) || defined(__ia64__) || defined(__ppc64__)
    return true;
#else
    return false;
#endif
#elif defined(_WIN32) || defined(_WIN64)
#if defined(_WIN64)
    return true;
#elif defined(_WIN32)
    return false;
#endif
#else
    #error Unsupported platform
#endif
}

bool Environment::IsDebug()
{
    return !IsRelease();
}

bool Environment::IsRelease()
{
#if defined(NDEBUG)
    return true;
#else
    return false;
#endif
}

bool Environment::IsBigEndian()
{
    char16_t test = 0x0102;
    return ((char*)&test)[0] == 0x01;
}

bool Environment::IsLittleEndian()
{
    char16_t test = 0x0102;
    return ((char*)&test)[0] == 0x02;
}

std::string Environment::OSVersion()
{
#if defined(__APPLE__)
    char result[1024];
    size_t size = sizeof(result);
    if (sysctlbyname("kern.osrelease", result, &size, nullptr, 0) == 0)
        return result;

    return "<apple>";
#elif defined(__CYGWIN__)
    struct utsname name;
    if (uname(&name) == 0)
    {
        std::string result(name.sysname);
        result.append(" ");
        result.append(name.release);
        result.append(" ");
        result.append(name.version);
        return result;
    }

    return "<cygwin>";
#elif defined(linux) || defined(__linux) || defined(__linux__)
    static std::regex pattern("DISTRIB_DESCRIPTION=\"(.*)\"");

    std::string line;
    std::ifstream stream("/etc/lsb-release");
    while (getline(stream, line))
    {
        std::smatch matches;
        if (std::regex_match(line, matches, pattern))
            return matches[1];
    }

    return "<linux>";
#elif defined(_WIN32) || defined(_WIN64)
    static void(__stdcall *GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall*)(LPSYSTEM_INFO))GetProcAddress(GetModuleHandle("kernel32.dll"), "GetNativeSystemInfo");
    static BOOL(__stdcall *GetProductInfo)(IN DWORD dwOSMajorVersion, IN DWORD dwOSMinorVersion, IN DWORD dwSpMajorVersion, IN DWORD dwSpMinorVersion, OUT PDWORD pdwReturnedProductType) = (BOOL(__stdcall*)(DWORD, DWORD, DWORD, DWORD, PDWORD))GetProcAddress(GetModuleHandle("kernel32.dll"), "GetProductInfo");

    OSVERSIONINFOEX osvi;
    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

    BOOL bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi);
    if (bOsVersionInfoEx == 0)
        return "<windows>";

    SYSTEM_INFO si;
    ZeroMemory(&si, sizeof(SYSTEM_INFO));

    if (GetNativeSystemInfo != nullptr)
        GetNativeSystemInfo(&si);
    else
        GetSystemInfo(&si);

    if ((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) || (osvi.dwMajorVersion <= 4))
    {
        return "<windows>";
    }

    std::stringstream os;

    // Windows version
    os << "Microsoft ";
    if (osvi.dwMajorVersion >= 6)
    {
        if (osvi.dwMajorVersion == 10)
        {
            if (osvi.dwMinorVersion == 0)
            {
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    os << "Windows 10 ";
                else
                    os << "Windows Server 2016 ";
            }
        }
        else if (osvi.dwMajorVersion == 6)
        {
            if (osvi.dwMinorVersion == 3)
            {
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    os << "Windows 8.1 ";
                else
                    os << "Windows Server 2012 R2 ";
            }
            else if (osvi.dwMinorVersion == 2)
            {
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    os << "Windows 8 ";
                else
                    os << "Windows Server 2012 ";
            }
            else if (osvi.dwMinorVersion == 1)
            {
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    os << "Windows 7 ";
                else
                    os << "Windows Server 2008 R2 ";
            }
            else if (osvi.dwMinorVersion == 0)
            {
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    os << "Windows Vista ";
                else
                    os << "Windows Server 2008 ";
            }
        }

        DWORD dwType;
        if ((GetProductInfo != nullptr) && GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType))
        {
            switch (dwType)
            {
                case PRODUCT_ULTIMATE:
                    os << "Ultimate Edition";
                    break;
                case PRODUCT_PROFESSIONAL:
                    os << "Professional";
                    break;
                case PRODUCT_HOME_PREMIUM:
                    os << "Home Premium Edition";
                    break;
                case PRODUCT_HOME_BASIC:
                    os << "Home Basic Edition";
                    break;
                case PRODUCT_ENTERPRISE:
                    os << "Enterprise Edition";
                    break;
                case PRODUCT_BUSINESS:
                    os << "Business Edition";
                    break;
                case PRODUCT_STARTER:
                    os << "Starter Edition";
                    break;
                case PRODUCT_CLUSTER_SERVER:
                    os << "Cluster Server Edition";
                    break;
                case PRODUCT_DATACENTER_SERVER:
                    os << "Datacenter Edition";
                    break;
                case PRODUCT_DATACENTER_SERVER_CORE:
                    os << "Datacenter Edition (core installation)";
                    break;
                case PRODUCT_ENTERPRISE_SERVER:
                    os << "Enterprise Edition";
                    break;
                case PRODUCT_ENTERPRISE_SERVER_CORE:
                    os << "Enterprise Edition (core installation)";
                    break;
                case PRODUCT_ENTERPRISE_SERVER_IA64:
                    os << "Enterprise Edition for Itanium-based Systems";
                    break;
                case PRODUCT_SMALLBUSINESS_SERVER:
                    os << "Small Business Server";
                    break;
                case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
                    os << "Small Business Server Premium Edition";
                    break;
                case PRODUCT_STANDARD_SERVER:
                    os << "Standard Edition";
                    break;
                case PRODUCT_STANDARD_SERVER_CORE:
                    os << "Standard Edition (core installation)";
                    break;
                case PRODUCT_WEB_SERVER:
                    os << "Web Server Edition";
                    break;
            }
        }
    }
    else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 2))
    {
        if (GetSystemMetrics(SM_SERVERR2))
            os << "Windows Server 2003 R2, ";
        else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER)
            os << "Windows Storage Server 2003";
        else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER)
            os << "Windows Home Server";
        else if ((osvi.wProductType == VER_NT_WORKSTATION) && (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64))
            os << "Windows XP Professional x64 Edition";
        else
            os << "Windows Server 2003, ";
        if (osvi.wProductType != VER_NT_WORKSTATION)
        {
            if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64)
            {
                if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter Edition for Itanium-based Systems";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise Edition for Itanium-based Systems";
            }
            else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
            {
                if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter x64 Edition";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise x64 Edition";
                else
                    os << "Standard x64 Edition";
            }
            else
            {
                if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
                    os << "Compute Cluster Edition";
                else if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter Edition";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise Edition";
                else if (osvi.wSuiteMask & VER_SUITE_BLADE)
                    os << "Web Edition";
                else
                    os << "Standard Edition";
            }
        }
    }
    else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 1))
    {
        os << "Windows XP ";
        if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
            os << "Home Edition";
        else
            os << "Professional";
    }
    else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0))
    {
        os << "Windows 2000 ";
        if (osvi.wProductType == VER_NT_WORKSTATION)
            os <<  "Professional";
        else
        {
            if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                os << "Datacenter Server";
            else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                os << "Advanced Server";
            else
                os << "Server";
        }
    }

    // Windows Service Pack version
    if (std::strlen(osvi.szCSDVersion) > 0)
        os << " " << osvi.szCSDVersion;

    // Windows build
    os << " (build " << osvi.dwBuildNumber << ")";

    // Windows architecture
    if ( osvi.dwMajorVersion >= 6 )
    {
        if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
            os <<  ", 64-bit";
        else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL)
            os << ", 32-bit";
    }

    return os.str();
#else
    #error Unsupported platform
#endif
}

std::string Environment::EndLine()
{
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
    return "\n";
#elif defined(_WIN32) || defined(_WIN64)
    return "\r\n";
#else
    #error Unsupported platform
#endif
}

time_t Environment::Timestamp()
{
    return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
}

} // namespace CppBenchmark
<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "MissionSettingsItem.h"
#include "JsonHelper.h"
#include "MissionController.h"
#include "QGCGeo.h"
#include "QGroundControlQmlGlobal.h"
#include "SimpleMissionItem.h"
#include "SettingsManager.h"
#include "AppSettings.h"
#include "MissionCommandUIInfo.h"

#include <QPolygonF>

QGC_LOGGING_CATEGORY(MissionSettingsComplexItemLog, "MissionSettingsComplexItemLog")

const char* MissionSettingsItem::jsonComplexItemTypeValue = "MissionSettings";

const char* MissionSettingsItem::_plannedHomePositionAltitudeName = "PlannedHomePositionAltitude";

QMap<QString, FactMetaData*> MissionSettingsItem::_metaDataMap;

MissionSettingsItem::MissionSettingsItem(Vehicle* vehicle, QObject* parent)
    : ComplexMissionItem                (vehicle, parent)
    , _plannedHomePositionAltitudeFact  (0, _plannedHomePositionAltitudeName,   FactMetaData::valueTypeDouble)
    , _missionEndRTL                    (false)
    , _cameraSection                    (vehicle)
    , _speedSection                     (vehicle)
    , _sequenceNumber                   (0)
    , _dirty                            (false)
{
    _editorQml = "qrc:/qml/MissionSettingsEditor.qml";

    if (_metaDataMap.isEmpty()) {
        _metaDataMap = FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/MissionSettings.FactMetaData.json"), NULL /* metaDataParent */);
    }

    _plannedHomePositionAltitudeFact.setMetaData    (_metaDataMap[_plannedHomePositionAltitudeName]);

    _plannedHomePositionAltitudeFact.setRawValue    (_plannedHomePositionAltitudeFact.rawDefaultValue());

    setHomePositionSpecialCase(true);

    connect(this,               &MissionSettingsItem::specifyMissionFlightSpeedChanged, this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
    connect(this,               &MissionSettingsItem::missionEndRTLChanged,             this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
    connect(&_cameraSection,    &CameraSection::itemCountChanged,                       this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
    connect(&_speedSection,     &CameraSection::itemCountChanged,                       this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);

    connect(&_plannedHomePositionAltitudeFact,  &Fact::valueChanged,                        this, &MissionSettingsItem::_setDirty);

    connect(&_plannedHomePositionAltitudeFact,  &Fact::valueChanged, this, &MissionSettingsItem::_updateAltitudeInCoordinate);

    connect(&_cameraSection,    &CameraSection::dirtyChanged,   this, &MissionSettingsItem::_sectionDirtyChanged);
    connect(&_speedSection,     &SpeedSection::dirtyChanged,    this, &MissionSettingsItem::_sectionDirtyChanged);

    connect(&_cameraSection,    &CameraSection::specifyGimbalChanged,       this, &MissionSettingsItem::specifiedGimbalYawChanged);
    connect(&_cameraSection,    &CameraSection::specifiedGimbalYawChanged,  this, &MissionSettingsItem::specifiedGimbalYawChanged);
}

int MissionSettingsItem::lastSequenceNumber(void) const
{
    int lastSequenceNumber = _sequenceNumber;

    lastSequenceNumber += _cameraSection.itemCount();
    lastSequenceNumber += _speedSection.itemCount();

    return lastSequenceNumber;
}

void MissionSettingsItem::setDirty(bool dirty)
{
    if (_dirty != dirty) {
        _dirty = dirty;
        emit dirtyChanged(_dirty);
    }
}

void MissionSettingsItem::save(QJsonArray&  missionItems)
{
    QList<MissionItem*> items;

    appendMissionItems(items, this);

    // First item show be planned home position, we are not reponsible for save/load
    // Remaining items we just output as is
    for (int i=1; i<items.count(); i++) {
        MissionItem* item = items[i];
        QJsonObject saveObject;
        item->save(saveObject);
        missionItems.append(saveObject);
        item->deleteLater();
    }
}

void MissionSettingsItem::setSequenceNumber(int sequenceNumber)
{
    if (_sequenceNumber != sequenceNumber) {
        _sequenceNumber = sequenceNumber;
        emit sequenceNumberChanged(sequenceNumber);
        emit lastSequenceNumberChanged(lastSequenceNumber());
    }
}

bool MissionSettingsItem::load(const QJsonObject& complexObject, int sequenceNumber, QString& errorString)
{
    Q_UNUSED(complexObject);
    Q_UNUSED(sequenceNumber);
    Q_UNUSED(errorString);

    return true;
}

double MissionSettingsItem::greatestDistanceTo(const QGeoCoordinate &other) const
{
    Q_UNUSED(other);
    return 0;
}

bool MissionSettingsItem::specifiesCoordinate(void) const
{
    return true;
}

void MissionSettingsItem::appendMissionItems(QList<MissionItem*>& items, QObject* missionItemParent)
{
    int seqNum = _sequenceNumber;

    // IMPORTANT NOTE: If anything changes here you must also change MissionSettingsItem::scanForMissionSettings

    // Planned home position
    MissionItem* item = new MissionItem(seqNum++,
                                        MAV_CMD_NAV_WAYPOINT,
                                        MAV_FRAME_GLOBAL,
                                        0,                      // Hold time
                                        0,                      // Acceptance radius
                                        0,                      // Not sure?
                                        0,                      // Yaw
                                        coordinate().latitude(),
                                        coordinate().longitude(),
                                        _plannedHomePositionAltitudeFact.rawValue().toDouble(),
                                        true,                   // autoContinue
                                        false,                  // isCurrentItem
                                        missionItemParent);
    items.append(item);

    _cameraSection.appendSectionItems(items, missionItemParent, seqNum);
    _speedSection.appendSectionItems(items, missionItemParent, seqNum);
}

bool MissionSettingsItem::addMissionEndAction(QList<MissionItem*>& items, int seqNum, QObject* missionItemParent)
{
    MissionItem* item = NULL;

    // IMPORTANT NOTE: If anything changes here you must also change MissionSettingsItem::scanForMissionSettings

    // Find last waypoint coordinate information so we have a lat/lon/alt to use
    QGeoCoordinate  lastWaypointCoord;
    MAV_FRAME       lastWaypointFrame;

    bool found = false;
    for (int i=items.count()-1; i>0; i--) {
        MissionItem* missionItem = items[i];

        const MissionCommandUIInfo* uiInfo = qgcApp()->toolbox()->missionCommandTree()->getUIInfo(_vehicle, (MAV_CMD)missionItem->command());
        if (uiInfo->specifiesCoordinate() && !uiInfo->isStandaloneCoordinate()) {
            lastWaypointCoord = missionItem->coordinate();
            lastWaypointFrame = missionItem->frame();
            found = true;
            break;
        }
    }
    if (!found) {
        return false;
    }

    if (_missionEndRTL) {
        qCDebug(MissionSettingsComplexItemLog) << "Appending end action RTL seqNum" << seqNum;
        item = new MissionItem(seqNum,
                               MAV_CMD_NAV_RETURN_TO_LAUNCH,
                               MAV_FRAME_MISSION,
                               0, 0, 0, 0, 0, 0, 0,        // param 1-7 not used
                               true,                       // autoContinue
                               false,                      // isCurrentItem
                               missionItemParent);
        items.append(item);
        return true;
    } else {
        return false;
    }
}

bool MissionSettingsItem::scanForMissionSettings(QmlObjectListModel* visualItems, int scanIndex)
{
    bool foundSpeedSection = false;
    bool foundCameraSection = false;

    qCDebug(MissionSettingsComplexItemLog) << "MissionSettingsItem::scanForMissionSettings count:scanIndex" << visualItems->count() << scanIndex;

    MissionSettingsItem* settingsItem = visualItems->value<MissionSettingsItem*>(scanIndex);
    if (!settingsItem) {
        qWarning() << "Item specified by scanIndex not MissionSettingsItem";
        return false;
    }

    // Scan through the initial mission items for possible mission settings

    scanIndex++;
    foundCameraSection = settingsItem->_cameraSection.scanForSection(visualItems, scanIndex);
    foundSpeedSection = settingsItem->_speedSection.scanForSection(visualItems, scanIndex);

    // Look at the end of the mission for end actions

    int lastIndex = visualItems->count() - 1;
    SimpleMissionItem* item = visualItems->value<SimpleMissionItem*>(lastIndex);
    if (item) {
        MissionItem& missionItem = item->missionItem();

        if (item->command() == MAV_CMD_NAV_RETURN_TO_LAUNCH &&
                missionItem.param1() == 0 && missionItem.param2() == 0 && missionItem.param3() == 0 && missionItem.param4() == 0 && missionItem.param5() == 0 && missionItem.param6() == 0 && missionItem.param7() == 0) {
            qCDebug(MissionSettingsComplexItemLog) << "Scan: Found end action RTL";
            settingsItem->_missionEndRTL = true;
            visualItems->removeAt(lastIndex)->deleteLater();
        }
    }

    return foundSpeedSection || foundCameraSection;
}

double MissionSettingsItem::complexDistance(void) const
{
    return 0;
}

void MissionSettingsItem::_setDirty(void)
{
    setDirty(true);
}

void MissionSettingsItem::setCoordinate(const QGeoCoordinate& coordinate)
{
    if (_plannedHomePositionCoordinate != coordinate) {
        _plannedHomePositionCoordinate = coordinate;
        emit coordinateChanged(coordinate);
        emit exitCoordinateChanged(coordinate);
        _plannedHomePositionAltitudeFact.setRawValue(coordinate.altitude());
    }
}

void MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber(void)
{
    emit lastSequenceNumberChanged(lastSequenceNumber());
    setDirty(true);
}

void MissionSettingsItem::_sectionDirtyChanged(bool dirty)
{
    if (dirty) {
        setDirty(true);
    }
}

double MissionSettingsItem::specifiedGimbalYaw(void)
{
    return _cameraSection.specifyGimbal() ? _cameraSection.gimbalYaw()->rawValue().toDouble() : std::numeric_limits<double>::quiet_NaN();
}

void MissionSettingsItem::_updateAltitudeInCoordinate(QVariant value)
{
    double newAltitude = value.toDouble();

    if (!qFuzzyCompare(_plannedHomePositionCoordinate.altitude(), newAltitude)) {

        _plannedHomePositionCoordinate.setAltitude(newAltitude);
        emit coordinateChanged(_plannedHomePositionCoordinate);
        emit exitCoordinateChanged(_plannedHomePositionCoordinate);
    }
}

double MissionSettingsItem::specifiedFlightSpeed(void)
{
    if (_speedSection.specifyFlightSpeed()) {
        return _speedSection.flightSpeed()->rawValue().toDouble();
    } else {
        return std::numeric_limits<double>::quiet_NaN();
    }
}
<commit_msg>Remove unused code<commit_after>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "MissionSettingsItem.h"
#include "JsonHelper.h"
#include "MissionController.h"
#include "QGCGeo.h"
#include "QGroundControlQmlGlobal.h"
#include "SimpleMissionItem.h"
#include "SettingsManager.h"
#include "AppSettings.h"
#include "MissionCommandUIInfo.h"

#include <QPolygonF>

QGC_LOGGING_CATEGORY(MissionSettingsComplexItemLog, "MissionSettingsComplexItemLog")

const char* MissionSettingsItem::jsonComplexItemTypeValue = "MissionSettings";

const char* MissionSettingsItem::_plannedHomePositionAltitudeName = "PlannedHomePositionAltitude";

QMap<QString, FactMetaData*> MissionSettingsItem::_metaDataMap;

MissionSettingsItem::MissionSettingsItem(Vehicle* vehicle, QObject* parent)
    : ComplexMissionItem                (vehicle, parent)
    , _plannedHomePositionAltitudeFact  (0, _plannedHomePositionAltitudeName,   FactMetaData::valueTypeDouble)
    , _missionEndRTL                    (false)
    , _cameraSection                    (vehicle)
    , _speedSection                     (vehicle)
    , _sequenceNumber                   (0)
    , _dirty                            (false)
{
    _editorQml = "qrc:/qml/MissionSettingsEditor.qml";

    if (_metaDataMap.isEmpty()) {
        _metaDataMap = FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/MissionSettings.FactMetaData.json"), NULL /* metaDataParent */);
    }

    _plannedHomePositionAltitudeFact.setMetaData    (_metaDataMap[_plannedHomePositionAltitudeName]);

    _plannedHomePositionAltitudeFact.setRawValue    (_plannedHomePositionAltitudeFact.rawDefaultValue());

    setHomePositionSpecialCase(true);

    connect(this,               &MissionSettingsItem::specifyMissionFlightSpeedChanged, this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
    connect(this,               &MissionSettingsItem::missionEndRTLChanged,             this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
    connect(&_cameraSection,    &CameraSection::itemCountChanged,                       this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
    connect(&_speedSection,     &CameraSection::itemCountChanged,                       this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);

    connect(&_plannedHomePositionAltitudeFact,  &Fact::valueChanged,                        this, &MissionSettingsItem::_setDirty);

    connect(&_plannedHomePositionAltitudeFact,  &Fact::valueChanged, this, &MissionSettingsItem::_updateAltitudeInCoordinate);

    connect(&_cameraSection,    &CameraSection::dirtyChanged,   this, &MissionSettingsItem::_sectionDirtyChanged);
    connect(&_speedSection,     &SpeedSection::dirtyChanged,    this, &MissionSettingsItem::_sectionDirtyChanged);

    connect(&_cameraSection,    &CameraSection::specifyGimbalChanged,       this, &MissionSettingsItem::specifiedGimbalYawChanged);
    connect(&_cameraSection,    &CameraSection::specifiedGimbalYawChanged,  this, &MissionSettingsItem::specifiedGimbalYawChanged);
}

int MissionSettingsItem::lastSequenceNumber(void) const
{
    int lastSequenceNumber = _sequenceNumber;

    lastSequenceNumber += _cameraSection.itemCount();
    lastSequenceNumber += _speedSection.itemCount();

    return lastSequenceNumber;
}

void MissionSettingsItem::setDirty(bool dirty)
{
    if (_dirty != dirty) {
        _dirty = dirty;
        emit dirtyChanged(_dirty);
    }
}

void MissionSettingsItem::save(QJsonArray&  missionItems)
{
    QList<MissionItem*> items;

    appendMissionItems(items, this);

    // First item show be planned home position, we are not reponsible for save/load
    // Remaining items we just output as is
    for (int i=1; i<items.count(); i++) {
        MissionItem* item = items[i];
        QJsonObject saveObject;
        item->save(saveObject);
        missionItems.append(saveObject);
        item->deleteLater();
    }
}

void MissionSettingsItem::setSequenceNumber(int sequenceNumber)
{
    if (_sequenceNumber != sequenceNumber) {
        _sequenceNumber = sequenceNumber;
        emit sequenceNumberChanged(sequenceNumber);
        emit lastSequenceNumberChanged(lastSequenceNumber());
    }
}

bool MissionSettingsItem::load(const QJsonObject& complexObject, int sequenceNumber, QString& errorString)
{
    Q_UNUSED(complexObject);
    Q_UNUSED(sequenceNumber);
    Q_UNUSED(errorString);

    return true;
}

double MissionSettingsItem::greatestDistanceTo(const QGeoCoordinate &other) const
{
    Q_UNUSED(other);
    return 0;
}

bool MissionSettingsItem::specifiesCoordinate(void) const
{
    return true;
}

void MissionSettingsItem::appendMissionItems(QList<MissionItem*>& items, QObject* missionItemParent)
{
    int seqNum = _sequenceNumber;

    // IMPORTANT NOTE: If anything changes here you must also change MissionSettingsItem::scanForMissionSettings

    // Planned home position
    MissionItem* item = new MissionItem(seqNum++,
                                        MAV_CMD_NAV_WAYPOINT,
                                        MAV_FRAME_GLOBAL,
                                        0,                      // Hold time
                                        0,                      // Acceptance radius
                                        0,                      // Not sure?
                                        0,                      // Yaw
                                        coordinate().latitude(),
                                        coordinate().longitude(),
                                        _plannedHomePositionAltitudeFact.rawValue().toDouble(),
                                        true,                   // autoContinue
                                        false,                  // isCurrentItem
                                        missionItemParent);
    items.append(item);

    _cameraSection.appendSectionItems(items, missionItemParent, seqNum);
    _speedSection.appendSectionItems(items, missionItemParent, seqNum);
}

bool MissionSettingsItem::addMissionEndAction(QList<MissionItem*>& items, int seqNum, QObject* missionItemParent)
{
    MissionItem* item = NULL;

    // IMPORTANT NOTE: If anything changes here you must also change MissionSettingsItem::scanForMissionSettings

    if (_missionEndRTL) {
        qCDebug(MissionSettingsComplexItemLog) << "Appending end action RTL seqNum" << seqNum;
        item = new MissionItem(seqNum,
                               MAV_CMD_NAV_RETURN_TO_LAUNCH,
                               MAV_FRAME_MISSION,
                               0, 0, 0, 0, 0, 0, 0,        // param 1-7 not used
                               true,                       // autoContinue
                               false,                      // isCurrentItem
                               missionItemParent);
        items.append(item);
        return true;
    } else {
        return false;
    }
}

bool MissionSettingsItem::scanForMissionSettings(QmlObjectListModel* visualItems, int scanIndex)
{
    bool foundSpeedSection = false;
    bool foundCameraSection = false;

    qCDebug(MissionSettingsComplexItemLog) << "MissionSettingsItem::scanForMissionSettings count:scanIndex" << visualItems->count() << scanIndex;

    MissionSettingsItem* settingsItem = visualItems->value<MissionSettingsItem*>(scanIndex);
    if (!settingsItem) {
        qWarning() << "Item specified by scanIndex not MissionSettingsItem";
        return false;
    }

    // Scan through the initial mission items for possible mission settings

    scanIndex++;
    foundCameraSection = settingsItem->_cameraSection.scanForSection(visualItems, scanIndex);
    foundSpeedSection = settingsItem->_speedSection.scanForSection(visualItems, scanIndex);

    // Look at the end of the mission for end actions

    int lastIndex = visualItems->count() - 1;
    SimpleMissionItem* item = visualItems->value<SimpleMissionItem*>(lastIndex);
    if (item) {
        MissionItem& missionItem = item->missionItem();

        if (item->command() == MAV_CMD_NAV_RETURN_TO_LAUNCH &&
                missionItem.param1() == 0 && missionItem.param2() == 0 && missionItem.param3() == 0 && missionItem.param4() == 0 && missionItem.param5() == 0 && missionItem.param6() == 0 && missionItem.param7() == 0) {
            qCDebug(MissionSettingsComplexItemLog) << "Scan: Found end action RTL";
            settingsItem->_missionEndRTL = true;
            visualItems->removeAt(lastIndex)->deleteLater();
        }
    }

    return foundSpeedSection || foundCameraSection;
}

double MissionSettingsItem::complexDistance(void) const
{
    return 0;
}

void MissionSettingsItem::_setDirty(void)
{
    setDirty(true);
}

void MissionSettingsItem::setCoordinate(const QGeoCoordinate& coordinate)
{
    if (_plannedHomePositionCoordinate != coordinate) {
        _plannedHomePositionCoordinate = coordinate;
        emit coordinateChanged(coordinate);
        emit exitCoordinateChanged(coordinate);
        _plannedHomePositionAltitudeFact.setRawValue(coordinate.altitude());
    }
}

void MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber(void)
{
    emit lastSequenceNumberChanged(lastSequenceNumber());
    setDirty(true);
}

void MissionSettingsItem::_sectionDirtyChanged(bool dirty)
{
    if (dirty) {
        setDirty(true);
    }
}

double MissionSettingsItem::specifiedGimbalYaw(void)
{
    return _cameraSection.specifyGimbal() ? _cameraSection.gimbalYaw()->rawValue().toDouble() : std::numeric_limits<double>::quiet_NaN();
}

void MissionSettingsItem::_updateAltitudeInCoordinate(QVariant value)
{
    double newAltitude = value.toDouble();

    if (!qFuzzyCompare(_plannedHomePositionCoordinate.altitude(), newAltitude)) {

        _plannedHomePositionCoordinate.setAltitude(newAltitude);
        emit coordinateChanged(_plannedHomePositionCoordinate);
        emit exitCoordinateChanged(_plannedHomePositionCoordinate);
    }
}

double MissionSettingsItem::specifiedFlightSpeed(void)
{
    if (_speedSection.specifyFlightSpeed()) {
        return _speedSection.flightSpeed()->rawValue().toDouble();
    } else {
        return std::numeric_limits<double>::quiet_NaN();
    }
}
<|endoftext|>