<commit_before>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware Inc.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

=========================================================================*/

// ctkDICOMWidget includes
#include "ctkDICOMTableView.h"
#include "ui_ctkDICOMTableView.h"

// Qt includes
#include <QSortFilterProxyModel>
#include <QSqlQueryModel>

//------------------------------------------------------------------------------
class ctkDICOMTableViewPrivate : public Ui_ctkDICOMTableView
{
  Q_DECLARE_PUBLIC (ctkDICOMTableView)

protected:
  ctkDICOMTableView* const q_ptr;

public:
  ctkDICOMTableViewPrivate(ctkDICOMTableView& obj);
  ctkDICOMTableViewPrivate(ctkDICOMTableView& obj, ctkDICOMDatabase* db);
  ~ctkDICOMTableViewPrivate();
  // Initialize UI
  void init();
  // Setup tableview with tablemodel if database is available
  void setUpTableView();
  //Temporay solution to hide UID columns
  void hideUIDColumns();

  void showFilterActiveWarning(bool);

  QString queryTableName() const;

  ctkDICOMDatabase* dicomDatabase;
  QSqlQueryModel dicomSQLModel;
  QSortFilterProxyModel* dicomSQLFilterModel;
  QString queryForeignKey;

  QStringList currentSelection;
  //Key = QString for columns, Values = QStringList
  QHash<QString, QStringList> sqlWhereConditions;

};

//------------------------------------------------------------------------------
ctkDICOMTableViewPrivate::ctkDICOMTableViewPrivate(ctkDICOMTableView &obj)
  : q_ptr(&obj)
{
  this->dicomSQLFilterModel = new QSortFilterProxyModel(&obj);
  this->dicomDatabase = new ctkDICOMDatabase(&obj);
}

//------------------------------------------------------------------------------
ctkDICOMTableViewPrivate::ctkDICOMTableViewPrivate(ctkDICOMTableView &obj, ctkDICOMDatabase* db)
  : q_ptr(&obj)
  , dicomDatabase(db)
{
  this->dicomSQLFilterModel = new QSortFilterProxyModel(&obj);
}

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

void ctkDICOMTableViewPrivate::init()
{
  Q_Q(ctkDICOMTableView);
  this->setupUi(q);

  this->leSearchBox->setAlwaysShowClearIcon(true);
  this->leSearchBox->setShowSearchIcon(true);

  if (this->dicomDatabase != 0)
    {
      this->setUpTableView();
    }
}

//------------------------------------------------------------------------------
void ctkDICOMTableViewPrivate::setUpTableView()
{
  Q_Q(ctkDICOMTableView);
  if (this->dicomDatabase != 0)
    {
      q->setQuery();
      this->dicomSQLFilterModel->setSourceModel(&this->dicomSQLModel);
      this->dicomSQLFilterModel->setFilterKeyColumn(-1);
      this->dicomSQLFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
      this->tblDicomDatabaseView->setModel(this->dicomSQLFilterModel);
      this->tblDicomDatabaseView->setColumnHidden(0, true);
      this->tblDicomDatabaseView->setSortingEnabled(true);
      this->tblDicomDatabaseView->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
      this->hideUIDColumns();

      QObject::connect(this->tblDicomDatabaseView->selectionModel(),
                       SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),
                       q, SLOT(onSelectionChanged()));

      QObject::connect(this->tblDicomDatabaseView->selectionModel(),
                       SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),
                       q, SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)));

      QObject::connect(this->tblDicomDatabaseView, SIGNAL(doubleClicked(const QModelIndex&)),
                       q, SIGNAL(doubleClicked(const QModelIndex&)));

      QObject::connect(this->leSearchBox, SIGNAL(textChanged(QString)),
                       this->dicomSQLFilterModel, SLOT(setFilterWildcard(QString)));

      QObject::connect(this->leSearchBox, SIGNAL(textChanged(QString)), q, SLOT(onFilterChanged()));

      QObject::connect(this->dicomDatabase, SIGNAL(databaseChanged()), q, SLOT(onDatabaseChanged()));
      QObject::connect(this->dicomDatabase, SIGNAL(instanceAdded(const QString&)),
                       q, SLOT(onInstanceAdded()));
    }
}

//------------------------------------------------------------------------------
//Temporay solution to hide UID columns
void ctkDICOMTableViewPrivate::hideUIDColumns()
{
  const int numberOfColumns = this->tblDicomDatabaseView->model()->columnCount();
  for (int i = 0; i < numberOfColumns; ++i)
    {
    QString columnName = this->tblDicomDatabaseView->model()->headerData(i, Qt::Horizontal).toString();
    if (columnName.contains("UID"))
      {
        this->tblDicomDatabaseView->hideColumn(i);
      }
    }
}

//----------------------------------------------------------------------------
QString ctkDICOMTableViewPrivate::queryTableName() const
{
  return this->lblTableName->text();
}

//----------------------------------------------------------------------------
void ctkDICOMTableViewPrivate::showFilterActiveWarning(bool showWarning)
{
  QPalette palette;
  if (showWarning)
    {
      palette.setColor(QPalette::Base,Qt::yellow);
    }
  else
    {
      palette.setColor(QPalette::Base,Qt::white);
    }
  this->leSearchBox->setPalette(palette);
}

//----------------------------------------------------------------------------
// ctkDICOMTableView methods

//----------------------------------------------------------------------------
ctkDICOMTableView::ctkDICOMTableView(QWidget *parent)
  : Superclass(parent)
  , d_ptr(new ctkDICOMTableViewPrivate(*this))
{
  Q_D(ctkDICOMTableView);
  d->init();
}

//----------------------------------------------------------------------------
ctkDICOMTableView::ctkDICOMTableView(QString queryTableName, QWidget *parent)
  : Superclass(parent)
  , d_ptr(new ctkDICOMTableViewPrivate(*this))
{
  Q_D(ctkDICOMTableView);
  d->init();
  this->setQueryTableName(queryTableName);
  d->lblTableName->setText(queryTableName);
}

//------------------------------------------------------------------------------
ctkDICOMTableView::ctkDICOMTableView (ctkDICOMDatabase* dicomDataBase, QString queryTableName, QWidget* parent)
  : Superclass(parent)
  , d_ptr(new ctkDICOMTableViewPrivate(*this))
{
  this->setDicomDataBase(dicomDataBase);
  Q_D(ctkDICOMTableView);
  this->setQueryTableName(queryTableName);
  d->init();
}

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

//------------------------------------------------------------------------------
void ctkDICOMTableView::setDicomDataBase(ctkDICOMDatabase *dicomDatabase)
{
  Q_D(ctkDICOMTableView);
  d->dicomDatabase = dicomDatabase;
  //Create connections for new database
  QObject::connect(d->dicomDatabase, SIGNAL(instanceAdded(const QString&)),
                   this, SLOT(onInstanceAdded()));
  QObject::connect(d->dicomDatabase, SIGNAL(databaseChanged()), this, SLOT(onDatabaseChanged()));
  this->setQuery();
  d->hideUIDColumns();
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::setQueryTableName(const QString &tableName)
{
  Q_D(ctkDICOMTableView);
  d->lblTableName->setText(tableName);
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::setQueryForeignKey(const QString &foreignKey)
{
  Q_D(ctkDICOMTableView);
  d->queryForeignKey = foreignKey;
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::onSelectionChanged()
{
  emit selectionChanged(currentSelection());
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::onDatabaseChanged()
{
  Q_D(ctkDICOMTableView);
  setQuery();
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::onUpdateQuery(const QStringList& uids)
{
  Q_D(ctkDICOMTableView);

  setQuery(uids);

  d->showFilterActiveWarning( d->dicomSQLFilterModel->rowCount() == 0 &&
                              d->leSearchBox->text().length() != 0 );

  const QStringList& newUIDS = this->uidsForAllRows();
  emit queryChanged(newUIDS);
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::onFilterChanged()
{
  Q_D(ctkDICOMTableView);

  const QStringList uids = this->uidsForAllRows();

  d->showFilterActiveWarning( d->dicomSQLFilterModel->rowCount() == 0 &&
                              d->dicomSQLModel.rowCount() != 0);

  d->tblDicomDatabaseView->clearSelection();
  emit queryChanged(uids);
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::onInstanceAdded()
{
  Q_D(ctkDICOMTableView);
  d->sqlWhereConditions.clear();
  d->tblDicomDatabaseView->clearSelection();
  d->leSearchBox->clear();
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::setQuery(const QStringList &uids)
{
  Q_D(ctkDICOMTableView);
  QString query = ("select distinct %1.* from Patients, Series, Studies where "
                   "Patients.UID = Studies.PatientsUID and Studies.StudyInstanceUID = Series.StudyInstanceUID");

  if (!uids.empty() && d->queryForeignKey.length() != 0)
    {
      query += " and %1."+d->queryForeignKey+" in ( '";
      query.append(uids.join("','")).append("')");
    }
  if (!d->sqlWhereConditions.empty())
    {
      QHash<QString, QStringList>::const_iterator i = d->sqlWhereConditions.begin();
      while (i != d->sqlWhereConditions.end())
        {
          if (!i.value().empty())
            {
              query += " and "+i.key()+" in ( '";
              query.append(i.value().join("','")).append("')");
            }
          ++i;
        }
    }
  if (d->dicomDatabase != 0)
    d->dicomSQLModel.setQuery(query.arg(d->queryTableName()), d->dicomDatabase->database());
}

void ctkDICOMTableView::addSqlWhereCondition(const std::pair<QString, QStringList> &condition)
{
  Q_D(ctkDICOMTableView);
  d->sqlWhereConditions.insert(condition.first, condition.second);
}

//------------------------------------------------------------------------------
QStringList ctkDICOMTableView::uidsForAllRows() const
{
  Q_D(const ctkDICOMTableView);
  QAbstractItemModel* tableModel = d->tblDicomDatabaseView->model();
  int numberOfRows = tableModel->rowCount();
  QStringList uids;
  if (numberOfRows == 0)
    {
      //Return invalid UID if there are no rows
      uids << QString("#");
    }
  else
    {
      for(int i = 0; i < numberOfRows; ++i)
        {
          uids << QString("%1").arg(tableModel->index(i,0).data().toString());
        }
    }
  return uids;
}

//------------------------------------------------------------------------------
QStringList ctkDICOMTableView::currentSelection() const
{
  Q_D(const ctkDICOMTableView);

  QModelIndexList currentSelection = d->tblDicomDatabaseView->selectionModel()->selectedRows(0);
  QStringList uids;

  foreach(QModelIndex i, currentSelection)
    {
      uids<< i.data().toString();
    }

  return  uids;
}

//------------------------------------------------------------------------------
bool ctkDICOMTableView::filterActive()
{
  Q_D(ctkDICOMTableView);
  return (d->leSearchBox->text().length() != 0);
}
<commit_msg>Not using const references when declaring a connection<commit_after>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware Inc.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

=========================================================================*/

// ctkDICOMWidget includes
#include "ctkDICOMTableView.h"
#include "ui_ctkDICOMTableView.h"

// Qt includes
#include <QSortFilterProxyModel>
#include <QSqlQueryModel>

//------------------------------------------------------------------------------
class ctkDICOMTableViewPrivate : public Ui_ctkDICOMTableView
{
  Q_DECLARE_PUBLIC (ctkDICOMTableView)

protected:
  ctkDICOMTableView* const q_ptr;

public:
  ctkDICOMTableViewPrivate(ctkDICOMTableView& obj);
  ctkDICOMTableViewPrivate(ctkDICOMTableView& obj, ctkDICOMDatabase* db);
  ~ctkDICOMTableViewPrivate();
  // Initialize UI
  void init();
  // Setup tableview with tablemodel if database is available
  void setUpTableView();
  //Temporay solution to hide UID columns
  void hideUIDColumns();

  void showFilterActiveWarning(bool);

  QString queryTableName() const;

  ctkDICOMDatabase* dicomDatabase;
  QSqlQueryModel dicomSQLModel;
  QSortFilterProxyModel* dicomSQLFilterModel;
  QString queryForeignKey;

  QStringList currentSelection;
  //Key = QString for columns, Values = QStringList
  QHash<QString, QStringList> sqlWhereConditions;

};

//------------------------------------------------------------------------------
ctkDICOMTableViewPrivate::ctkDICOMTableViewPrivate(ctkDICOMTableView &obj)
  : q_ptr(&obj)
{
  this->dicomSQLFilterModel = new QSortFilterProxyModel(&obj);
  this->dicomDatabase = new ctkDICOMDatabase(&obj);
}

//------------------------------------------------------------------------------
ctkDICOMTableViewPrivate::ctkDICOMTableViewPrivate(ctkDICOMTableView &obj, ctkDICOMDatabase* db)
  : q_ptr(&obj)
  , dicomDatabase(db)
{
  this->dicomSQLFilterModel = new QSortFilterProxyModel(&obj);
}

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

void ctkDICOMTableViewPrivate::init()
{
  Q_Q(ctkDICOMTableView);
  this->setupUi(q);

  this->leSearchBox->setAlwaysShowClearIcon(true);
  this->leSearchBox->setShowSearchIcon(true);

  if (this->dicomDatabase != 0)
    {
      this->setUpTableView();
    }
}

//------------------------------------------------------------------------------
void ctkDICOMTableViewPrivate::setUpTableView()
{
  Q_Q(ctkDICOMTableView);
  if (this->dicomDatabase != 0)
    {
      q->setQuery();
      this->dicomSQLFilterModel->setSourceModel(&this->dicomSQLModel);
      this->dicomSQLFilterModel->setFilterKeyColumn(-1);
      this->dicomSQLFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
      this->tblDicomDatabaseView->setModel(this->dicomSQLFilterModel);
      this->tblDicomDatabaseView->setColumnHidden(0, true);
      this->tblDicomDatabaseView->setSortingEnabled(true);
      this->tblDicomDatabaseView->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
      this->hideUIDColumns();

      QObject::connect(this->tblDicomDatabaseView->selectionModel(),
                       SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),
                       q, SLOT(onSelectionChanged()));

      QObject::connect(this->tblDicomDatabaseView->selectionModel(),
                       SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),
                       q, SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)));

      QObject::connect(this->tblDicomDatabaseView, SIGNAL(doubleClicked(const QModelIndex&)),
                       q, SIGNAL(doubleClicked(const QModelIndex&)));

      QObject::connect(this->leSearchBox, SIGNAL(textChanged(QString)),
                       this->dicomSQLFilterModel, SLOT(setFilterWildcard(QString)));

      QObject::connect(this->leSearchBox, SIGNAL(textChanged(QString)), q, SLOT(onFilterChanged()));

      QObject::connect(this->dicomDatabase, SIGNAL(databaseChanged()), q, SLOT(onDatabaseChanged()));
      QObject::connect(this->dicomDatabase, SIGNAL(instanceAdded(QString)),
                       q, SLOT(onInstanceAdded()));
    }
}

//------------------------------------------------------------------------------
//Temporay solution to hide UID columns
void ctkDICOMTableViewPrivate::hideUIDColumns()
{
  const int numberOfColumns = this->tblDicomDatabaseView->model()->columnCount();
  for (int i = 0; i < numberOfColumns; ++i)
    {
    QString columnName = this->tblDicomDatabaseView->model()->headerData(i, Qt::Horizontal).toString();
    if (columnName.contains("UID"))
      {
        this->tblDicomDatabaseView->hideColumn(i);
      }
    }
}

//----------------------------------------------------------------------------
QString ctkDICOMTableViewPrivate::queryTableName() const
{
  return this->lblTableName->text();
}

//----------------------------------------------------------------------------
void ctkDICOMTableViewPrivate::showFilterActiveWarning(bool showWarning)
{
  QPalette palette;
  if (showWarning)
    {
      palette.setColor(QPalette::Base,Qt::yellow);
    }
  else
    {
      palette.setColor(QPalette::Base,Qt::white);
    }
  this->leSearchBox->setPalette(palette);
}

//----------------------------------------------------------------------------
// ctkDICOMTableView methods

//----------------------------------------------------------------------------
ctkDICOMTableView::ctkDICOMTableView(QWidget *parent)
  : Superclass(parent)
  , d_ptr(new ctkDICOMTableViewPrivate(*this))
{
  Q_D(ctkDICOMTableView);
  d->init();
}

//----------------------------------------------------------------------------
ctkDICOMTableView::ctkDICOMTableView(QString queryTableName, QWidget *parent)
  : Superclass(parent)
  , d_ptr(new ctkDICOMTableViewPrivate(*this))
{
  Q_D(ctkDICOMTableView);
  d->init();
  this->setQueryTableName(queryTableName);
  d->lblTableName->setText(queryTableName);
}

//------------------------------------------------------------------------------
ctkDICOMTableView::ctkDICOMTableView (ctkDICOMDatabase* dicomDataBase, QString queryTableName, QWidget* parent)
  : Superclass(parent)
  , d_ptr(new ctkDICOMTableViewPrivate(*this))
{
  this->setDicomDataBase(dicomDataBase);
  Q_D(ctkDICOMTableView);
  this->setQueryTableName(queryTableName);
  d->init();
}

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

//------------------------------------------------------------------------------
void ctkDICOMTableView::setDicomDataBase(ctkDICOMDatabase *dicomDatabase)
{
  Q_D(ctkDICOMTableView);
  d->dicomDatabase = dicomDatabase;
  //Create connections for new database
  QObject::connect(d->dicomDatabase, SIGNAL(instanceAdded(const QString&)),
                   this, SLOT(onInstanceAdded()));
  QObject::connect(d->dicomDatabase, SIGNAL(databaseChanged()), this, SLOT(onDatabaseChanged()));
  this->setQuery();
  d->hideUIDColumns();
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::setQueryTableName(const QString &tableName)
{
  Q_D(ctkDICOMTableView);
  d->lblTableName->setText(tableName);
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::setQueryForeignKey(const QString &foreignKey)
{
  Q_D(ctkDICOMTableView);
  d->queryForeignKey = foreignKey;
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::onSelectionChanged()
{
  emit selectionChanged(currentSelection());
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::onDatabaseChanged()
{
  Q_D(ctkDICOMTableView);
  setQuery();
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::onUpdateQuery(const QStringList& uids)
{
  Q_D(ctkDICOMTableView);

  setQuery(uids);

  d->showFilterActiveWarning( d->dicomSQLFilterModel->rowCount() == 0 &&
                              d->leSearchBox->text().length() != 0 );

  const QStringList& newUIDS = this->uidsForAllRows();
  emit queryChanged(newUIDS);
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::onFilterChanged()
{
  Q_D(ctkDICOMTableView);

  const QStringList uids = this->uidsForAllRows();

  d->showFilterActiveWarning( d->dicomSQLFilterModel->rowCount() == 0 &&
                              d->dicomSQLModel.rowCount() != 0);

  d->tblDicomDatabaseView->clearSelection();
  emit queryChanged(uids);
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::onInstanceAdded()
{
  Q_D(ctkDICOMTableView);
  d->sqlWhereConditions.clear();
  d->tblDicomDatabaseView->clearSelection();
  d->leSearchBox->clear();
}

//------------------------------------------------------------------------------
void ctkDICOMTableView::setQuery(const QStringList &uids)
{
  Q_D(ctkDICOMTableView);
  QString query = ("select distinct %1.* from Patients, Series, Studies where "
                   "Patients.UID = Studies.PatientsUID and Studies.StudyInstanceUID = Series.StudyInstanceUID");

  if (!uids.empty() && d->queryForeignKey.length() != 0)
    {
      query += " and %1."+d->queryForeignKey+" in ( '";
      query.append(uids.join("','")).append("')");
    }
  if (!d->sqlWhereConditions.empty())
    {
      QHash<QString, QStringList>::const_iterator i = d->sqlWhereConditions.begin();
      while (i != d->sqlWhereConditions.end())
        {
          if (!i.value().empty())
            {
              query += " and "+i.key()+" in ( '";
              query.append(i.value().join("','")).append("')");
            }
          ++i;
        }
    }
  if (d->dicomDatabase != 0)
    d->dicomSQLModel.setQuery(query.arg(d->queryTableName()), d->dicomDatabase->database());
}

void ctkDICOMTableView::addSqlWhereCondition(const std::pair<QString, QStringList> &condition)
{
  Q_D(ctkDICOMTableView);
  d->sqlWhereConditions.insert(condition.first, condition.second);
}

//------------------------------------------------------------------------------
QStringList ctkDICOMTableView::uidsForAllRows() const
{
  Q_D(const ctkDICOMTableView);
  QAbstractItemModel* tableModel = d->tblDicomDatabaseView->model();
  int numberOfRows = tableModel->rowCount();
  QStringList uids;
  if (numberOfRows == 0)
    {
      //Return invalid UID if there are no rows
      uids << QString("#");
    }
  else
    {
      for(int i = 0; i < numberOfRows; ++i)
        {
          uids << QString("%1").arg(tableModel->index(i,0).data().toString());
        }
    }
  return uids;
}

//------------------------------------------------------------------------------
QStringList ctkDICOMTableView::currentSelection() const
{
  Q_D(const ctkDICOMTableView);

  QModelIndexList currentSelection = d->tblDicomDatabaseView->selectionModel()->selectedRows(0);
  QStringList uids;

  foreach(QModelIndex i, currentSelection)
    {
      uids<< i.data().toString();
    }

  return  uids;
}

//------------------------------------------------------------------------------
bool ctkDICOMTableView::filterActive()
{
  Q_D(ctkDICOMTableView);
  return (d->leSearchBox->text().length() != 0);
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include "modules/control/control.h"

#include <iomanip>
#include <string>

#include "ros/include/std_msgs/String.h"

#include "modules/localization/proto/localization.pb.h"

#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/time/time.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/control/common/control_gflags.h"

namespace apollo {
namespace control {

using apollo::canbus::Chassis;
using apollo::common::ErrorCode;
using apollo::common::Status;
using apollo::common::adapter::AdapterManager;
using apollo::common::monitor::MonitorMessageItem;
using apollo::common::time::Clock;
using apollo::localization::LocalizationEstimate;
using apollo::planning::ADCTrajectory;

std::string Control::Name() const {
  return FLAGS_node_name;
}

Status Control::Init() {
  AINFO << "Control init, starting ...";
  CHECK(common::util::GetProtoFromFile(FLAGS_control_conf_file, &control_conf_))
      << "Unable to load control conf file: " + FLAGS_control_conf_file;

  AINFO << "Conf file: " << FLAGS_control_conf_file << " is loaded.";

  AdapterManager::Init(FLAGS_adapter_config_filename);

  apollo::common::monitor::MonitorBuffer buffer(&monitor_);

  // set controller
  if (!controller_agent_.Init(&control_conf_).ok()) {
    std::string error_msg = "Control init controller failed! Stopping...";
    buffer.ERROR(error_msg);
    return Status(ErrorCode::CONTROL_INIT_ERROR, error_msg);
  }

  // lock it in case for after sub, init_vehicle not ready, but msg trigger
  // come
  CHECK(AdapterManager::GetLocalization())
      << "Localization is not initialized.";

  CHECK(AdapterManager::GetChassis()) << "Chassis is not initialized.";

  CHECK(AdapterManager::GetPlanning()) << "Planning is not initialized.";

  CHECK(AdapterManager::GetPad()) << "Pad is not initialized.";

  CHECK(AdapterManager::GetControlCommand())
      << "ControlCommand publisher is not initialized.";

  AdapterManager::AddPadCallback(&Control::OnPad, this);
  AdapterManager::AddMonitorCallback(&Control::OnMonitor, this);

  return Status::OK();
}

Status Control::Start() {
  // set initial vehicle state by cmd
  // need to sleep, because advertised channel is not ready immediately
  // simple test shows a short delay of 80 ms or so
  AINFO << "Control resetting vehicle state, sleeping for 1000 ms ...";
  usleep(1000 * 1000);

  // should init_vehicle first, let car enter work status, then use status msg
  // trigger control

  AINFO << "Control default driving action is "
        << DrivingAction_Name(control_conf_.action());
  pad_msg_.set_action(control_conf_.action());

  timer_ = AdapterManager::CreateTimer(
      ros::Duration(control_conf_.control_period()), &Control::OnTimer, this);

  AINFO << "Control init done!";

  apollo::common::monitor::MonitorBuffer buffer(&monitor_);
  buffer.INFO("control started");

  return Status::OK();
}

void Control::OnPad(const PadMessage &pad) {
  pad_msg_ = pad;
  ADEBUG << "Received Pad Msg:" << pad.DebugString();
  AERROR_IF(!pad_msg_.has_action()) << "pad message check failed!";

  // do something according to pad message
  if (pad_msg_.action() == DrivingAction::RESET) {
    AINFO << "Control received RESET action!";
    estop_ = false;
  }
  pad_received_ = true;
}

void Control::OnMonitor(
    const apollo::common::monitor::MonitorMessage &monitor_message) {
  for (const auto &item : monitor_message.item()) {
    if (item.log_level() == MonitorMessageItem::FATAL) {
      estop_ = true;
      return;
    }
  }
}

Status Control::ProduceControlCommand(ControlCommand *control_command) {
  Status status = CheckInput();
  // check data
  if (!status.ok()) {
    AERROR_EVERY(100) << "Control input data failed: "
                      << status.error_message();
    estop_ = true;
  } else {
    Status status_ts = CheckTimestamp();
    if (!status_ts.ok()) {
      AERROR << "Input messages timeout";
      estop_ = true;
      status = status_ts;
    }
  }

  // check estop
  estop_ = estop_ || trajectory_.estop().is_estop();

  // if planning set estop, then no control process triggered
  if (!estop_) {
    if (chassis_.driving_mode() == Chassis::COMPLETE_MANUAL) {
      controller_agent_.Reset();
      AINFO_EVERY(100) << "Reset Controllers in Manual Mode";
    }

    auto debug = control_command->mutable_debug()->mutable_input_debug();
    debug->mutable_localization_header()->CopyFrom(localization_.header());
    debug->mutable_canbus_header()->CopyFrom(chassis_.header());
    debug->mutable_trajectory_header()->CopyFrom(trajectory_.header());

    Status status_compute = controller_agent_.ComputeControlCommand(
        &localization_, &chassis_, &trajectory_, control_command);

    if (!status_compute.ok()) {
      AERROR << "Control main function failed"
             << " with localization: " << localization_.ShortDebugString()
             << " with chassis: " << chassis_.ShortDebugString()
             << " with trajectory: " << trajectory_.ShortDebugString()
             << " with cmd: " << control_command->ShortDebugString()
             << " status:" << status_compute.error_message();
      estop_ = true;
      status = status_compute;
    }
  }

  if (estop_) {
    AWARN_EVERY(100) << "Estop triggered! No control core method executed!";
    // set Estop command
    control_command->set_speed(0);
    control_command->set_throttle(0);
    control_command->set_brake(control_conf_.soft_estop_brake());
    control_command->set_gear_location(Chassis::GEAR_DRIVE);
  }
  // check signal
  if (trajectory_.has_signal()) {
    control_command->mutable_signal()->CopyFrom(trajectory_.signal());
  }
  return status;
}

void Control::OnTimer(const ros::TimerEvent &) {
  double start_timestamp = Clock::NowInSecond();

  ControlCommand control_command;

  Status status = ProduceControlCommand(&control_command);
  AERROR_IF(!status.ok()) << "Failed to produce control command:"
                          << status.error_message();

  double end_timestamp = Clock::NowInSecond();

  if (pad_received_) {
    control_command.mutable_pad_msg()->CopyFrom(pad_msg_);
    pad_received_ = false;
  }

  const double time_diff_ms = (end_timestamp - start_timestamp) * 1000;
  control_command.mutable_latency_stats()->set_total_time_ms(time_diff_ms);
  ADEBUG << "control cycle time is: " << time_diff_ms << " ms.";
  status.Save(control_command.mutable_header()->mutable_status());

  SendCmd(&control_command);
}

Status Control::CheckInput() {
  AdapterManager::Observe();
  auto localization_adapter = AdapterManager::GetLocalization();
  if (localization_adapter->Empty()) {
    AWARN_EVERY(100) << "No Localization msg yet. ";
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "No localization msg");
  }
  localization_ = localization_adapter->GetLatestObserved();
  ADEBUG << "Received localization:" << localization_.ShortDebugString();

  auto chassis_adapter = AdapterManager::GetChassis();
  if (chassis_adapter->Empty()) {
    AWARN_EVERY(100) << "No Chassis msg yet. ";
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "No chassis msg");
  }
  chassis_ = chassis_adapter->GetLatestObserved();
  ADEBUG << "Received chassis:" << chassis_.ShortDebugString();

  auto trajectory_adapter = AdapterManager::GetPlanning();
  if (trajectory_adapter->Empty()) {
    AWARN_EVERY(100) << "No planning msg yet. ";
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "No planning msg");
  }
  trajectory_ = trajectory_adapter->GetLatestObserved();
  if (!trajectory_.estop().is_estop() &&
      trajectory_.trajectory_point_size() == 0) {
    AWARN_EVERY(100) << "planning has no trajectory point. ";
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR,
                  "planning has no trajectory point.");
  }

  for (auto &trajectory_point : *trajectory_.mutable_trajectory_point()) {
    if (trajectory_point.v() < control_conf_.minimum_speed_resolution()) {
      trajectory_point.set_v(0.0);
      trajectory_point.set_a(0.0);
    }
  }

  // Add tempprary flag for test
  if (FLAGS_use_relative_position) {
    localization_.mutable_pose()->mutable_position()->set_x(0.0);
    localization_.mutable_pose()->mutable_position()->set_y(0.0);
    localization_.mutable_pose()->set_heading(0.0);
  }
  common::VehicleStateProvider::instance()->Update(localization_, chassis_);

  return Status::OK();
}

Status Control::CheckTimestamp() {
  if (!FLAGS_enable_input_timestamp_check || FLAGS_is_control_test_mode) {
    ADEBUG << "Skip input timestamp check by gflags.";
    return Status::OK();
  }
  double current_timestamp = Clock::NowInSecond();
  double localization_diff =
      current_timestamp - localization_.header().timestamp_sec();
  if (localization_diff >
      (FLAGS_max_localization_miss_num * control_conf_.localization_period())) {
    AERROR << "Localization msg lost for " << std::setprecision(6)
           << localization_diff << "s";
    apollo::common::monitor::MonitorBuffer buffer(&monitor_);
    buffer.ERROR("Localization msg lost");
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Localization msg timeout");
  }

  double chassis_diff = current_timestamp - chassis_.header().timestamp_sec();
  if (chassis_diff >
      (FLAGS_max_chassis_miss_num * control_conf_.chassis_period())) {
    AERROR << "Chassis msg lost for " << std::setprecision(6) << chassis_diff
           << "s";
    apollo::common::monitor::MonitorBuffer buffer(&monitor_);
    buffer.ERROR("Chassis msg lost");
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Chassis msg timeout");
  }

  double trajectory_diff =
      current_timestamp - trajectory_.header().timestamp_sec();
  if (trajectory_diff >
      (FLAGS_max_planning_miss_num * control_conf_.trajectory_period())) {
    AERROR << "Trajectory msg lost for " << std::setprecision(6)
           << trajectory_diff << "s";
    apollo::common::monitor::MonitorBuffer buffer(&monitor_);
    buffer.ERROR("Trajectory msg lost");
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Trajectory msg timeout");
  }
  return Status::OK();
}

void Control::SendCmd(ControlCommand *control_command) {
  // set header
  AdapterManager::FillControlCommandHeader(Name(), control_command);

  ADEBUG << control_command->ShortDebugString();
  if (FLAGS_is_control_test_mode) {
    ADEBUG << "Skip publish control command in test mode";
    return;
  }
  AdapterManager::PublishControlCommand(*control_command);
}

void Control::Stop() {}

}  // namespace control
}  // namespace apollo
<commit_msg>control: forward vehicle signal to canbus. (#1146)<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include "modules/control/control.h"

#include <iomanip>
#include <string>

#include "ros/include/std_msgs/String.h"

#include "modules/localization/proto/localization.pb.h"

#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/time/time.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/control/common/control_gflags.h"

namespace apollo {
namespace control {

using apollo::canbus::Chassis;
using apollo::common::ErrorCode;
using apollo::common::Status;
using apollo::common::adapter::AdapterManager;
using apollo::common::monitor::MonitorMessageItem;
using apollo::common::time::Clock;
using apollo::localization::LocalizationEstimate;
using apollo::planning::ADCTrajectory;

std::string Control::Name() const {
  return FLAGS_node_name;
}

Status Control::Init() {
  AINFO << "Control init, starting ...";
  CHECK(common::util::GetProtoFromFile(FLAGS_control_conf_file, &control_conf_))
      << "Unable to load control conf file: " + FLAGS_control_conf_file;

  AINFO << "Conf file: " << FLAGS_control_conf_file << " is loaded.";

  AdapterManager::Init(FLAGS_adapter_config_filename);

  apollo::common::monitor::MonitorBuffer buffer(&monitor_);

  // set controller
  if (!controller_agent_.Init(&control_conf_).ok()) {
    std::string error_msg = "Control init controller failed! Stopping...";
    buffer.ERROR(error_msg);
    return Status(ErrorCode::CONTROL_INIT_ERROR, error_msg);
  }

  // lock it in case for after sub, init_vehicle not ready, but msg trigger
  // come
  CHECK(AdapterManager::GetLocalization())
      << "Localization is not initialized.";

  CHECK(AdapterManager::GetChassis()) << "Chassis is not initialized.";

  CHECK(AdapterManager::GetPlanning()) << "Planning is not initialized.";

  CHECK(AdapterManager::GetPad()) << "Pad is not initialized.";

  CHECK(AdapterManager::GetControlCommand())
      << "ControlCommand publisher is not initialized.";

  AdapterManager::AddPadCallback(&Control::OnPad, this);
  AdapterManager::AddMonitorCallback(&Control::OnMonitor, this);

  return Status::OK();
}

Status Control::Start() {
  // set initial vehicle state by cmd
  // need to sleep, because advertised channel is not ready immediately
  // simple test shows a short delay of 80 ms or so
  AINFO << "Control resetting vehicle state, sleeping for 1000 ms ...";
  usleep(1000 * 1000);

  // should init_vehicle first, let car enter work status, then use status msg
  // trigger control

  AINFO << "Control default driving action is "
        << DrivingAction_Name(control_conf_.action());
  pad_msg_.set_action(control_conf_.action());

  timer_ = AdapterManager::CreateTimer(
      ros::Duration(control_conf_.control_period()), &Control::OnTimer, this);

  AINFO << "Control init done!";

  apollo::common::monitor::MonitorBuffer buffer(&monitor_);
  buffer.INFO("control started");

  return Status::OK();
}

void Control::OnPad(const PadMessage &pad) {
  pad_msg_ = pad;
  ADEBUG << "Received Pad Msg:" << pad.DebugString();
  AERROR_IF(!pad_msg_.has_action()) << "pad message check failed!";

  // do something according to pad message
  if (pad_msg_.action() == DrivingAction::RESET) {
    AINFO << "Control received RESET action!";
    estop_ = false;
  }
  pad_received_ = true;
}

void Control::OnMonitor(
    const apollo::common::monitor::MonitorMessage &monitor_message) {
  for (const auto &item : monitor_message.item()) {
    if (item.log_level() == MonitorMessageItem::FATAL) {
      estop_ = true;
      return;
    }
  }
}

Status Control::ProduceControlCommand(ControlCommand *control_command) {
  Status status = CheckInput();
  // check data
  if (!status.ok()) {
    AERROR_EVERY(100) << "Control input data failed: "
                      << status.error_message();
    estop_ = true;
  } else {
    Status status_ts = CheckTimestamp();
    if (!status_ts.ok()) {
      AERROR << "Input messages timeout";
      estop_ = true;
      status = status_ts;
    }
  }

  // check estop
  estop_ = estop_ || trajectory_.estop().is_estop();

  // if planning set estop, then no control process triggered
  if (!estop_) {
    if (chassis_.driving_mode() == Chassis::COMPLETE_MANUAL) {
      controller_agent_.Reset();
      AINFO_EVERY(100) << "Reset Controllers in Manual Mode";
    }

    auto debug = control_command->mutable_debug()->mutable_input_debug();
    debug->mutable_localization_header()->CopyFrom(localization_.header());
    debug->mutable_canbus_header()->CopyFrom(chassis_.header());
    debug->mutable_trajectory_header()->CopyFrom(trajectory_.header());

    Status status_compute = controller_agent_.ComputeControlCommand(
        &localization_, &chassis_, &trajectory_, control_command);

    if (!status_compute.ok()) {
      AERROR << "Control main function failed"
             << " with localization: " << localization_.ShortDebugString()
             << " with chassis: " << chassis_.ShortDebugString()
             << " with trajectory: " << trajectory_.ShortDebugString()
             << " with cmd: " << control_command->ShortDebugString()
             << " status:" << status_compute.error_message();
      estop_ = true;
      status = status_compute;
    }
  }

  if (estop_) {
    AWARN_EVERY(100) << "Estop triggered! No control core method executed!";
    // set Estop command
    control_command->set_speed(0);
    control_command->set_throttle(0);
    control_command->set_brake(control_conf_.soft_estop_brake());
    control_command->set_gear_location(Chassis::GEAR_DRIVE);
  }
  // check signal
  if (trajectory_.decision().has_vehicle_signal()) {
    control_command->mutable_signal()->CopyFrom(
        trajectory_.decision().vehicle_signal());
  }
  return status;
}

void Control::OnTimer(const ros::TimerEvent &) {
  double start_timestamp = Clock::NowInSecond();

  ControlCommand control_command;

  Status status = ProduceControlCommand(&control_command);
  AERROR_IF(!status.ok()) << "Failed to produce control command:"
                          << status.error_message();

  double end_timestamp = Clock::NowInSecond();

  if (pad_received_) {
    control_command.mutable_pad_msg()->CopyFrom(pad_msg_);
    pad_received_ = false;
  }

  const double time_diff_ms = (end_timestamp - start_timestamp) * 1000;
  control_command.mutable_latency_stats()->set_total_time_ms(time_diff_ms);
  ADEBUG << "control cycle time is: " << time_diff_ms << " ms.";
  status.Save(control_command.mutable_header()->mutable_status());

  SendCmd(&control_command);
}

Status Control::CheckInput() {
  AdapterManager::Observe();
  auto localization_adapter = AdapterManager::GetLocalization();
  if (localization_adapter->Empty()) {
    AWARN_EVERY(100) << "No Localization msg yet. ";
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "No localization msg");
  }
  localization_ = localization_adapter->GetLatestObserved();
  ADEBUG << "Received localization:" << localization_.ShortDebugString();

  auto chassis_adapter = AdapterManager::GetChassis();
  if (chassis_adapter->Empty()) {
    AWARN_EVERY(100) << "No Chassis msg yet. ";
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "No chassis msg");
  }
  chassis_ = chassis_adapter->GetLatestObserved();
  ADEBUG << "Received chassis:" << chassis_.ShortDebugString();

  auto trajectory_adapter = AdapterManager::GetPlanning();
  if (trajectory_adapter->Empty()) {
    AWARN_EVERY(100) << "No planning msg yet. ";
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "No planning msg");
  }
  trajectory_ = trajectory_adapter->GetLatestObserved();
  if (!trajectory_.estop().is_estop() &&
      trajectory_.trajectory_point_size() == 0) {
    AWARN_EVERY(100) << "planning has no trajectory point. ";
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR,
                  "planning has no trajectory point.");
  }

  for (auto &trajectory_point : *trajectory_.mutable_trajectory_point()) {
    if (trajectory_point.v() < control_conf_.minimum_speed_resolution()) {
      trajectory_point.set_v(0.0);
      trajectory_point.set_a(0.0);
    }
  }

  // Add tempprary flag for test
  if (FLAGS_use_relative_position) {
    localization_.mutable_pose()->mutable_position()->set_x(0.0);
    localization_.mutable_pose()->mutable_position()->set_y(0.0);
    localization_.mutable_pose()->set_heading(0.0);
  }
  common::VehicleStateProvider::instance()->Update(localization_, chassis_);

  return Status::OK();
}

Status Control::CheckTimestamp() {
  if (!FLAGS_enable_input_timestamp_check || FLAGS_is_control_test_mode) {
    ADEBUG << "Skip input timestamp check by gflags.";
    return Status::OK();
  }
  double current_timestamp = Clock::NowInSecond();
  double localization_diff =
      current_timestamp - localization_.header().timestamp_sec();
  if (localization_diff >
      (FLAGS_max_localization_miss_num * control_conf_.localization_period())) {
    AERROR << "Localization msg lost for " << std::setprecision(6)
           << localization_diff << "s";
    apollo::common::monitor::MonitorBuffer buffer(&monitor_);
    buffer.ERROR("Localization msg lost");
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Localization msg timeout");
  }

  double chassis_diff = current_timestamp - chassis_.header().timestamp_sec();
  if (chassis_diff >
      (FLAGS_max_chassis_miss_num * control_conf_.chassis_period())) {
    AERROR << "Chassis msg lost for " << std::setprecision(6) << chassis_diff
           << "s";
    apollo::common::monitor::MonitorBuffer buffer(&monitor_);
    buffer.ERROR("Chassis msg lost");
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Chassis msg timeout");
  }

  double trajectory_diff =
      current_timestamp - trajectory_.header().timestamp_sec();
  if (trajectory_diff >
      (FLAGS_max_planning_miss_num * control_conf_.trajectory_period())) {
    AERROR << "Trajectory msg lost for " << std::setprecision(6)
           << trajectory_diff << "s";
    apollo::common::monitor::MonitorBuffer buffer(&monitor_);
    buffer.ERROR("Trajectory msg lost");
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Trajectory msg timeout");
  }
  return Status::OK();
}

void Control::SendCmd(ControlCommand *control_command) {
  // set header
  AdapterManager::FillControlCommandHeader(Name(), control_command);

  ADEBUG << control_command->ShortDebugString();
  if (FLAGS_is_control_test_mode) {
    ADEBUG << "Skip publish control command in test mode";
    return;
  }
  AdapterManager::PublishControlCommand(*control_command);
}

void Control::Stop() {}

}  // namespace control
}  // namespace apollo
<|endoftext|>


<commit_before>//=============================================================================
// ■ map.cpp
//-----------------------------------------------------------------------------
//   地图类
//=============================================================================

#include "tiled_map.hpp"
#include "glm/gtc/noise.hpp"

namespace VM76 {

	DataMap::DataMap(int w, int h, int l) {
		map = new TileData[w * h * l];
		width = w; length = l; height = h;

		generate_V1();
	}

	static TileData constStone = {1, 0};

	TileData DataMap::tileQuery(int x, int y, int z) {
		if (x < 0 || x > width || y < 0 || y > length || z < 0 || z > height) return constStone;
		return map[calcIndex(x,y,z)];
	}

	void DataMap::generate_flat() {
		for (int x = 0; x < width; x++)
			for (int z = 0; z < length; z++)
				for (int y = 0; y < height; y++)
					map[calcIndex(x,y,z)].tid = (y == 0) ? Grass : Air;
	}

	void DataMap::generate_V1() {
		for (int i = 0; i < width; i ++)
			for (int j = 0; j < length; j++) {
				glm::vec2 pos = glm::vec2(i, j) * 0.002f;
				float n = glm::perlin(pos);
				pos = pos * 1.5f + glm::vec2(0.1f, 0.13f); n += glm::perlin(pos) * 0.8f;
				pos = pos * 2.1f + glm::vec2(0.1f, 0.13f); n += glm::perlin(pos) * 0.6f;
				pos = pos * 2.2f + glm::vec2(0.1f, 0.13f); n += glm::perlin(pos) * 0.45f;
				pos = pos * 2.6f + glm::vec2(0.15f, 0.1f); n += glm::perlin(pos) * 0.25f;
				pos = pos * 4.5f + glm::vec2(0.09f); n += glm::perlin(pos) * 0.11f;

				n = glm::clamp(1.0f / (float) TERRIAN_MAX_HEIGHT, n * 0.5f + 0.5f, 1.0f);
				int h = n * TERRIAN_MAX_HEIGHT;
				int ho = h;
				h = glm::clamp(0, h, height);

				for (int y = 0; y < h; y++) {
					map[calcIndex(i, y, j)].tid = (y == ho - 1) ? Grass : Stone;
				}
				for (int y = h; y < height; y++) map[calcIndex(i, y, j)].tid = Air;
			}
	}

	Map::Map(int w, int h, int l, int csize) {
		log("Init map with size %d, %d, %d in chunk size %d", w, l, h, csize);
		CHUNK_SIZE = csize;
		width = w; length = l; height = h;
		bw = CHUNK_SIZE * w; bl = CHUNK_SIZE * l; bh = CHUNK_SIZE * h;

		chunks = new TiledMap*[w * l * h];

		map = new DataMap(bw, bh, bl);

		for (int x = 0; x < length; x++)
			for (int z = 0; z < width; z++) {
				log("Load Chunks group X:%d Z:%d", x, z);

				for (int y = 0; y < height; y++) {
					int ind = calcChunkIndex(x,y,z);
					chunks[ind] = new TiledMap(
						CHUNK_SIZE, CHUNK_SIZE, CHUNK_SIZE,
						glm::vec3(CHUNK_SIZE * x, CHUNK_SIZE * y, CHUNK_SIZE * z),
						map
					);
					chunks[ind]->bake_tiles();
				}
			}

		log("Map initialized");
	}

	void Map::place_block(glm::vec3 dir, int tid) {
		int cx = (int) dir.x / CHUNK_SIZE;
		int cy = (int) dir.y / CHUNK_SIZE;
		int cz = (int) dir.z / CHUNK_SIZE;

		map->map[map->calcIndex(dir)].tid = tid;
		chunks[calcChunkIndex(cx,cy,cz)]->bake_tiles();
	}

	void Map::render() {
		for (int x = 0; x < width * length * height; x++)
			chunks[x]->render();
	}

	void Map::dispose() {
		for (int x = 0; x < width * length * height; x++) VMDE_Dispose(chunks[x]);
		xefree(chunks);
	}

	int Map::calcChunkIndex(int x, int y, int z) {
		return (width * length) * y + (length) * z + x;
	}
}
<commit_msg>Log更新<commit_after>//=============================================================================
// ■ map.cpp
//-----------------------------------------------------------------------------
//   地图类
//=============================================================================

#include "tiled_map.hpp"
#include "glm/gtc/noise.hpp"

namespace VM76 {

	DataMap::DataMap(int w, int h, int l) {
		map = new TileData[w * h * l];
		width = w; length = l; height = h;

		generate_V1();
	}

	static TileData constStone = {1, 0};

	TileData DataMap::tileQuery(int x, int y, int z) {
		if (x < 0 || x > width || y < 0 || y > length || z < 0 || z > height) return constStone;
		return map[calcIndex(x,y,z)];
	}

	void DataMap::generate_flat() {
		for (int x = 0; x < width; x++)
			for (int z = 0; z < length; z++)
				for (int y = 0; y < height; y++)
					map[calcIndex(x,y,z)].tid = (y == 0) ? Grass : Air;
	}

	void DataMap::generate_V1() {
		log("Start generating maps");
		for (int i = 0; i < width; i ++) {
			if (i % (width / 12) == 0)
				log("Generated %d%% (%d / %d)",
					(int) (100.0 / width * i),
					i * length * height, width * length * height
				);

			for (int j = 0; j < length; j++) {
				glm::vec2 pos = glm::vec2(i, j) * 0.002f;
				float n = glm::perlin(pos);
				pos = pos * 1.5f + glm::vec2(0.1f, 0.13f); n += glm::perlin(pos) * 0.8f;
				pos = pos * 2.1f + glm::vec2(0.1f, 0.13f); n += glm::perlin(pos) * 0.6f;
				pos = pos * 2.2f + glm::vec2(0.1f, 0.13f); n += glm::perlin(pos) * 0.45f;
				pos = pos * 2.6f + glm::vec2(0.15f, 0.1f); n += glm::perlin(pos) * 0.25f;
				pos = pos * 4.5f + glm::vec2(0.09f); n += glm::perlin(pos) * 0.11f;

				n = glm::clamp(1.0f / (float) TERRIAN_MAX_HEIGHT, n * 0.5f + 0.5f, 1.0f);
				int h = n * TERRIAN_MAX_HEIGHT;
				int ho = h;
				h = glm::clamp(0, h, height);

				for (int y = 0; y < h; y++) {
					map[calcIndex(i, y, j)].tid = (y == ho - 1) ? Grass : Stone;
				}
				for (int y = h; y < height; y++) map[calcIndex(i, y, j)].tid = Air;
			}
		}
		log("Generated 100%%, Complete");
	}

	Map::Map(int w, int h, int l, int csize) {
		log("Init map with size %d, %d, %d in chunk size %d", w, l, h, csize);
		CHUNK_SIZE = csize;
		width = w; length = l; height = h;
		bw = CHUNK_SIZE * w; bl = CHUNK_SIZE * l; bh = CHUNK_SIZE * h;

		chunks = new TiledMap*[w * l * h];

		map = new DataMap(bw, bh, bl);

		for (int x = 0; x < length; x++) {
			log("Baking Chunks: %d%% (%d / %d)",
				(int) (100.0 / length * x),
				x * width * height, width * length * height
			);
			for (int z = 0; z < width; z++)
				for (int y = 0; y < height; y++) {
					int ind = calcChunkIndex(x,y,z);
					chunks[ind] = new TiledMap(
						CHUNK_SIZE, CHUNK_SIZE, CHUNK_SIZE,
						glm::vec3(CHUNK_SIZE * x, CHUNK_SIZE * y, CHUNK_SIZE * z),
						map
					);
					chunks[ind]->bake_tiles();
				}
		}

		log("Baking Chunks: 100%%, map initialized");
	}

	void Map::place_block(glm::vec3 dir, int tid) {
		int cx = (int) dir.x / CHUNK_SIZE;
		int cy = (int) dir.y / CHUNK_SIZE;
		int cz = (int) dir.z / CHUNK_SIZE;

		map->map[map->calcIndex(dir)].tid = tid;
		chunks[calcChunkIndex(cx,cy,cz)]->bake_tiles();
	}

	void Map::render() {
		for (int x = 0; x < width * length * height; x++)
			chunks[x]->render();
	}

	void Map::dispose() {
		for (int x = 0; x < width * length * height; x++) VMDE_Dispose(chunks[x]);
		xefree(chunks);
	}

	int Map::calcChunkIndex(int x, int y, int z) {
		return (width * length) * y + (length) * z + x;
	}
}
<|endoftext|>


<commit_before>// Copyright 2010-2012 Google
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <math.h>
#include <string.h>
#include <algorithm>
#include "base/hash.h"
#include <string>
#include <utility>
#include <vector>

#include "base/commandlineflags.h"
#include "base/hash.h"
#include "base/int-type-indexed-vector.h"
#include "base/int-type.h"
#include "base/integral_types.h"
#include "base/logging.h"
#include "base/map-util.h"
#include "base/scoped_ptr.h"
#include "base/stringprintf.h"
#include "constraint_solver/constraint_solver.h"
#include "constraint_solver/constraint_solveri.h"
#include "util/bitset.h"
#include "util/const_int_array.h"

namespace operations_research {
namespace {
DEFINE_INT_TYPE(AtomIndex, int);

const static AtomIndex kFailAtom = AtomIndex(0);

template <class T> class UnorderedRevArray {
 public:
  UnorderedRevArray(int initial_capacity)
  : elements_(), num_elements_(0) {
    elements_.reserve(initial_capacity);
  }

  UnorderedRevArray(const std::vector<T>& elements)
      : elements_(elements), num_elements_(elements.size()) {}

  ~UnorderedRevArray() {}

  int Size() const { return num_elements_.Value(); }

  T Element(int i) const {
    DCHECK_GE(i, 0);
    DCHECK_LT(i, num_elements_.Value());
    return elements_[i];
  }

  void Insert(Solver* const solver, T elt) {
    elements_.push_back(elt);
    num_elements_.Incr(solver);
  }

  void Remove(Solver* const solver, int position_of_element_to_remove) {
    num_elements_.Decr(solver);
    SwapTo(position_of_element_to_remove, num_elements_.Value());
  }

  void Clear(Solver* const solver) {
    num_elements_.SetValue(solver, 0);
  }

 private:
  void SwapTo(int current_position, int next_position) {
    if (current_position != next_position) {
      const T next_value = elements_[next_position];
      elements_[next_position] = elements_[current_position];
      elements_[current_position] = next_value;
    }
  }

  std::vector<T> elements_; // set of elements.
  NumericalRev<int> num_elements_; // number of elements in the set.
};

class Store;
class SumLessConstant;
class SumTriggerAction;

class Atom {
 public:
  Atom(AtomIndex index) : atom_index_(index) {}
  ~Atom() {}

  void Listen(SumLessConstant* const ct) {
    sum_less_constant_constraints_.push_back(ct);
  }

  void Listen(SumTriggerAction* const ct) {
    sum_trigger_actions_constraints_.insert(ct);
  }

  void StopListening(SumTriggerAction* const ct) {
    sum_trigger_actions_constraints_.erase(ct);
  }

  void AddFlipAction(AtomIndex action) {
    actions_.push_back(action);
  }

  void Flip(Store* const store);

  bool IsFlipped() const {
    return flipped_.Switched();
  }

 private:
  const AtomIndex atom_index_;
  std::vector<SumLessConstant*> sum_less_constant_constraints_;
  hash_set<SumTriggerAction*> sum_trigger_actions_constraints_;
  std::vector<AtomIndex> actions_;
  RevSwitch flipped_;
};

class Store : public Constraint {
 public:
  Store(Solver* const solver) : Constraint(solver) {}

  ~Store() {}

  AtomIndex TrueIndex(IntVar* const var) {
    int raw_index = indices_.Add(var);
    if (raw_index >= true_atoms_.size()) {
      true_atoms_.resize(raw_index);
      false_atoms_.resize(raw_index);
    }
    return 1 + AtomIndex(raw_index);
  }

  AtomIndex FalseIndex(IntVar* const var) {
    return -TrueIndex(var);
  }

  void VariableBound(int index) {
    if (indices_.Element(index)->Min() == 0) {
      Flip(AtomIndex(-1 - index));
    } else {
      Flip(AtomIndex(1 + index));
    }
  }

  void Listen(AtomIndex atom, SumLessConstant* const ct) {
    FindAtom(atom)->Listen(ct);
  }

  void Listen(AtomIndex atom, SumTriggerAction* const ct) {
    FindAtom(atom)->Listen(ct);
  }

  void StopListening(AtomIndex atom, SumTriggerAction* const ct) {
    FindAtom(atom)->StopListening(ct);
  }

  void Flip(AtomIndex atom) {
    if (atom == kFailAtom || IsFlipped(-atom)) {
      solver()->Fail();
    } else {
      FindAtom(atom)->Flip(this);
    }
  }

  bool IsFlipped(AtomIndex atom) {
    if (atom == kFailAtom) {
      return false;
    } else {
      return FindAtom(atom)->IsFlipped();
    }
  }

  virtual void Post() {
    for (int i = 0; i < indices_.size(); ++i) {
      Demon* const d = MakeConstraintDemon1(solver(),
                                            this,
                                            &Store::VariableBound,
                                            "VariableBound",
                                            i);
      indices_.Element(i)->WhenDomain(d);
    }
  }

  virtual void InitialPropagate() {
    for (int i = 0; i < indices_.size(); ++i) {
      if (indices_.Element(i)->Bound()) {
        VariableBound(i);
      }
    }
  }

 private:
  Atom* FindAtom(AtomIndex atom) const {
    CHECK_NE(atom, kFailAtom);
    if (atom > kFailAtom) {
      return true_atoms_[atom.value() - 1];
    } else {
      return false_atoms_[-1 - atom.value()];
    }
  }

  VectorMap<IntVar*> indices_;
  std::vector<Atom*> true_atoms_;
  std::vector<Atom*> false_atoms_;
};

class SumLessConstant {
 public:
  SumLessConstant(std::vector<AtomIndex>& vars, int constant)
      : vars_(vars),
        constant_(constant),
        sum_(0) {}

  ~SumLessConstant() {}

  void Post(Store* const store) {
    for (int i = 0; i < vars_.size(); ++i) {
      store->Listen(vars_[i], this);
    }
  }

  void Flip(Store* const store, AtomIndex index) {
    sum_.Incr(store->solver());
    if (sum_.Value() > constant_) {
      store->solver()->Fail();
    } else if (sum_.Value() == constant_) {
      UnflipAllPending(store);
    }
  }

  void UnflipAllPending(Store* const store) {
    int count = 0;
    for (int i = 0; i < vars_.size(); ++i) {
      if (!store->IsFlipped(vars_[i])) {
        count++;
        store->Flip(-vars_[i]);
      }
    }
    // Check count.
  }

 private:
  std::vector<AtomIndex> vars_;
  const int constant_;
  NumericalRev<int> sum_;
};

class SumTriggerAction {
 public:
  SumTriggerAction(std::vector<AtomIndex>& vars,
                   int constant,
                   std::vector<AtomIndex>& actions)
      : vars_(vars),
        constant_(constant),
        actions_(actions),
        sum_(0) {}

  ~SumTriggerAction() {}

  void Post(Store* const store) {
    for (int i = 0; i < vars_.size(); ++i) {
      store->Listen(vars_[i], this);
    }
  }

  void Flip(Store* const store, AtomIndex index) {
    sum_.Incr(store->solver());
    if (sum_.Value() >= constant_) {
      StopListening(store);
      FlipAllAction(store);
    }
  }

  void StopListening(Store* const store) {
    for (int i = 0; i < vars_.size(); ++i) {
      store->StopListening(vars_[i], this);
    }
  }

  void FlipAllAction(Store* const store) {
    for (int i = 0; i < actions_.size(); ++i) {
      store->Flip(actions_[i]);
    }
  }

 private:
  std::vector<AtomIndex> vars_;
  const int constant_;
  std::vector<AtomIndex> actions_;
  NumericalRev<int> sum_;
};

void Atom::Flip(Store* const store) {
  for (int i = 0; i < actions_.size(); ++i) {
    store->Flip(actions_[i]);
  }
  for (int i = 0; i < sum_less_constant_constraints_.size(); ++i) {
    sum_less_constant_constraints_[i]->Flip(store, atom_index_);
  }
  for (ConstIter<hash_set<SumTriggerAction*> > iter(
           sum_trigger_actions_constraints_); !iter.at_end(); ++iter) {
    (*iter)->Flip(store, atom_index_);
  }
}
}  // namespace

}  // namespace operations_research
<commit_msg>unfinished boolean propagator<commit_after>// Copyright 2010-2012 Google
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <math.h>
#include <string.h>
#include <algorithm>
#include "base/hash.h"
#include <string>
#include <utility>
#include <vector>

#include "base/commandlineflags.h"
#include "base/hash.h"
#include "base/int-type-indexed-vector.h"
#include "base/int-type.h"
#include "base/integral_types.h"
#include "base/logging.h"
#include "base/map-util.h"
#include "base/scoped_ptr.h"
#include "base/stringprintf.h"
#include "constraint_solver/constraint_solver.h"
#include "constraint_solver/constraint_solveri.h"
#include "util/bitset.h"
#include "util/const_int_array.h"

namespace operations_research {
namespace {
DEFINE_INT_TYPE(AtomIndex, int);

const static AtomIndex kFailAtom = AtomIndex(0);

template <class T> class UnorderedRevArray {
 public:
  UnorderedRevArray(int initial_capacity)
  : elements_(), num_elements_(0) {
    elements_.reserve(initial_capacity);
  }

  UnorderedRevArray(const std::vector<T>& elements)
      : elements_(elements), num_elements_(elements.size()) {}

  ~UnorderedRevArray() {}

  int Size() const { return num_elements_.Value(); }

  T Element(int i) const {
    DCHECK_GE(i, 0);
    DCHECK_LT(i, num_elements_.Value());
    return elements_[i];
  }

  void Insert(Solver* const solver, T elt) {
    elements_.push_back(elt);
    num_elements_.Incr(solver);
  }

  void Remove(Solver* const solver, int position_of_element_to_remove) {
    num_elements_.Decr(solver);
    SwapTo(position_of_element_to_remove, num_elements_.Value());
  }

  void Clear(Solver* const solver) {
    num_elements_.SetValue(solver, 0);
  }

 private:
  void SwapTo(int current_position, int next_position) {
    if (current_position != next_position) {
      const T next_value = elements_[next_position];
      elements_[next_position] = elements_[current_position];
      elements_[current_position] = next_value;
    }
  }

  std::vector<T> elements_; // set of elements.
  NumericalRev<int> num_elements_; // number of elements in the set.
};

class Store;
class SumLessConstant;
class SumTriggerAction;

class Atom {
 public:
  Atom(AtomIndex index) : atom_index_(index) {}
  ~Atom() {}

  void Listen(SumLessConstant* const ct) {
    sum_less_constant_constraints_.push_back(ct);
  }

  void Listen(SumTriggerAction* const ct) {
    sum_trigger_actions_constraints_.insert(ct);
  }

  void StopListening(SumTriggerAction* const ct) {
    sum_trigger_actions_constraints_.erase(ct);
  }

  void AddFlipAction(AtomIndex action) {
    actions_.push_back(action);
  }

  void Flip(Store* const store);

  bool IsFlipped() const {
    return flipped_.Switched();
  }

 private:
  const AtomIndex atom_index_;
  std::vector<SumLessConstant*> sum_less_constant_constraints_;
  hash_set<SumTriggerAction*> sum_trigger_actions_constraints_;
  std::vector<AtomIndex> actions_;
  RevSwitch flipped_;
};

class Store : public Constraint {
 public:
  Store(Solver* const solver) : Constraint(solver) {}

  ~Store() {}

  AtomIndex TrueIndex(IntVar* const var) {
    int raw_index = indices_.Add(var);
    if (raw_index >= true_atoms_.size()) {
      true_atoms_.resize(raw_index);
      false_atoms_.resize(raw_index);
    }
    return 1 + AtomIndex(raw_index);
  }

  AtomIndex FalseIndex(IntVar* const var) {
    return -TrueIndex(var);
  }

  void VariableBound(int index) {
    if (indices_.Element(index)->Min() == 0) {
      Flip(AtomIndex(-1 - index));
    } else {
      Flip(AtomIndex(1 + index));
    }
  }

  void Listen(AtomIndex atom, SumLessConstant* const ct) {
    FindAtom(atom)->Listen(ct);
  }

  void Listen(AtomIndex atom, SumTriggerAction* const ct) {
    FindAtom(atom)->Listen(ct);
  }

  void StopListening(AtomIndex atom, SumTriggerAction* const ct) {
    FindAtom(atom)->StopListening(ct);
  }

  void Flip(AtomIndex atom) {
    if (atom == kFailAtom || IsFlipped(-atom)) {
      solver()->Fail();
    } else {
      FindAtom(atom)->Flip(this);
    }
  }

  bool IsFlipped(AtomIndex atom) {
    if (atom == kFailAtom) {
      return false;
    } else {
      return FindAtom(atom)->IsFlipped();
    }
  }

  virtual void Post() {
    for (int i = 0; i < indices_.size(); ++i) {
      Demon* const d = MakeConstraintDemon1(solver(),
                                            this,
                                            &Store::VariableBound,
                                            "VariableBound",
                                            i);
      indices_.Element(i)->WhenDomain(d);
    }
  }

  virtual void InitialPropagate() {
    for (int i = 0; i < indices_.size(); ++i) {
      if (indices_.Element(i)->Bound()) {
        VariableBound(i);
      }
    }
  }

 private:
  Atom* FindAtom(AtomIndex atom) const {
    CHECK_NE(atom, kFailAtom);
    if (atom > kFailAtom) {
      return true_atoms_[atom.value() - 1];
    } else {
      return false_atoms_[-1 - atom.value()];
    }
  }

  VectorMap<IntVar*> indices_;
  std::vector<Atom*> true_atoms_;
  std::vector<Atom*> false_atoms_;
};

class SumLessConstant {
 public:
  SumLessConstant(std::vector<AtomIndex>& vars, int constant)
      : vars_(vars),
        constant_(constant),
        sum_(0) {}

  ~SumLessConstant() {}

  void Post(Store* const store) {
    for (int i = 0; i < vars_.size(); ++i) {
      store->Listen(vars_[i], this);
    }
  }

  void Flip(Store* const store, AtomIndex index) {
    sum_.Incr(store->solver());
    if (sum_.Value() > constant_) {
      store->solver()->Fail();
    } else if (sum_.Value() == constant_) {
      UnflipAllPending(store);
    }
  }

  void UnflipAllPending(Store* const store) {
    int count = 0;
    for (int i = 0; i < vars_.size(); ++i) {
      if (!store->IsFlipped(vars_[i])) {
        count++;
        store->Flip(-vars_[i]);
      }
    }
    // Check count.
  }

 private:
  std::vector<AtomIndex> vars_;
  const int constant_;
  NumericalRev<int> sum_;
};

class SumTriggerAction {
 public:
  SumTriggerAction(std::vector<AtomIndex>& vars,
                   int constant,
                   std::vector<AtomIndex>& actions)
      : vars_(vars),
        constant_(constant),
        actions_(actions),
        sum_(0) {}

  ~SumTriggerAction() {}

  void Post(Store* const store) {
    for (int i = 0; i < vars_.size(); ++i) {
      store->Listen(vars_[i], this);
    }
  }

  void Flip(Store* const store, AtomIndex index) {
    sum_.Incr(store->solver());
    if (sum_.Value() >= constant_) {
      StopListening(store);
      FlipAllAction(store);
    }
  }

  void StopListening(Store* const store) {
    for (int i = 0; i < vars_.size(); ++i) {
      store->StopListening(vars_[i], this);
    }
  }

  void FlipAllAction(Store* const store) {
    for (int i = 0; i < actions_.size(); ++i) {
      store->Flip(actions_[i]);
    }
  }

 private:
  std::vector<AtomIndex> vars_;
  const int constant_;
  std::vector<AtomIndex> actions_;
  NumericalRev<int> sum_;
};

void Atom::Flip(Store* const store) {
  CHECK(!flipped_.Switched());
  flipped_.Switch(store->solver());
  for (int i = 0; i < actions_.size(); ++i) {
    store->Flip(actions_[i]);
  }
  for (int i = 0; i < sum_less_constant_constraints_.size(); ++i) {
    sum_less_constant_constraints_[i]->Flip(store, atom_index_);
  }
  for (ConstIter<hash_set<SumTriggerAction*> > iter(
           sum_trigger_actions_constraints_); !iter.at_end(); ++iter) {
    (*iter)->Flip(store, atom_index_);
  }
}
}  // namespace

}  // namespace operations_research
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName         :    NFPluginLoader.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :
//    @Module           :    NFPluginLoader
//
// -------------------------------------------------------------------------

//#include <crtdbg.h>
#include <time.h>
#include <stdio.h>
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <functional>
#include <atomic>
#include "NFCActorManager.h"
#include "NFComm/Config/NFConfig.h"
#include "NFComm/NFCore/NFPlatform.h"
#include "boost/thread.hpp"

#pragma comment( lib, "DbgHelp" )
#if NF_PLATFORM == NF_PLATFORM_WIN

// Dumpļ
void CreateDumpFile(const std::string& strDumpFilePathName, EXCEPTION_POINTERS* pException)
{
    // Dumpļ
    HANDLE hDumpFile = CreateFile(strDumpFilePathName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    // DumpϢ
    MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
    dumpInfo.ExceptionPointers = pException;
    dumpInfo.ThreadId = GetCurrentThreadId();
    dumpInfo.ClientPointers = TRUE;

    // дDumpļ
    MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);

    CloseHandle(hDumpFile);
}

// Unhandled ExceptionĻص
long ApplicationCrashHandler(EXCEPTION_POINTERS* pException)
{
    time_t t = time(0);
    char szDmupName[MAX_PATH];
    tm* ptm = localtime(&t);

    sprintf(szDmupName, "%d_%d_%d_%d_%d_%d.dmp",  ptm->tm_year + 1900, ptm->tm_mon, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
    CreateDumpFile(szDmupName, pException);

    FatalAppExit(-1,  szDmupName);

    return EXCEPTION_EXECUTE_HANDLER;
}
#endif

void CloseXButton()
{
#if NF_PLATFORM == NF_PLATFORM_WIN

    HWND hWnd = GetConsoleWindow();
    if(hWnd)
    {
        HMENU hMenu = GetSystemMenu(hWnd, FALSE);
        EnableMenuItem(hMenu, SC_CLOSE, MF_DISABLED | MF_BYCOMMAND);
    }

#endif
}

bool bExitApp = false;
boost::thread gThread;

void ThreadFunc()
{
    while ( !bExitApp )
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));

        std::string s;
        std::cin >> s;
        if ( 0 == stricmp( s.c_str(), "exit" ) )
        {
            bExitApp = true;
        }
    }
}

void CreateBackThread()
{
    gThread = boost::thread(boost::bind(&ThreadFunc));
    //std::cout << "CreateBackThread, thread ID = " << gThread.get_id() << std::endl;
}

void PrintfLogo()
{
#if NF_PLATFORM == NF_PLATFORM_WIN
    std::cout << "\n" << std::endl;

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

    std::cout << "" << std::endl;
    std::cout << "                                            " << std::endl;
    std::cout << "                 NoahFrame                  " << std::endl;
    std::cout << "     Copyright (c) 2011  kytoo              " << std::endl;
    std::cout << "             All rights reserved.           " << std::endl;
    std::cout << "                                            " << std::endl;
    std::cout << "               www.yowoyo.com               " << std::endl;
    std::cout << "                                            " << std::endl;
    std::cout << "\n" << std::endl;

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

    std::cout << "\n" << std::endl;
#endif // NF_PLATFORM
}

unsigned long unStartTickTime = 0;
unsigned long unLastTickTime = 0;

#if NF_PLATFORM == NF_PLATFORM_WIN || NF_PLATFORM == NF_PLATFORM_LINUX || NF_PLATFORM == NF_PLATFORM_APPLE
int main()
#elif  NF_PLATFORM == NF_PLATFORM_ANDROID || NF_PLATFORM == NF_PLATFORM_APPLE_IOS

#endif
{
#if NF_PLATFORM == NF_PLATFORM_WIN
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);
#endif
	NFCActorManager::GetSingletonPtr()->Init();
	NFCActorManager::GetSingletonPtr()->AfterInit();
    NFCActorManager::GetSingletonPtr()->CheckConfig();

    PrintfLogo();

    CloseXButton();
    CreateBackThread();

    unStartTickTime = ::NF_GetTickCount();
    unLastTickTime = unStartTickTime;

    while (!bExitApp)    //DEBUG汾RELEASE
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        while (true)
        {
            if (bExitApp)
            {
                break;
            }

			unsigned long unNowTickTime = ::NF_GetTickCount();
			float fStartedTime = float(unNowTickTime - unStartTickTime) / 1000;
			float fLastTime = float(unNowTickTime - unLastTickTime) / 1000;

			if (fStartedTime < 0.001f)
			{
				fStartedTime = 0.0f;
			}

			if (fLastTime < 0.001f)
			{
				fLastTime = 0.0f;
			}
#if NF_PLATFORM == NF_PLATFORM_WIN
            __try
            {
#endif
                NFCActorManager::GetSingletonPtr()->Execute(fLastTime, fStartedTime);
				unLastTickTime = unNowTickTime;
#if NF_PLATFORM == NF_PLATFORM_WIN
            }
            __except (ApplicationCrashHandler(GetExceptionInformation()))
            {
            }
#endif
        }
    }

	NFCActorManager::GetSingletonPtr()->BeforeShut();
	NFCActorManager::GetSingletonPtr()->Shut();

    NFCActorManager::GetSingletonPtr()->ReleaseInstance();

    return 0;
}
<commit_msg>release version<commit_after>// -------------------------------------------------------------------------
//    @FileName         :    NFPluginLoader.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :
//    @Module           :    NFPluginLoader
//
// -------------------------------------------------------------------------

//#include <crtdbg.h>
#include <time.h>
#include <stdio.h>
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <functional>
#include <atomic>
#include "NFCActorManager.h"
#include "NFComm/Config/NFConfig.h"
#include "NFComm/NFCore/NFPlatform.h"
#include "boost/thread.hpp"

#pragma comment( lib, "DbgHelp" )
#if NF_PLATFORM == NF_PLATFORM_WIN

// Dumpļ
void CreateDumpFile(const std::string& strDumpFilePathName, EXCEPTION_POINTERS* pException)
{
    // Dumpļ
    HANDLE hDumpFile = CreateFile(strDumpFilePathName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    // DumpϢ
    MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
    dumpInfo.ExceptionPointers = pException;
    dumpInfo.ThreadId = GetCurrentThreadId();
    dumpInfo.ClientPointers = TRUE;

    // дDumpļ
    MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);

    CloseHandle(hDumpFile);
}

// Unhandled ExceptionĻص
long ApplicationCrashHandler(EXCEPTION_POINTERS* pException)
{
    time_t t = time(0);
    char szDmupName[MAX_PATH];
    tm* ptm = localtime(&t);

    sprintf(szDmupName, "%d_%d_%d_%d_%d_%d.dmp",  ptm->tm_year + 1900, ptm->tm_mon, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
    CreateDumpFile(szDmupName, pException);

    FatalAppExit(-1,  szDmupName);

    return EXCEPTION_EXECUTE_HANDLER;
}
#endif

void CloseXButton()
{
#if NF_PLATFORM == NF_PLATFORM_WIN

    HWND hWnd = GetConsoleWindow();
    if(hWnd)
    {
        HMENU hMenu = GetSystemMenu(hWnd, FALSE);
        EnableMenuItem(hMenu, SC_CLOSE, MF_DISABLED | MF_BYCOMMAND);
    }

#endif
}

bool bExitApp = false;
boost::thread gThread;

void ThreadFunc()
{
    while ( !bExitApp )
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));

        std::string s;
        std::cin >> s;
        if ( 0 == stricmp( s.c_str(), "exit" ) )
        {
            bExitApp = true;
        }
    }
}

void CreateBackThread()
{
    gThread = boost::thread(boost::bind(&ThreadFunc));
    //std::cout << "CreateBackThread, thread ID = " << gThread.get_id() << std::endl;
}

void PrintfLogo()
{
#if NF_PLATFORM == NF_PLATFORM_WIN
    std::cout << "\n" << std::endl;

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

    std::cout << "" << std::endl;
    std::cout << "                                            " << std::endl;
    std::cout << "                 NoahFrame                  " << std::endl;
    std::cout << "     Copyright (c) 2011  kytoo              " << std::endl;
    std::cout << "             All rights reserved.           " << std::endl;
    std::cout << "                                            " << std::endl;
    std::cout << "               www.yowoyo.com               " << std::endl;
    std::cout << "                                            " << std::endl;
    std::cout << "\n" << std::endl;

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

    std::cout << "\n" << std::endl;
#endif // NF_PLATFORM
}

unsigned long unStartTickTime = 0;
unsigned long unLastTickTime = 0;

#if NF_PLATFORM == NF_PLATFORM_WIN || NF_PLATFORM == NF_PLATFORM_LINUX || NF_PLATFORM == NF_PLATFORM_APPLE
int main()
#elif  NF_PLATFORM == NF_PLATFORM_ANDROID || NF_PLATFORM == NF_PLATFORM_APPLE_IOS

#endif
{
#if NF_PLATFORM == NF_PLATFORM_WIN
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);
#endif
	NFCActorManager::GetSingletonPtr()->Init();
	NFCActorManager::GetSingletonPtr()->AfterInit();
    NFCActorManager::GetSingletonPtr()->CheckConfig();

    PrintfLogo();

    CloseXButton();
    CreateBackThread();

    unStartTickTime = ::NF_GetTickCount();
    unLastTickTime = unStartTickTime;

    while (!bExitApp)    //DEBUG汾RELEASE
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        while (true)
        {
            if (bExitApp)
            {
                break;
            }

			unsigned long unNowTickTime = ::NF_GetTickCount();
			float fStartedTime = float(unNowTickTime - unStartTickTime) / 1000;
			float fLastTime = float(unNowTickTime - unLastTickTime) / 1000;

			if (fStartedTime < 0.001f)
			{
				fStartedTime = 0.0f;
			}

#if NF_PLATFORM == NF_PLATFORM_WIN
            __try
            {
#endif
                NFCActorManager::GetSingletonPtr()->Execute(fLastTime, fStartedTime);
				unLastTickTime = unNowTickTime;
#if NF_PLATFORM == NF_PLATFORM_WIN
            }
            __except (ApplicationCrashHandler(GetExceptionInformation()))
            {
            }
#endif
        }
    }

	NFCActorManager::GetSingletonPtr()->BeforeShut();
	NFCActorManager::GetSingletonPtr()->Shut();

    NFCActorManager::GetSingletonPtr()->ReleaseInstance();

    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: accresmgr.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_accessibility.hxx"
#include <accessibility/helper/accresmgr.hxx>

#ifndef _TOOLS_SIMPLERESMGR_HXX
#include <tools/simplerm.hxx>
#endif
#include <vcl/svapp.hxx>

// -----------------------------------------------------------------------------
// TkResMgr
// -----------------------------------------------------------------------------

SimpleResMgr* TkResMgr::m_pImpl = NULL;

// -----------------------------------------------------------------------------

TkResMgr::EnsureDelete::~EnsureDelete()
{
    delete TkResMgr::m_pImpl;
}

// -----------------------------------------------------------------------------

void TkResMgr::ensureImplExists()
{
    if (m_pImpl)
        return;

    ::com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();

    ByteString sResMgrName( "tk" );

    m_pImpl = SimpleResMgr::Create( sResMgrName.GetBuffer(), aLocale );

    if (m_pImpl)
    {
        // now that we have a impl class, make sure it's deleted on unloading the library
        static TkResMgr::EnsureDelete s_aDeleteTheImplClass;
    }
}

// -----------------------------------------------------------------------------

::rtl::OUString TkResMgr::loadString( sal_uInt16 nResId )
{
    ::rtl::OUString sReturn;

    ensureImplExists();
    if ( m_pImpl )
        sReturn = m_pImpl->ReadString( nResId );

    return sReturn;
}

// -----------------------------------------------------------------------------
<commit_msg>INTEGRATION: CWS aqua11y01 (1.3.26); FILE MERGED 2008/03/12 12:14:52 obr 1.3.26.2: RESYNC: (1.3-1.4); FILE MERGED 2007/12/10 13:37:29 fne 1.3.26.1: #i82877# corrected resource bundle name<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: accresmgr.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_accessibility.hxx"
#include <accessibility/helper/accresmgr.hxx>

#ifndef _TOOLS_SIMPLERESMGR_HXX
#include <tools/simplerm.hxx>
#endif
#include <vcl/svapp.hxx>

// -----------------------------------------------------------------------------
// TkResMgr
// -----------------------------------------------------------------------------

SimpleResMgr* TkResMgr::m_pImpl = NULL;

// -----------------------------------------------------------------------------

TkResMgr::EnsureDelete::~EnsureDelete()
{
    delete TkResMgr::m_pImpl;
}

// -----------------------------------------------------------------------------

void TkResMgr::ensureImplExists()
{
    if (m_pImpl)
        return;

    ::com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();

    ByteString sResMgrName( "acc" );

    m_pImpl = SimpleResMgr::Create( sResMgrName.GetBuffer(), aLocale );

    if (m_pImpl)
    {
        // now that we have a impl class, make sure it's deleted on unloading the library
        static TkResMgr::EnsureDelete s_aDeleteTheImplClass;
    }
}

// -----------------------------------------------------------------------------

::rtl::OUString TkResMgr::loadString( sal_uInt16 nResId )
{
    ::rtl::OUString sReturn;

    ensureImplExists();
    if ( m_pImpl )
        sReturn = m_pImpl->ReadString( nResId );

    return sReturn;
}

// -----------------------------------------------------------------------------
<|endoftext|>