<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Alexandru-Eugen Ichim
 *                      Willow Garage, Inc
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *  $Id$
 */

#ifndef PCL_FEATURES_IMPL_NORMAL_BASED_SIGNATURE_H_
#define PCL_FEATURES_IMPL_NORMAL_BASED_SIGNATURE_H_

#include <pcl/features/normal_based_signature.h>

template <typename PointT, typename PointNT, typename PointFeature> void
pcl::NormalBasedSignatureEstimation<PointT, PointNT, PointFeature>::computeFeature (FeatureCloud &output)
{
  // do a few checks before starting the computations

  PointFeature test_feature;
  if (N_prime_ * M_prime_ != sizeof (test_feature.values) / sizeof (float))
  {
    PCL_ERROR ("NormalBasedSignatureEstimation: not using the proper signature size: %u vs %u\n", N_prime_ * M_prime_, sizeof (test_feature.values) / sizeof (float));
    return;
  }

  std::vector<int> k_indices;
  std::vector<float> k_sqr_distances;

  tree_->setInputCloud (input_);
  output.points.resize (indices_->size ());

  for (size_t index_i = 0; index_i < indices_->size (); ++index_i)
  {
    size_t point_i = (*indices_)[index_i];
    Eigen::MatrixXf s_matrix (N_, M_);

    Eigen::Vector4f center_point = input_->points[point_i].getVector4fMap ();

    for (size_t k = 0; k < N_; ++k)
    {
      Eigen::VectorXf s_row (M_);

      for (size_t l = 0; l < M_; ++l)
      {
        Eigen::Vector4f normal = normals_->points[point_i].getNormalVector4fMap ();
        Eigen::Vector4f normal_u = Eigen::Vector4f::Zero ();
        Eigen::Vector4f normal_v = Eigen::Vector4f::Zero ();

        if (fabs (normal.x ()) > 0.0001f)
        {
          normal_u.x () = - normal.y () / normal.x ();
          normal_u.y () = 1.0f;
          normal_u.z () = 0.0f;
          normal_u.normalize ();

        }
        else if (fabs (normal.y ()) > 0.0001f)
        {
          normal_u.x () = 1.0f;
          normal_u.y () = - normal.x () / normal.y ();
          normal_u.z () = 0.0f;
          normal_u.normalize ();
        }
        else
        {
          normal_u.x () = 0.0f;
          normal_u.y () = 1.0f;
          normal_u.z () = - normal.y () / normal.z ();
        }
        normal_v = normal.cross3 (normal_u);

        Eigen::Vector4f zeta_point = 2.0f * static_cast<float> (l + 1) * scale_h_ / static_cast<float> (M_) *
            (cosf (2.0f * static_cast<float> (M_PI) * static_cast<float> ((k + 1) / N_)) * normal_u +
             sinf (2.0f * static_cast<float> (M_PI) * static_cast<float> ((k + 1) / N_)) * normal_v);

        // Compute normal by using the neighbors
        Eigen::Vector4f zeta_point_plus_center = zeta_point + center_point;
        PointT zeta_point_pcl;
        zeta_point_pcl.x = zeta_point_plus_center.x (); zeta_point_pcl.y = zeta_point_plus_center.y (); zeta_point_pcl.z = zeta_point_plus_center.z ();

        tree_->radiusSearch (zeta_point_pcl, search_radius_, k_indices, k_sqr_distances);

        // Do k nearest search if there are no neighbors nearby
        if (k_indices.size () == 0)
        {
          k_indices.resize (5);
          k_sqr_distances.resize (5);
          tree_->nearestKSearch (zeta_point_pcl, 5, k_indices, k_sqr_distances);
        }

        Eigen::Vector4f average_normal = Eigen::Vector4f::Zero ();

        float average_normalization_factor = 0.0f;

        // Normals weighted by 1/squared_distances
        for (size_t nn_i = 0; nn_i < k_indices.size (); ++nn_i)
        {
          if (k_sqr_distances[nn_i] < 1e-7f)
          {
            average_normal = normals_->points[k_indices[nn_i]].getNormalVector4fMap ();
            average_normalization_factor = 1.0f;
            break;
          }
          average_normal += normals_->points[k_indices[nn_i]].getNormalVector4fMap () / k_sqr_distances[nn_i];
          average_normalization_factor += 1.0f / k_sqr_distances[nn_i];
        }
        average_normal /= average_normalization_factor;
        float s = zeta_point.dot (average_normal) / zeta_point.norm ();
        s_row[l] = s;
      }

      // do DCT on the s_matrix row-wise
      Eigen::VectorXf dct_row (M_);
      for (int m = 0; m < s_row.size (); ++m)
      {
        float Xk = 0.0f;
        for (int n = 0; n < s_row.size (); ++n)
          Xk += static_cast<float> (s_row[n] * cos (M_PI / (static_cast<double> (M_ * n) + 0.5) * static_cast<double> (k)));
        dct_row[m] = Xk;
      }
      s_row = dct_row;
      s_matrix.row (k).matrix () = dct_row;
    }

    // do DFT on the s_matrix column-wise
    Eigen::MatrixXf dft_matrix (N_, M_);
    for (size_t column_i = 0; column_i < M_; ++column_i)
    {
      Eigen::VectorXf dft_col (N_);
      for (size_t k = 0; k < N_; ++k)
      {
        float Xk_real = 0.0f, Xk_imag = 0.0f;
        for (size_t n = 0; n < N_; ++n)
        {
          Xk_real += static_cast<float> (s_matrix (n, column_i) * cos (2.0f * M_PI / static_cast<double> (N_ * k * n)));
          Xk_imag += static_cast<float> (s_matrix (n, column_i) * sin (2.0f * M_PI / static_cast<double> (N_ * k * n)));
        }
        dft_col[k] = sqrtf (Xk_real*Xk_real + Xk_imag*Xk_imag);
      }
      dft_matrix.col (column_i).matrix () = dft_col;
    }

    Eigen::MatrixXf final_matrix = dft_matrix.block (0, 0, N_prime_, M_prime_);

    PointFeature feature_point;
    for (size_t i = 0; i < N_prime_; ++i)
      for (size_t j = 0; j < M_prime_; ++j)
        feature_point.values[i*M_prime_ + j] = final_matrix (i, j);

    output.points[index_i] = feature_point;
  }
}

#define PCL_INSTANTIATE_NormalBasedSignatureEstimation(T,NT,OutT) template class PCL_EXPORTS pcl::NormalBasedSignatureEstimation<T,NT,OutT>;

#endif /* PCL_FEATURES_IMPL_NORMAL_BASED_SIGNATURE_H_ */
<commit_msg>removed a compiler warning on win32<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Alexandru-Eugen Ichim
 *                      Willow Garage, Inc
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *  $Id$
 */

#ifndef PCL_FEATURES_IMPL_NORMAL_BASED_SIGNATURE_H_
#define PCL_FEATURES_IMPL_NORMAL_BASED_SIGNATURE_H_

#include <pcl/features/normal_based_signature.h>

template <typename PointT, typename PointNT, typename PointFeature> void
pcl::NormalBasedSignatureEstimation<PointT, PointNT, PointFeature>::computeFeature (FeatureCloud &output)
{
  // do a few checks before starting the computations

  PointFeature test_feature;
  (void)test_feature;
  if (N_prime_ * M_prime_ != sizeof (test_feature.values) / sizeof (float))
  {
    PCL_ERROR ("NormalBasedSignatureEstimation: not using the proper signature size: %u vs %u\n", N_prime_ * M_prime_, sizeof (test_feature.values) / sizeof (float));
    return;
  }

  std::vector<int> k_indices;
  std::vector<float> k_sqr_distances;

  tree_->setInputCloud (input_);
  output.points.resize (indices_->size ());

  for (size_t index_i = 0; index_i < indices_->size (); ++index_i)
  {
    size_t point_i = (*indices_)[index_i];
    Eigen::MatrixXf s_matrix (N_, M_);

    Eigen::Vector4f center_point = input_->points[point_i].getVector4fMap ();

    for (size_t k = 0; k < N_; ++k)
    {
      Eigen::VectorXf s_row (M_);

      for (size_t l = 0; l < M_; ++l)
      {
        Eigen::Vector4f normal = normals_->points[point_i].getNormalVector4fMap ();
        Eigen::Vector4f normal_u = Eigen::Vector4f::Zero ();
        Eigen::Vector4f normal_v = Eigen::Vector4f::Zero ();

        if (fabs (normal.x ()) > 0.0001f)
        {
          normal_u.x () = - normal.y () / normal.x ();
          normal_u.y () = 1.0f;
          normal_u.z () = 0.0f;
          normal_u.normalize ();

        }
        else if (fabs (normal.y ()) > 0.0001f)
        {
          normal_u.x () = 1.0f;
          normal_u.y () = - normal.x () / normal.y ();
          normal_u.z () = 0.0f;
          normal_u.normalize ();
        }
        else
        {
          normal_u.x () = 0.0f;
          normal_u.y () = 1.0f;
          normal_u.z () = - normal.y () / normal.z ();
        }
        normal_v = normal.cross3 (normal_u);

        Eigen::Vector4f zeta_point = 2.0f * static_cast<float> (l + 1) * scale_h_ / static_cast<float> (M_) *
            (cosf (2.0f * static_cast<float> (M_PI) * static_cast<float> ((k + 1) / N_)) * normal_u +
             sinf (2.0f * static_cast<float> (M_PI) * static_cast<float> ((k + 1) / N_)) * normal_v);

        // Compute normal by using the neighbors
        Eigen::Vector4f zeta_point_plus_center = zeta_point + center_point;
        PointT zeta_point_pcl;
        zeta_point_pcl.x = zeta_point_plus_center.x (); zeta_point_pcl.y = zeta_point_plus_center.y (); zeta_point_pcl.z = zeta_point_plus_center.z ();

        tree_->radiusSearch (zeta_point_pcl, search_radius_, k_indices, k_sqr_distances);

        // Do k nearest search if there are no neighbors nearby
        if (k_indices.size () == 0)
        {
          k_indices.resize (5);
          k_sqr_distances.resize (5);
          tree_->nearestKSearch (zeta_point_pcl, 5, k_indices, k_sqr_distances);
        }

        Eigen::Vector4f average_normal = Eigen::Vector4f::Zero ();

        float average_normalization_factor = 0.0f;

        // Normals weighted by 1/squared_distances
        for (size_t nn_i = 0; nn_i < k_indices.size (); ++nn_i)
        {
          if (k_sqr_distances[nn_i] < 1e-7f)
          {
            average_normal = normals_->points[k_indices[nn_i]].getNormalVector4fMap ();
            average_normalization_factor = 1.0f;
            break;
          }
          average_normal += normals_->points[k_indices[nn_i]].getNormalVector4fMap () / k_sqr_distances[nn_i];
          average_normalization_factor += 1.0f / k_sqr_distances[nn_i];
        }
        average_normal /= average_normalization_factor;
        float s = zeta_point.dot (average_normal) / zeta_point.norm ();
        s_row[l] = s;
      }

      // do DCT on the s_matrix row-wise
      Eigen::VectorXf dct_row (M_);
      for (int m = 0; m < s_row.size (); ++m)
      {
        float Xk = 0.0f;
        for (int n = 0; n < s_row.size (); ++n)
          Xk += static_cast<float> (s_row[n] * cos (M_PI / (static_cast<double> (M_ * n) + 0.5) * static_cast<double> (k)));
        dct_row[m] = Xk;
      }
      s_row = dct_row;
      s_matrix.row (k).matrix () = dct_row;
    }

    // do DFT on the s_matrix column-wise
    Eigen::MatrixXf dft_matrix (N_, M_);
    for (size_t column_i = 0; column_i < M_; ++column_i)
    {
      Eigen::VectorXf dft_col (N_);
      for (size_t k = 0; k < N_; ++k)
      {
        float Xk_real = 0.0f, Xk_imag = 0.0f;
        for (size_t n = 0; n < N_; ++n)
        {
          Xk_real += static_cast<float> (s_matrix (n, column_i) * cos (2.0f * M_PI / static_cast<double> (N_ * k * n)));
          Xk_imag += static_cast<float> (s_matrix (n, column_i) * sin (2.0f * M_PI / static_cast<double> (N_ * k * n)));
        }
        dft_col[k] = sqrtf (Xk_real*Xk_real + Xk_imag*Xk_imag);
      }
      dft_matrix.col (column_i).matrix () = dft_col;
    }

    Eigen::MatrixXf final_matrix = dft_matrix.block (0, 0, N_prime_, M_prime_);

    PointFeature feature_point;
    for (size_t i = 0; i < N_prime_; ++i)
      for (size_t j = 0; j < M_prime_; ++j)
        feature_point.values[i*M_prime_ + j] = final_matrix (i, j);

    output.points[index_i] = feature_point;
  }
}

#define PCL_INSTANTIATE_NormalBasedSignatureEstimation(T,NT,OutT) template class PCL_EXPORTS pcl::NormalBasedSignatureEstimation<T,NT,OutT>;

#endif /* PCL_FEATURES_IMPL_NORMAL_BASED_SIGNATURE_H_ */
<|endoftext|>


<commit_before>#include "addtrainingdlg.h"
#include "ui_addtrainingdlg.h"
#include <QDebug>
#include <QSqlField>
#include <QMessageBox>

/**
 * @brief Creates a dialog for adding and editing training.
 * @param parent The parent widget.
 */
AddTrainingDlg::AddTrainingDlg(TrainingModel *model, int trainingRow, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AddTrainingDlg)
{
    ui->setupUi(this);

    connect(ui->btnAdd, SIGNAL(clicked()), this, SLOT(addTraining()));
    connect(ui->btnAddAndClose, SIGNAL(clicked()), this, SLOT(addTrainingAndClose()));
    connect(ui->btnSave, SIGNAL(clicked()), this, SLOT(saveTraining()));

    teamModel = new TeamModel;
    ui->comboBoxTeam->setModel(teamModel);
    ui->comboBoxTeam->setModelColumn(1);

    this->trainingModel = model;

    QDate currentDate = QDate::currentDate();

    int year = currentDate.year();
    int month = currentDate.month();
    if(month < 9) year--;
    startSeason = QDate::fromString("1.9."+QString::number(year), "d.M.yyyy");
    endSeason = QDate::fromString("31.8."+QString::number(year+1), "d.M.yyyy");

    if(trainingRow == -1) // Add
    {
        ui->editDate->setDate(currentDate);
        ui->btnSave->setVisible(false);
        ui->chckBoxCanceled->setVisible(false);

    }
    else // Edit
    {
        setWindowTitle(tr("Edit training"));

        QSqlRecord record = trainingModel->record(trainingRow);

        QDateTime datetime = record.field("datetime").value().toDateTime();

        ui->editDate->setDate(datetime.date());
        ui->editTime->setTime(datetime.time());
        ui->editPlace->setText(record.field("place").value().toString());

        ui->checkBoxEveryWeek->setVisible(false);
        ui->checkBoxEveryWeek->setChecked(false);
        ui->comboBoxDay->setVisible(false);
        ui->editDate->setEnabled(true);
        ui->btnAdd->setVisible(false);
        ui->btnAddAndClose->setVisible(false);
    }

    m_row = trainingRow;

    setWindowState(Qt::WindowMinimized);
}

void AddTrainingDlg::addTraining()
{
    if(!insertTrainings()) return;

    ui->checkBoxEveryWeek->setChecked(true);
    ui->editDate->setEnabled(false);
    ui->editTime->setTime(QTime::fromString("12:00", "hh:mm"));
    ui->editPlace->setText("");
}

void AddTrainingDlg::addTrainingAndClose()
{
    if(!insertTrainings()) return;

    close();
}

void AddTrainingDlg::saveTraining()
{
    if(!checkForm(tr("Edit training"))) return;

    QSqlRecord record = prepareRecords().at(0);

    trainingModel->setRecord(m_row, record);
    trainingModel->submitAll();

    close();
}

bool AddTrainingDlg::insertTrainings()
{
    if(!checkForm(tr("Add training"))) return false;

    QList<QSqlRecord> records = prepareRecords();

    if(records.size() == 0) return false;

    QList<QSqlRecord>::iterator r;
    for(r = records.begin(); r != records.end(); ++r)
    {
        if(!trainingModel->insertRecord(-1, *r))
            qDebug("err insert record");
    }

    if(!trainingModel->submitAll())
    {
        qDebug("err submit");
    }

    return true;
}

QList<QSqlRecord> AddTrainingDlg::prepareRecords()
{
    QList<QSqlRecord> records;
    int idx = ui->comboBoxTeam->currentIndex();
    int teamId = teamModel->record(idx).field("id").value().toInt();
    if(ui->checkBoxEveryWeek->isChecked())
    {
        QDateTime start = QDateTime::currentDateTime();
        start.setTime(ui->editTime->time());
        int nowDayOfWeek = start.date().dayOfWeek();
        int dayOfWeek = ui->comboBoxDay->currentIndex()+1;

        if(dayOfWeek > nowDayOfWeek)
            start = start.addDays(dayOfWeek - nowDayOfWeek);
        else if(dayOfWeek < nowDayOfWeek)
            start = start.addDays(dayOfWeek - nowDayOfWeek + 7);

        while(start.date() < endSeason)
        {
            records.append(createRecord(start, teamId));
            start = start.addDays(7);
        }
    }
    else
    {
        QDateTime datetime = ui->editDate->dateTime();
        datetime.setTime(ui->editTime->time());
        records.append(createRecord(datetime, teamId));
    }

    return records;
}

QSqlRecord AddTrainingDlg::createRecord(QDateTime datetime, int teamID)
{
    QSqlRecord record;

    QSqlField datetimeField("datetime", QVariant::Date);
    QSqlField place("place", QVariant::String);
    QSqlField canceled("canceled", QVariant::Bool);
    QSqlField teamIDField("team_id", QVariant::Int);

    datetimeField.setValue(datetime);
    place.setValue(ui->editPlace->text().trimmed());
    canceled.setValue(ui->chckBoxCanceled->isChecked());
    teamIDField.setValue(teamID);

    record.append(datetimeField);
    record.append(place);
    record.append(canceled);
    record.append(teamIDField);

    return record;
}

bool AddTrainingDlg::checkForm(QString title)
{
    if(ui->editPlace->text().trimmed() == "")
    {
        QMessageBox::information(this, title, tr("You must specified place."));
        return false;
    }
    return true;
}

/**
 * @brief Destructs the dialog.
 */
AddTrainingDlg::~AddTrainingDlg()
{
    delete ui;
}
<commit_msg>Fixed - Edit training.<commit_after>#include "addtrainingdlg.h"
#include "ui_addtrainingdlg.h"
#include <QDebug>
#include <QSqlField>
#include <QMessageBox>

/**
 * @brief Creates a dialog for adding and editing training.
 * @param parent The parent widget.
 */
AddTrainingDlg::AddTrainingDlg(TrainingModel *model, int trainingRow, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AddTrainingDlg)
{
    ui->setupUi(this);

    connect(ui->btnAdd, SIGNAL(clicked()), this, SLOT(addTraining()));
    connect(ui->btnAddAndClose, SIGNAL(clicked()), this, SLOT(addTrainingAndClose()));
    connect(ui->btnSave, SIGNAL(clicked()), this, SLOT(saveTraining()));

    teamModel = new TeamModel;
    ui->comboBoxTeam->setModel(teamModel);
    ui->comboBoxTeam->setModelColumn(1);

    this->trainingModel = model;

    QDate currentDate = QDate::currentDate();

    int year = currentDate.year();
    int month = currentDate.month();
    if(month < 9) year--;
    startSeason = QDate::fromString("1.9."+QString::number(year), "d.M.yyyy");
    endSeason = QDate::fromString("31.8."+QString::number(year+1), "d.M.yyyy");

    if(trainingRow == -1) // Add
    {
        ui->editDate->setDate(currentDate);
        ui->btnSave->setVisible(false);
        ui->chckBoxCanceled->setVisible(false);

    }
    else // Edit
    {
        setWindowTitle(tr("Edit training"));

        QSqlRecord record = trainingModel->record(trainingRow);

        QDateTime datetime = record.field("datetime").value().toDateTime();

        ui->editDate->setDate(datetime.date());
        ui->editTime->setTime(datetime.time());
        ui->editPlace->setText(record.field("place").value().toString());
        ui->chckBoxCanceled->setChecked(record.field("canceled").value().toBool());

        ui->checkBoxEveryWeek->setVisible(false);
        ui->checkBoxEveryWeek->setChecked(false);
        ui->comboBoxDay->setVisible(false);
        ui->editDate->setEnabled(true);
        ui->btnAdd->setVisible(false);
        ui->btnAddAndClose->setVisible(false);
    }

    m_row = trainingRow;

    setWindowState(Qt::WindowMinimized);
}

void AddTrainingDlg::addTraining()
{
    if(!insertTrainings()) return;

    ui->checkBoxEveryWeek->setChecked(true);
    ui->editDate->setEnabled(false);
    ui->editTime->setTime(QTime::fromString("12:00", "hh:mm"));
    ui->editPlace->setText("");
}

void AddTrainingDlg::addTrainingAndClose()
{
    if(!insertTrainings()) return;

    close();
}

void AddTrainingDlg::saveTraining()
{
    if(!checkForm(tr("Edit training"))) return;

    QSqlRecord record = prepareRecords().at(0);

    trainingModel->setRecord(m_row, record);
    trainingModel->submitAll();

    close();
}

bool AddTrainingDlg::insertTrainings()
{
    if(!checkForm(tr("Add training"))) return false;

    QList<QSqlRecord> records = prepareRecords();

    if(records.size() == 0) return false;

    QList<QSqlRecord>::iterator r;
    for(r = records.begin(); r != records.end(); ++r)
    {
        if(!trainingModel->insertRecord(-1, *r))
            qDebug("err insert record");
    }

    if(!trainingModel->submitAll())
    {
        qDebug("err submit");
    }

    return true;
}

QList<QSqlRecord> AddTrainingDlg::prepareRecords()
{
    QList<QSqlRecord> records;
    int idx = ui->comboBoxTeam->currentIndex();
    int teamId = teamModel->record(idx).field("id").value().toInt();
    if(ui->checkBoxEveryWeek->isChecked())
    {
        QDateTime start = QDateTime::currentDateTime();
        start.setTime(ui->editTime->time());
        int nowDayOfWeek = start.date().dayOfWeek();
        int dayOfWeek = ui->comboBoxDay->currentIndex()+1;

        if(dayOfWeek > nowDayOfWeek)
            start = start.addDays(dayOfWeek - nowDayOfWeek);
        else if(dayOfWeek < nowDayOfWeek)
            start = start.addDays(dayOfWeek - nowDayOfWeek + 7);

        while(start.date() < endSeason)
        {
            records.append(createRecord(start, teamId));
            start = start.addDays(7);
        }
    }
    else
    {
        QDateTime datetime = ui->editDate->dateTime();
        datetime.setTime(ui->editTime->time());
        records.append(createRecord(datetime, teamId));
    }

    return records;
}

QSqlRecord AddTrainingDlg::createRecord(QDateTime datetime, int teamID)
{
    QSqlRecord record;

    QSqlField datetimeField("datetime", QVariant::Date);
    QSqlField place("place", QVariant::String);
    QSqlField canceled("canceled", QVariant::Bool);
    QSqlField teamIDField("team_id", QVariant::Int);

    datetimeField.setValue(datetime);
    place.setValue(ui->editPlace->text().trimmed());
    canceled.setValue(ui->chckBoxCanceled->isChecked());
    teamIDField.setValue(teamID);

    record.append(datetimeField);
    record.append(place);
    record.append(canceled);
    record.append(teamIDField);

    return record;
}

bool AddTrainingDlg::checkForm(QString title)
{
    if(ui->editPlace->text().trimmed() == "")
    {
        QMessageBox::information(this, title, tr("You must specified place."));
        return false;
    }
    return true;
}

/**
 * @brief Destructs the dialog.
 */
AddTrainingDlg::~AddTrainingDlg()
{
    delete ui;
}
<|endoftext|>


<commit_before>#include "engine/blob.h"
#include "engine/command_line_parser.h"
#include "engine/crc32.h"
#include "engine/fs/disk_file_device.h"
#include "engine/fs/file_system.h"
#include "engine/fs/file_system.h"
#include "engine/fs/memory_file_device.h"
#include "engine/fs/pack_file_device.h"
#include "engine/input_system.h"
#include "engine/log.h"
#include "engine/lua_wrapper.h"
#include "engine/mt/thread.h"
#include "engine/path_utils.h"
#include "engine/profiler.h"
#include "engine/resource_manager.h"
#include "engine/resource_manager_base.h"
#include "engine/system.h"
#include "engine/timer.h"
#include "engine/debug/debug.h"
#include "editor/gizmo.h"
#include "editor/world_editor.h"
#include "engine/engine.h"
#include "engine/plugin_manager.h"
#include "renderer/pipeline.h"
#include "renderer/renderer.h"
#include "renderer/texture.h"
#include "engine/universe/universe.h"
#include <cstdio>
#include <X11/Xlib.h>

namespace Lumix
{

struct App
{
	App()
	{
		m_universe = nullptr;
		m_exit_code = 0;
		m_frame_timer = Timer::create(m_allocator);
		ASSERT(!s_instance);
		s_instance = this;
		m_pipeline = nullptr;
	}

	~App()
	{
		Timer::destroy(m_frame_timer);
		ASSERT(!m_universe);
		s_instance = nullptr;
	}

	/*
	LRESULT onMessage(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
	{
		switch (msg)
		{
			case WM_CLOSE: PostQuitMessage(0); break;
			case WM_MOVE:
			case WM_SIZE: onResize(); break;
			case WM_QUIT: m_finished = true; break;
			case WM_INPUT: handleRawInput(lparam); break;
		}
		return DefWindowProc(hwnd, msg, wparam, lparam);
	}

	static LRESULT CALLBACK msgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
	{
		if (!s_instance || !s_instance->m_pipeline) return DefWindowProc(hwnd, msg, wparam, lparam);

		return s_instance->onMessage(hwnd, msg, wparam, lparam);
	}

	void onResize()
	{
		RECT rect;
		RECT screen_rect;
		GetClientRect(m_hwnd, &rect);
		GetWindowRect(m_hwnd, &screen_rect);
		int w = rect.right - rect.left;
		int h = rect.bottom - rect.top;
		if (w > 0)
		{
			ClipCursor(&screen_rect);
			m_pipeline->setViewport(0, 0, w, h);
			Renderer* renderer =
				static_cast<Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
			renderer->resize(w, h);
		}
	}
*/

	bool createWindow()
	{
		m_display = XOpenDisplay(nullptr);
		if (!m_display) return false;

		int s = DefaultScreen(m_display);
		m_window = XCreateSimpleWindow(m_display, RootWindow(m_display, s), 10, 10, 100, 100, 1
			, BlackPixel(m_display, s), WhitePixel(m_display, s));
		XSelectInput(m_display, m_window, ExposureMask | KeyPressMask);
		XMapWindow(m_display, m_window);
		return true;
	}

	void init()
	{
		copyString(m_pipeline_path, "pipelines/app.lua");
		copyString(m_startup_script_path, "startup.lua");
		char cmd_line[1024];
		getCommandLine(cmd_line, lengthOf(cmd_line));
		CommandLineParser parser(cmd_line);
		while (parser.next())
		{
			if (parser.currentEquals("-pipeline"))
			{
				if (!parser.next()) break;

				parser.getCurrent(m_pipeline_path, lengthOf(m_pipeline_path));
			}
			else if(parser.currentEquals("-script"))
			{
				if (!parser.next()) break;

				parser.getCurrent(m_startup_script_path, lengthOf(m_startup_script_path));
			}
		}

		createWindow();

		g_log_info.getCallback().bind<outputToConsole>();
		g_log_warning.getCallback().bind<outputToConsole>();
		g_log_error.getCallback().bind<outputToConsole>();

		enableCrashReporting(false);

		m_file_system = FS::FileSystem::create(m_allocator);

		m_mem_file_device = LUMIX_NEW(m_allocator, FS::MemoryFileDevice)(m_allocator);
		m_disk_file_device = LUMIX_NEW(m_allocator, FS::DiskFileDevice)("disk", "", m_allocator);
		m_pack_file_device = LUMIX_NEW(m_allocator, FS::PackFileDevice)(m_allocator);

		m_file_system->mount(m_mem_file_device);
		m_file_system->mount(m_disk_file_device);
		m_file_system->mount(m_pack_file_device);
		m_pack_file_device->mount("data.pak");
		m_file_system->setDefaultDevice("memory:disk:pack");
		m_file_system->setSaveGameDevice("memory:disk");

		m_engine = Engine::create("", "", m_file_system, m_allocator);
		Engine::PlatformData platform_data;
		platform_data.window_handle = (void*)(uintptr_t)m_window;
		platform_data.display = m_display;
		m_engine->setPlatformData(platform_data);

		m_engine->getPluginManager().load("renderer");
		m_engine->getPluginManager().load("animation");
		m_engine->getPluginManager().load("audio");
		m_engine->getPluginManager().load("lua_script");
		m_engine->getPluginManager().load("physics");
		m_engine->getInputSystem().enable(true);
		Renderer* renderer = static_cast<Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
		m_pipeline = Pipeline::create(*renderer, Path(m_pipeline_path), "", m_engine->getAllocator());
		m_pipeline->load();

		while (m_engine->getFileSystem().hasWork())
		{
			MT::sleep(100);
			m_engine->getFileSystem().updateAsyncTransactions();
		}

		m_universe = &m_engine->createUniverse(true);
		m_pipeline->setScene((RenderScene*)m_universe->getScene(crc32("renderer")));
		m_pipeline->setViewport(0, 0, 600, 400);
		renderer->resize(600, 400);

		registerLuaAPI();

		//while (ShowCursor(false) >= 0); // TODO
		// onResize(); // TODO
	}

	void startupScriptLoaded(FS::IFile& file, bool success)
	{
		if (!success)
		{
			g_log_error.log("App") << "Could not open " << m_startup_script_path;
			return;
		}

		m_engine->runScript((const char*)file.getBuffer(), (int)file.size(), m_startup_script_path);
	}

	void registerLuaAPI()
	{
		lua_State* L = m_engine->getState();

		#define REGISTER_FUNCTION(F, name) \
			do { \
				auto* f = &LuaWrapper::wrapMethod<App, decltype(&App::F), &App::F>; \
				LuaWrapper::createSystemFunction(L, "App", name, f); \
			} while(false) \

		REGISTER_FUNCTION(loadUniverse, "loadUniverse");
		REGISTER_FUNCTION(frame, "frame");
		REGISTER_FUNCTION(exit, "exit");

		#undef REGISTER_FUNCTION

		LuaWrapper::createSystemVariable(L, "App", "instance", this);
		LuaWrapper::createSystemVariable(L, "App", "universe", m_universe);

		auto& fs = m_engine->getFileSystem();
		FS::ReadCallback cb;
		cb.bind<App, &App::startupScriptLoaded>(this);
		fs.openAsync(fs.getDefaultDevice(), Path(m_startup_script_path), FS::Mode::OPEN_AND_READ, cb);
	}

	void universeFileLoaded(FS::IFile& file, bool success)
	{
		ASSERT(success);
		if (!success) return;

		ASSERT(file.getBuffer());
		InputBlob blob(file.getBuffer(), (int)file.size());
		#pragma pack(1)
			struct Header
			{
				u32 magic;
				int version;
				u32 hash;
				u32 engine_hash;
			};
		#pragma pack()
		Header header;
		blob.read(header);
		if (crc32((const u8*)blob.getData() + sizeof(header), blob.getSize() - sizeof(header)) !=
			header.hash)
		{
			g_log_error.log("App") << "Universe corrupted";
			return;
		}
		bool deserialize_succeeded = m_engine->deserialize(*m_universe, blob);
		if (!deserialize_succeeded)
		{
			g_log_error.log("App") << "Failed to deserialize universe";
		}
	}

	void loadUniverse(const char* path)
	{
		auto& fs = m_engine->getFileSystem();
		FS::ReadCallback file_read_cb;
		file_read_cb.bind<App, &App::universeFileLoaded>(this);
		fs.openAsync(fs.getDefaultDevice(), Path(path), FS::Mode::OPEN_AND_READ, file_read_cb);
	}

	void shutdown()
	{
		m_engine->destroyUniverse(*m_universe);
		FS::FileSystem::destroy(m_file_system);
		LUMIX_DELETE(m_allocator, m_disk_file_device);
		LUMIX_DELETE(m_allocator, m_mem_file_device);
		LUMIX_DELETE(m_allocator, m_pack_file_device);
		Pipeline::destroy(m_pipeline);
		Engine::destroy(m_engine, m_allocator);
		m_engine = nullptr;
		m_pipeline = nullptr;
		m_universe = nullptr;

		XCloseDisplay(m_display);
	}

	int getExitCode() const { return m_exit_code; }

	/*
	void handleRawInput(LPARAM lParam)
	{
		UINT dwSize;
		char data[sizeof(RAWINPUT) * 10];

		GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
		if (dwSize > sizeof(data)) return;

		if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &dwSize, sizeof(RAWINPUTHEADER)) !=
			dwSize) return;

		RAWINPUT* raw = (RAWINPUT*)data;
		if (raw->header.dwType == RIM_TYPEMOUSE &&
			raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
		{
			POINT p;
			GetCursorPos(&p);
			ScreenToClient(m_hwnd, &p);
			auto& input_system = m_engine->getInputSystem();
			input_system.injectMouseXMove(float(raw->data.mouse.lLastX));
			input_system.injectMouseYMove(float(raw->data.mouse.lLastY));
		}
	}
*/

	void handleEvents()
	{
		XEvent e;
		while (XPending(m_display) > 0)
		{
			XNextEvent(m_display, &e);
			if (e.type == KeyPress) break;
		}
	}

	static void outputToConsole(const char* system, const char* message)
	{
		printf("%s: %s\n", system, message);
	}

	void exit(int exit_code)
	{
		m_finished = true;
		m_exit_code = exit_code;
	}

	void frame()
	{
		float frame_time = m_frame_timer->tick();
		m_engine->update(*m_universe);
		m_pipeline->render();
		auto* renderer = m_engine->getPluginManager().getPlugin("renderer");
		static_cast<Renderer*>(renderer)->frame(false);
		m_engine->getFileSystem().updateAsyncTransactions();
		if (frame_time < 1 / 60.0f)
		{
			PROFILE_BLOCK("sleep");
			MT::sleep(u32(1000 / 60.0f - frame_time * 1000));
		}
		handleEvents();
	}

	void run()
	{
		m_finished = false;
		while (!m_finished)
		{
			frame();
		}
	}

private:
	DefaultAllocator m_allocator;
	Engine* m_engine;
	Universe* m_universe;
	Pipeline* m_pipeline;
	FS::FileSystem* m_file_system;
	FS::MemoryFileDevice* m_mem_file_device;
	FS::DiskFileDevice* m_disk_file_device;
	FS::PackFileDevice* m_pack_file_device;
	Timer* m_frame_timer;
	bool m_finished;
	int m_exit_code;
	char m_startup_script_path[MAX_PATH_LENGTH];
	char m_pipeline_path[MAX_PATH_LENGTH];
	Display* m_display;
	Window m_window;

	static App* s_instance;
};

App* App::s_instance = nullptr;

}

int main(int argc, char* argv[])
{
	Lumix::setCommandLine(argc, argv);
	Lumix::App app;
	app.init();
	app.run();
	app.shutdown();
	return app.getExitCode();
}

<commit_msg>linux fix<commit_after>#include "engine/blob.h"
#include "engine/command_line_parser.h"
#include "engine/crc32.h"
#include "engine/fs/disk_file_device.h"
#include "engine/fs/file_system.h"
#include "engine/fs/file_system.h"
#include "engine/fs/memory_file_device.h"
#include "engine/fs/pack_file_device.h"
#include "engine/input_system.h"
#include "engine/log.h"
#include "engine/lua_wrapper.h"
#include "engine/mt/thread.h"
#include "engine/path_utils.h"
#include "engine/profiler.h"
#include "engine/resource_manager.h"
#include "engine/resource_manager_base.h"
#include "engine/system.h"
#include "engine/timer.h"
#include "engine/debug/debug.h"
#include "editor/gizmo.h"
#include "editor/world_editor.h"
#include "engine/engine.h"
#include "engine/plugin_manager.h"
#include "renderer/pipeline.h"
#include "renderer/renderer.h"
#include "renderer/texture.h"
#include "engine/universe/universe.h"
#include <cstdio>
#include <X11/Xlib.h>

namespace Lumix
{

struct App
{
	App()
	{
		m_universe = nullptr;
		m_exit_code = 0;
		m_frame_timer = Timer::create(m_allocator);
		ASSERT(!s_instance);
		s_instance = this;
		m_pipeline = nullptr;
	}

	~App()
	{
		Timer::destroy(m_frame_timer);
		ASSERT(!m_universe);
		s_instance = nullptr;
	}

	/*
	LRESULT onMessage(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
	{
		switch (msg)
		{
			case WM_CLOSE: PostQuitMessage(0); break;
			case WM_MOVE:
			case WM_SIZE: onResize(); break;
			case WM_QUIT: m_finished = true; break;
			case WM_INPUT: handleRawInput(lparam); break;
		}
		return DefWindowProc(hwnd, msg, wparam, lparam);
	}

	static LRESULT CALLBACK msgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
	{
		if (!s_instance || !s_instance->m_pipeline) return DefWindowProc(hwnd, msg, wparam, lparam);

		return s_instance->onMessage(hwnd, msg, wparam, lparam);
	}

	void onResize()
	{
		RECT rect;
		RECT screen_rect;
		GetClientRect(m_hwnd, &rect);
		GetWindowRect(m_hwnd, &screen_rect);
		int w = rect.right - rect.left;
		int h = rect.bottom - rect.top;
		if (w > 0)
		{
			ClipCursor(&screen_rect);
			m_pipeline->setViewport(0, 0, w, h);
			Renderer* renderer =
				static_cast<Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
			renderer->resize(w, h);
		}
	}
*/

	bool createWindow()
	{
		m_display = XOpenDisplay(nullptr);
		if (!m_display) return false;

		int s = DefaultScreen(m_display);
		m_window = XCreateSimpleWindow(m_display, RootWindow(m_display, s), 10, 10, 100, 100, 1
			, BlackPixel(m_display, s), WhitePixel(m_display, s));
		XSelectInput(m_display, m_window, ExposureMask | KeyPressMask);
		XMapWindow(m_display, m_window);
		return true;
	}

	void init()
	{
		copyString(m_pipeline_path, "pipelines/app.lua");
		copyString(m_startup_script_path, "startup.lua");
		char cmd_line[1024];
		getCommandLine(cmd_line, lengthOf(cmd_line));
		CommandLineParser parser(cmd_line);
		while (parser.next())
		{
			if (parser.currentEquals("-pipeline"))
			{
				if (!parser.next()) break;

				parser.getCurrent(m_pipeline_path, lengthOf(m_pipeline_path));
			}
			else if(parser.currentEquals("-script"))
			{
				if (!parser.next()) break;

				parser.getCurrent(m_startup_script_path, lengthOf(m_startup_script_path));
			}
		}

		createWindow();

		g_log_info.getCallback().bind<outputToConsole>();
		g_log_warning.getCallback().bind<outputToConsole>();
		g_log_error.getCallback().bind<outputToConsole>();

		enableCrashReporting(false);

		m_file_system = FS::FileSystem::create(m_allocator);

		m_mem_file_device = LUMIX_NEW(m_allocator, FS::MemoryFileDevice)(m_allocator);
		m_disk_file_device = LUMIX_NEW(m_allocator, FS::DiskFileDevice)("disk", "", m_allocator);
		m_pack_file_device = LUMIX_NEW(m_allocator, FS::PackFileDevice)(m_allocator);

		m_file_system->mount(m_mem_file_device);
		m_file_system->mount(m_disk_file_device);
		m_file_system->mount(m_pack_file_device);
		m_pack_file_device->mount("data.pak");
		m_file_system->setDefaultDevice("memory:disk:pack");
		m_file_system->setSaveGameDevice("memory:disk");

		m_engine = Engine::create("", "", m_file_system, m_allocator);
		Engine::PlatformData platform_data;
		platform_data.window_handle = (void*)(uintptr_t)m_window;
		platform_data.display = m_display;
		m_engine->setPlatformData(platform_data);

		m_engine->getPluginManager().load("renderer");
		m_engine->getPluginManager().load("animation");
		m_engine->getPluginManager().load("audio");
		m_engine->getPluginManager().load("lua_script");
		m_engine->getPluginManager().load("physics");
		m_engine->getInputSystem().enable(true);
		Renderer* renderer = static_cast<Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
		m_pipeline = Pipeline::create(*renderer, Path(m_pipeline_path), "APP", m_engine->getAllocator());
		m_pipeline->load();

		while (m_engine->getFileSystem().hasWork())
		{
			MT::sleep(100);
			m_engine->getFileSystem().updateAsyncTransactions();
		}

		m_universe = &m_engine->createUniverse(true);
		m_pipeline->setScene((RenderScene*)m_universe->getScene(crc32("renderer")));
		m_pipeline->resize(600, 400);
		renderer->resize(600, 400);

		registerLuaAPI();

		//while (ShowCursor(false) >= 0); // TODO
		// onResize(); // TODO
	}

	void startupScriptLoaded(FS::IFile& file, bool success)
	{
		if (!success)
		{
			g_log_error.log("App") << "Could not open " << m_startup_script_path;
			return;
		}

		m_engine->runScript((const char*)file.getBuffer(), (int)file.size(), m_startup_script_path);
	}

	void registerLuaAPI()
	{
		lua_State* L = m_engine->getState();

		#define REGISTER_FUNCTION(F, name) \
			do { \
				auto* f = &LuaWrapper::wrapMethod<App, decltype(&App::F), &App::F>; \
				LuaWrapper::createSystemFunction(L, "App", name, f); \
			} while(false) \

		REGISTER_FUNCTION(loadUniverse, "loadUniverse");
		REGISTER_FUNCTION(frame, "frame");
		REGISTER_FUNCTION(exit, "exit");

		#undef REGISTER_FUNCTION

		LuaWrapper::createSystemVariable(L, "App", "instance", this);
		LuaWrapper::createSystemVariable(L, "App", "universe", m_universe);

		auto& fs = m_engine->getFileSystem();
		FS::ReadCallback cb;
		cb.bind<App, &App::startupScriptLoaded>(this);
		fs.openAsync(fs.getDefaultDevice(), Path(m_startup_script_path), FS::Mode::OPEN_AND_READ, cb);
	}

	void universeFileLoaded(FS::IFile& file, bool success)
	{
		ASSERT(success);
		if (!success) return;

		ASSERT(file.getBuffer());
		InputBlob blob(file.getBuffer(), (int)file.size());
		#pragma pack(1)
			struct Header
			{
				u32 magic;
				int version;
				u32 hash;
				u32 engine_hash;
			};
		#pragma pack()
		Header header;
		blob.read(header);
		if (crc32((const u8*)blob.getData() + sizeof(header), blob.getSize() - sizeof(header)) !=
			header.hash)
		{
			g_log_error.log("App") << "Universe corrupted";
			return;
		}
		bool deserialize_succeeded = m_engine->deserialize(*m_universe, blob);
		if (!deserialize_succeeded)
		{
			g_log_error.log("App") << "Failed to deserialize universe";
		}
	}

	void loadUniverse(const char* path)
	{
		auto& fs = m_engine->getFileSystem();
		FS::ReadCallback file_read_cb;
		file_read_cb.bind<App, &App::universeFileLoaded>(this);
		fs.openAsync(fs.getDefaultDevice(), Path(path), FS::Mode::OPEN_AND_READ, file_read_cb);
	}

	void shutdown()
	{
		m_engine->destroyUniverse(*m_universe);
		FS::FileSystem::destroy(m_file_system);
		LUMIX_DELETE(m_allocator, m_disk_file_device);
		LUMIX_DELETE(m_allocator, m_mem_file_device);
		LUMIX_DELETE(m_allocator, m_pack_file_device);
		Pipeline::destroy(m_pipeline);
		Engine::destroy(m_engine, m_allocator);
		m_engine = nullptr;
		m_pipeline = nullptr;
		m_universe = nullptr;

		XCloseDisplay(m_display);
	}

	int getExitCode() const { return m_exit_code; }

	/*
	void handleRawInput(LPARAM lParam)
	{
		UINT dwSize;
		char data[sizeof(RAWINPUT) * 10];

		GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
		if (dwSize > sizeof(data)) return;

		if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &dwSize, sizeof(RAWINPUTHEADER)) !=
			dwSize) return;

		RAWINPUT* raw = (RAWINPUT*)data;
		if (raw->header.dwType == RIM_TYPEMOUSE &&
			raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
		{
			POINT p;
			GetCursorPos(&p);
			ScreenToClient(m_hwnd, &p);
			auto& input_system = m_engine->getInputSystem();
			input_system.injectMouseXMove(float(raw->data.mouse.lLastX));
			input_system.injectMouseYMove(float(raw->data.mouse.lLastY));
		}
	}
*/

	void handleEvents()
	{
		XEvent e;
		while (XPending(m_display) > 0)
		{
			XNextEvent(m_display, &e);
			if (e.type == KeyPress) break;
		}
	}

	static void outputToConsole(const char* system, const char* message)
	{
		printf("%s: %s\n", system, message);
	}

	void exit(int exit_code)
	{
		m_finished = true;
		m_exit_code = exit_code;
	}

	void frame()
	{
		float frame_time = m_frame_timer->tick();
		m_engine->update(*m_universe);
		m_pipeline->render();
		auto* renderer = m_engine->getPluginManager().getPlugin("renderer");
		static_cast<Renderer*>(renderer)->frame(false);
		m_engine->getFileSystem().updateAsyncTransactions();
		if (frame_time < 1 / 60.0f)
		{
			PROFILE_BLOCK("sleep");
			MT::sleep(u32(1000 / 60.0f - frame_time * 1000));
		}
		handleEvents();
	}

	void run()
	{
		m_finished = false;
		while (!m_finished)
		{
			frame();
		}
	}

private:
	DefaultAllocator m_allocator;
	Engine* m_engine;
	Universe* m_universe;
	Pipeline* m_pipeline;
	FS::FileSystem* m_file_system;
	FS::MemoryFileDevice* m_mem_file_device;
	FS::DiskFileDevice* m_disk_file_device;
	FS::PackFileDevice* m_pack_file_device;
	Timer* m_frame_timer;
	bool m_finished;
	int m_exit_code;
	char m_startup_script_path[MAX_PATH_LENGTH];
	char m_pipeline_path[MAX_PATH_LENGTH];
	Display* m_display;
	Window m_window;

	static App* s_instance;
};

App* App::s_instance = nullptr;

}

int main(int argc, char* argv[])
{
	Lumix::setCommandLine(argc, argv);
	Lumix::App app;
	app.init();
	app.run();
	app.shutdown();
	return app.getExitCode();
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ignoreIterationMark_ja_JP.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 17:28:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// prevent internal compiler error with MSVC6SP3
#include <utility>

#include <i18nutil/oneToOneMapping.hxx>
#define TRANSLITERATION_IterationMark_ja_JP
#include <transliteration_Ignore.hxx>

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace rtl;

namespace com { namespace sun { namespace star { namespace i18n {

OneToOneMappingTable_t ignoreIterationMark_ja_JP_mappingTable[] = {
    MAKE_PAIR( 0x3046, 0x3094 ),  // HIRAGANA LETTER U --> HIRAGANA LETTER VU
    MAKE_PAIR( 0x304B, 0x304C ),  // HIRAGANA LETTER KA --> HIRAGANA LETTER GA
    MAKE_PAIR( 0x304D, 0x304E ),  // HIRAGANA LETTER KI --> HIRAGANA LETTER GI
    MAKE_PAIR( 0x304F, 0x3050 ),  // HIRAGANA LETTER KU --> HIRAGANA LETTER GU
    MAKE_PAIR( 0x3051, 0x3052 ),  // HIRAGANA LETTER KE --> HIRAGANA LETTER GE
    MAKE_PAIR( 0x3053, 0x3054 ),  // HIRAGANA LETTER KO --> HIRAGANA LETTER GO
    MAKE_PAIR( 0x3055, 0x3056 ),  // HIRAGANA LETTER SA --> HIRAGANA LETTER ZA
    MAKE_PAIR( 0x3057, 0x3058 ),  // HIRAGANA LETTER SI --> HIRAGANA LETTER ZI
    MAKE_PAIR( 0x3059, 0x305A ),  // HIRAGANA LETTER SU --> HIRAGANA LETTER ZU
    MAKE_PAIR( 0x305B, 0x305C ),  // HIRAGANA LETTER SE --> HIRAGANA LETTER ZE
    MAKE_PAIR( 0x305D, 0x305E ),  // HIRAGANA LETTER SO --> HIRAGANA LETTER ZO
    MAKE_PAIR( 0x305F, 0x3060 ),  // HIRAGANA LETTER TA --> HIRAGANA LETTER DA
    MAKE_PAIR( 0x3061, 0x3062 ),  // HIRAGANA LETTER TI --> HIRAGANA LETTER DI
    MAKE_PAIR( 0x3064, 0x3065 ),  // HIRAGANA LETTER TU --> HIRAGANA LETTER DU
    MAKE_PAIR( 0x3066, 0x3067 ),  // HIRAGANA LETTER TE --> HIRAGANA LETTER DE
    MAKE_PAIR( 0x3068, 0x3069 ),  // HIRAGANA LETTER TO --> HIRAGANA LETTER DO
    MAKE_PAIR( 0x306F, 0x3070 ),  // HIRAGANA LETTER HA --> HIRAGANA LETTER BA
    MAKE_PAIR( 0x3072, 0x3073 ),  // HIRAGANA LETTER HI --> HIRAGANA LETTER BI
    MAKE_PAIR( 0x3075, 0x3076 ),  // HIRAGANA LETTER HU --> HIRAGANA LETTER BU
    MAKE_PAIR( 0x3078, 0x3079 ),  // HIRAGANA LETTER HE --> HIRAGANA LETTER BE
    MAKE_PAIR( 0x307B, 0x307C ),  // HIRAGANA LETTER HO --> HIRAGANA LETTER BO
    MAKE_PAIR( 0x309D, 0x309E ),  // HIRAGANA ITERATION MARK --> HIRAGANA VOICED ITERATION MARK
    MAKE_PAIR( 0x30A6, 0x30F4 ),  // KATAKANA LETTER U --> KATAKANA LETTER VU
    MAKE_PAIR( 0x30AB, 0x30AC ),  // KATAKANA LETTER KA --> KATAKANA LETTER GA
    MAKE_PAIR( 0x30AD, 0x30AE ),  // KATAKANA LETTER KI --> KATAKANA LETTER GI
    MAKE_PAIR( 0x30AF, 0x30B0 ),  // KATAKANA LETTER KU --> KATAKANA LETTER GU
    MAKE_PAIR( 0x30B1, 0x30B2 ),  // KATAKANA LETTER KE --> KATAKANA LETTER GE
    MAKE_PAIR( 0x30B3, 0x30B4 ),  // KATAKANA LETTER KO --> KATAKANA LETTER GO
    MAKE_PAIR( 0x30B5, 0x30B6 ),  // KATAKANA LETTER SA --> KATAKANA LETTER ZA
    MAKE_PAIR( 0x30B7, 0x30B8 ),  // KATAKANA LETTER SI --> KATAKANA LETTER ZI
    MAKE_PAIR( 0x30B9, 0x30BA ),  // KATAKANA LETTER SU --> KATAKANA LETTER ZU
    MAKE_PAIR( 0x30BB, 0x30BC ),  // KATAKANA LETTER SE --> KATAKANA LETTER ZE
    MAKE_PAIR( 0x30BD, 0x30BE ),  // KATAKANA LETTER SO --> KATAKANA LETTER ZO
    MAKE_PAIR( 0x30BF, 0x30C0 ),  // KATAKANA LETTER TA --> KATAKANA LETTER DA
    MAKE_PAIR( 0x30C1, 0x30C2 ),  // KATAKANA LETTER TI --> KATAKANA LETTER DI
    MAKE_PAIR( 0x30C4, 0x30C5 ),  // KATAKANA LETTER TU --> KATAKANA LETTER DU
    MAKE_PAIR( 0x30C6, 0x30C7 ),  // KATAKANA LETTER TE --> KATAKANA LETTER DE
    MAKE_PAIR( 0x30C8, 0x30C9 ),  // KATAKANA LETTER TO --> KATAKANA LETTER DO
    MAKE_PAIR( 0x30CF, 0x30D0 ),  // KATAKANA LETTER HA --> KATAKANA LETTER BA
    MAKE_PAIR( 0x30D2, 0x30D3 ),  // KATAKANA LETTER HI --> KATAKANA LETTER BI
    MAKE_PAIR( 0x30D5, 0x30D6 ),  // KATAKANA LETTER HU --> KATAKANA LETTER BU
    MAKE_PAIR( 0x30D8, 0x30D9 ),  // KATAKANA LETTER HE --> KATAKANA LETTER BE
    MAKE_PAIR( 0x30DB, 0x30DC ),  // KATAKANA LETTER HO --> KATAKANA LETTER BO
    MAKE_PAIR( 0x30EF, 0x30F7 ),  // KATAKANA LETTER WA --> KATAKANA LETTER VA
    MAKE_PAIR( 0x30F0, 0x30F8 ),  // KATAKANA LETTER WI --> KATAKANA LETTER VI
    MAKE_PAIR( 0x30F1, 0x30F9 ),  // KATAKANA LETTER WE --> KATAKANA LETTER VE
    MAKE_PAIR( 0x30F2, 0x30FA ),  // KATAKANA LETTER WO --> KATAKANA LETTER VO
    MAKE_PAIR( 0x30FD, 0x30FE )   // KATAKANA ITERATION MARK --> KATAKANA VOICED ITERATION MARK
};

OUString SAL_CALL
ignoreIterationMark_ja_JP::folding( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, Sequence< sal_Int32 >& offset )
  throw(RuntimeException)
{
    oneToOneMapping table(ignoreIterationMark_ja_JP_mappingTable, sizeof(ignoreIterationMark_ja_JP_mappingTable));

    // Create a string buffer which can hold nCount + 1 characters.
    // The reference count is 0 now.
    rtl_uString * newStr = x_rtl_uString_new_WithLength( nCount ); // defined in x_rtl_ustring.h
    sal_Unicode * dst = newStr->buffer;
    const sal_Unicode * src = inStr.getStr() + startPos;

    sal_Int32 * p = 0;
    sal_Int32 position = 0;
    if (useOffset) {
        // Allocate nCount length to offset argument.
        offset.realloc( nCount );
        p = offset.getArray();
        position = startPos;
    }

    //
    sal_Unicode previousChar = *src ++;
    sal_Unicode currentChar;

    // Conversion
    while (-- nCount > 0) {
        currentChar = *src ++;

        switch ( currentChar ) {
            case 0x30fd: // KATAKANA ITERATION MARK
            case 0x309d: // HIRAGANA ITERATION MARK
            case 0x3005: // IDEOGRAPHIC ITERATION MARK
                currentChar = previousChar;
                break;
            case 0x30fe: // KATAKANA VOICED ITERATION MARK
            case 0x309e: // HIRAGANA VOICED ITERATION MARK
                currentChar = table[ previousChar ];
                break;
        }
        if (useOffset)
            *p ++ = position ++;
        *dst ++ = previousChar;
        previousChar = currentChar;
    }

    if (nCount == 0) {
        if (useOffset)
            *p = position;
        *dst ++ = previousChar;
    }

    *dst = (sal_Unicode) 0;

    newStr->length = sal_Int32(dst - newStr->buffer);
    if (useOffset)
        offset.realloc(newStr->length);
    return OUString( newStr ); // defined in rtl/usrting. The reference count is increased from 0 to 1.

}

} } } }
<commit_msg>INTEGRATION: CWS warnings01 (1.9.14); FILE MERGED 2005/11/09 20:22:03 pl 1.9.14.1: #i53898# removed warnings<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ignoreIterationMark_ja_JP.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 04:49:41 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// prevent internal compiler error with MSVC6SP3
#include <utility>

#include <i18nutil/oneToOneMapping.hxx>
#define TRANSLITERATION_IterationMark_ja_JP
#include <transliteration_Ignore.hxx>

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace rtl;

namespace com { namespace sun { namespace star { namespace i18n {

OneToOneMappingTable_t ignoreIterationMark_ja_JP_mappingTable[] = {
    MAKE_PAIR( 0x3046, 0x3094 ),  // HIRAGANA LETTER U --> HIRAGANA LETTER VU
    MAKE_PAIR( 0x304B, 0x304C ),  // HIRAGANA LETTER KA --> HIRAGANA LETTER GA
    MAKE_PAIR( 0x304D, 0x304E ),  // HIRAGANA LETTER KI --> HIRAGANA LETTER GI
    MAKE_PAIR( 0x304F, 0x3050 ),  // HIRAGANA LETTER KU --> HIRAGANA LETTER GU
    MAKE_PAIR( 0x3051, 0x3052 ),  // HIRAGANA LETTER KE --> HIRAGANA LETTER GE
    MAKE_PAIR( 0x3053, 0x3054 ),  // HIRAGANA LETTER KO --> HIRAGANA LETTER GO
    MAKE_PAIR( 0x3055, 0x3056 ),  // HIRAGANA LETTER SA --> HIRAGANA LETTER ZA
    MAKE_PAIR( 0x3057, 0x3058 ),  // HIRAGANA LETTER SI --> HIRAGANA LETTER ZI
    MAKE_PAIR( 0x3059, 0x305A ),  // HIRAGANA LETTER SU --> HIRAGANA LETTER ZU
    MAKE_PAIR( 0x305B, 0x305C ),  // HIRAGANA LETTER SE --> HIRAGANA LETTER ZE
    MAKE_PAIR( 0x305D, 0x305E ),  // HIRAGANA LETTER SO --> HIRAGANA LETTER ZO
    MAKE_PAIR( 0x305F, 0x3060 ),  // HIRAGANA LETTER TA --> HIRAGANA LETTER DA
    MAKE_PAIR( 0x3061, 0x3062 ),  // HIRAGANA LETTER TI --> HIRAGANA LETTER DI
    MAKE_PAIR( 0x3064, 0x3065 ),  // HIRAGANA LETTER TU --> HIRAGANA LETTER DU
    MAKE_PAIR( 0x3066, 0x3067 ),  // HIRAGANA LETTER TE --> HIRAGANA LETTER DE
    MAKE_PAIR( 0x3068, 0x3069 ),  // HIRAGANA LETTER TO --> HIRAGANA LETTER DO
    MAKE_PAIR( 0x306F, 0x3070 ),  // HIRAGANA LETTER HA --> HIRAGANA LETTER BA
    MAKE_PAIR( 0x3072, 0x3073 ),  // HIRAGANA LETTER HI --> HIRAGANA LETTER BI
    MAKE_PAIR( 0x3075, 0x3076 ),  // HIRAGANA LETTER HU --> HIRAGANA LETTER BU
    MAKE_PAIR( 0x3078, 0x3079 ),  // HIRAGANA LETTER HE --> HIRAGANA LETTER BE
    MAKE_PAIR( 0x307B, 0x307C ),  // HIRAGANA LETTER HO --> HIRAGANA LETTER BO
    MAKE_PAIR( 0x309D, 0x309E ),  // HIRAGANA ITERATION MARK --> HIRAGANA VOICED ITERATION MARK
    MAKE_PAIR( 0x30A6, 0x30F4 ),  // KATAKANA LETTER U --> KATAKANA LETTER VU
    MAKE_PAIR( 0x30AB, 0x30AC ),  // KATAKANA LETTER KA --> KATAKANA LETTER GA
    MAKE_PAIR( 0x30AD, 0x30AE ),  // KATAKANA LETTER KI --> KATAKANA LETTER GI
    MAKE_PAIR( 0x30AF, 0x30B0 ),  // KATAKANA LETTER KU --> KATAKANA LETTER GU
    MAKE_PAIR( 0x30B1, 0x30B2 ),  // KATAKANA LETTER KE --> KATAKANA LETTER GE
    MAKE_PAIR( 0x30B3, 0x30B4 ),  // KATAKANA LETTER KO --> KATAKANA LETTER GO
    MAKE_PAIR( 0x30B5, 0x30B6 ),  // KATAKANA LETTER SA --> KATAKANA LETTER ZA
    MAKE_PAIR( 0x30B7, 0x30B8 ),  // KATAKANA LETTER SI --> KATAKANA LETTER ZI
    MAKE_PAIR( 0x30B9, 0x30BA ),  // KATAKANA LETTER SU --> KATAKANA LETTER ZU
    MAKE_PAIR( 0x30BB, 0x30BC ),  // KATAKANA LETTER SE --> KATAKANA LETTER ZE
    MAKE_PAIR( 0x30BD, 0x30BE ),  // KATAKANA LETTER SO --> KATAKANA LETTER ZO
    MAKE_PAIR( 0x30BF, 0x30C0 ),  // KATAKANA LETTER TA --> KATAKANA LETTER DA
    MAKE_PAIR( 0x30C1, 0x30C2 ),  // KATAKANA LETTER TI --> KATAKANA LETTER DI
    MAKE_PAIR( 0x30C4, 0x30C5 ),  // KATAKANA LETTER TU --> KATAKANA LETTER DU
    MAKE_PAIR( 0x30C6, 0x30C7 ),  // KATAKANA LETTER TE --> KATAKANA LETTER DE
    MAKE_PAIR( 0x30C8, 0x30C9 ),  // KATAKANA LETTER TO --> KATAKANA LETTER DO
    MAKE_PAIR( 0x30CF, 0x30D0 ),  // KATAKANA LETTER HA --> KATAKANA LETTER BA
    MAKE_PAIR( 0x30D2, 0x30D3 ),  // KATAKANA LETTER HI --> KATAKANA LETTER BI
    MAKE_PAIR( 0x30D5, 0x30D6 ),  // KATAKANA LETTER HU --> KATAKANA LETTER BU
    MAKE_PAIR( 0x30D8, 0x30D9 ),  // KATAKANA LETTER HE --> KATAKANA LETTER BE
    MAKE_PAIR( 0x30DB, 0x30DC ),  // KATAKANA LETTER HO --> KATAKANA LETTER BO
    MAKE_PAIR( 0x30EF, 0x30F7 ),  // KATAKANA LETTER WA --> KATAKANA LETTER VA
    MAKE_PAIR( 0x30F0, 0x30F8 ),  // KATAKANA LETTER WI --> KATAKANA LETTER VI
    MAKE_PAIR( 0x30F1, 0x30F9 ),  // KATAKANA LETTER WE --> KATAKANA LETTER VE
    MAKE_PAIR( 0x30F2, 0x30FA ),  // KATAKANA LETTER WO --> KATAKANA LETTER VO
    MAKE_PAIR( 0x30FD, 0x30FE )   // KATAKANA ITERATION MARK --> KATAKANA VOICED ITERATION MARK
};

OUString SAL_CALL
ignoreIterationMark_ja_JP::folding( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, Sequence< sal_Int32 >& offset )
  throw(RuntimeException)
{
    oneToOneMapping aTable(ignoreIterationMark_ja_JP_mappingTable, sizeof(ignoreIterationMark_ja_JP_mappingTable));

    // Create a string buffer which can hold nCount + 1 characters.
    // The reference count is 0 now.
    rtl_uString * newStr = x_rtl_uString_new_WithLength( nCount ); // defined in x_rtl_ustring.h
    sal_Unicode * dst = newStr->buffer;
    const sal_Unicode * src = inStr.getStr() + startPos;

    sal_Int32 * p = 0;
    sal_Int32 position = 0;
    if (useOffset) {
        // Allocate nCount length to offset argument.
        offset.realloc( nCount );
        p = offset.getArray();
        position = startPos;
    }

    //
    sal_Unicode previousChar = *src ++;
    sal_Unicode currentChar;

    // Conversion
    while (-- nCount > 0) {
        currentChar = *src ++;

        switch ( currentChar ) {
            case 0x30fd: // KATAKANA ITERATION MARK
            case 0x309d: // HIRAGANA ITERATION MARK
            case 0x3005: // IDEOGRAPHIC ITERATION MARK
                currentChar = previousChar;
                break;
            case 0x30fe: // KATAKANA VOICED ITERATION MARK
            case 0x309e: // HIRAGANA VOICED ITERATION MARK
                currentChar = aTable[ previousChar ];
                break;
        }
        if (useOffset)
            *p ++ = position ++;
        *dst ++ = previousChar;
        previousChar = currentChar;
    }

    if (nCount == 0) {
        if (useOffset)
            *p = position;
        *dst ++ = previousChar;
    }

    *dst = (sal_Unicode) 0;

    newStr->length = sal_Int32(dst - newStr->buffer);
    if (useOffset)
        offset.realloc(newStr->length);
    return OUString( newStr ); // defined in rtl/usrting. The reference count is increased from 0 to 1.

}

} } } }
<|endoftext|>


<commit_before>// Copyright 2015 Open Source Robotics Foundation, 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
//
// 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.

#ifndef IMAGE_PIPELINE__IMAGE_VIEW_NODE_HPP_
#define IMAGE_PIPELINE__IMAGE_VIEW_NODE_HPP_

#include <sstream>
#include <string>

#include "opencv2/highgui/highgui.hpp"
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"

#include "common.hpp"

// Node which receives sensor_msgs/Image messages and renders them using OpenCV.
class ImageViewNode : public rclcpp::Node
{
public:
  explicit ImageViewNode(
    const std::string & input, const std::string & node_name = "image_view_node",
    bool watermark = true)
  : Node(node_name, rclcpp::NodeOptions().use_intra_process_comms(true))
  {
    // Create a subscription on the input topic.
    sub_ = this->create_subscription<sensor_msgs::msg::Image>(
      input,
      rclcpp::SensorDataQoS(),
      [node_name, watermark](const sensor_msgs::msg::Image::SharedPtr msg) {
        // Create a cv::Mat from the image message (without copying).
        cv::Mat cv_mat(
          msg->height, msg->width,
          encoding2mat_type(msg->encoding),
          msg->data.data());
        if (watermark) {
          // Annotate with the pid and pointer address.
          std::stringstream ss;
          ss << "pid: " << GETPID() << ", ptr: " << msg.get();
          draw_on_image(cv_mat, ss.str(), 60);
        }
        // Show the image.
        cv::Mat c_mat = cv_mat;
        cv::imshow(node_name.c_str(), c_mat);
        char key = cv::waitKey(1);    // Look for key presses.
        if (key == 27 /* ESC */ || key == 'q') {
          rclcpp::shutdown();
        }
        if (key == ' ') {    // If <space> then pause until another <space>.
          key = '\0';
          while (key != ' ') {
            key = cv::waitKey(1);
          }
        }
      });
  }

private:
  rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr sub_;

  cv::VideoCapture cap_;
  cv::Mat frame_;
};

#endif  // IMAGE_PIPELINE__IMAGE_VIEW_NODE_HPP_
<commit_msg>allow ESC/q/sigint to exit demo (#345)<commit_after>// Copyright 2015 Open Source Robotics Foundation, 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
//
// 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.

#ifndef IMAGE_PIPELINE__IMAGE_VIEW_NODE_HPP_
#define IMAGE_PIPELINE__IMAGE_VIEW_NODE_HPP_

#include <sstream>
#include <string>

#include "opencv2/highgui/highgui.hpp"
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"

#include "common.hpp"

// Node which receives sensor_msgs/Image messages and renders them using OpenCV.
class ImageViewNode : public rclcpp::Node
{
public:
  explicit ImageViewNode(
    const std::string & input, const std::string & node_name = "image_view_node",
    bool watermark = true)
  : Node(node_name, rclcpp::NodeOptions().use_intra_process_comms(true))
  {
    // Create a subscription on the input topic.
    sub_ = this->create_subscription<sensor_msgs::msg::Image>(
      input,
      rclcpp::SensorDataQoS(),
      [node_name, watermark](const sensor_msgs::msg::Image::SharedPtr msg) {
        // Create a cv::Mat from the image message (without copying).
        cv::Mat cv_mat(
          msg->height, msg->width,
          encoding2mat_type(msg->encoding),
          msg->data.data());
        if (watermark) {
          // Annotate with the pid and pointer address.
          std::stringstream ss;
          ss << "pid: " << GETPID() << ", ptr: " << msg.get();
          draw_on_image(cv_mat, ss.str(), 60);
        }
        // Show the image.
        cv::Mat c_mat = cv_mat;
        cv::imshow(node_name.c_str(), c_mat);
        char key = cv::waitKey(1);    // Look for key presses.
        if (key == 27 /* ESC */ || key == 'q') {
          rclcpp::shutdown();
        }
        if (key == ' ') {    // If <space> then pause until another <space>.
          key = '\0';
          while (key != ' ') {
            key = cv::waitKey(1);
            if (key == 27 /* ESC */ || key == 'q') {
              rclcpp::shutdown();
            }
            if (!rclcpp::ok()) {
              break;
            }
          }
        }
      });
  }

private:
  rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr sub_;

  cv::VideoCapture cap_;
  cv::Mat frame_;
};

#endif  // IMAGE_PIPELINE__IMAGE_VIEW_NODE_HPP_
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2018 ARM Limited
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright 2015 LabWare
 * Copyright 2014 Google, Inc.
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __REMOTE_GDB_HH__
#define __REMOTE_GDB_HH__

#include <sys/signal.h>

#include <exception>
#include <map>
#include <string>

#include "arch/types.hh"
#include "base/intmath.hh"
#include "base/pollevent.hh"
#include "base/socket.hh"
#include "cpu/pc_event.hh"

class System;
class ThreadContext;

class BaseRemoteGDB;
class HardBreakpoint;

/**
 * Concrete subclasses of this abstract class represent how the
 * register values are transmitted on the wire.  Usually each
 * architecture should define one subclass, but there can be more
 * if there is more than one possible wire format.  For example,
 * ARM defines both AArch32GdbRegCache and AArch64GdbRegCache.
 */
class BaseGdbRegCache
{
  public:

    /**
     * Return the pointer to the raw bytes buffer containing the
     * register values.  Each byte of this buffer is literally
     * encoded as two hex digits in the g or G RSP packet.
     */
    virtual char *data() const = 0;

    /**
     * Return the size of the raw buffer, in bytes
     * (i.e., half of the number of digits in the g/G packet).
     */
    virtual size_t size() const = 0;

    /**
     * Fill the raw buffer from the registers in the ThreadContext.
     */
    virtual void getRegs(ThreadContext*) = 0;

    /**
     * Set the ThreadContext's registers from the values
     * in the raw buffer.
     */
    virtual void setRegs(ThreadContext*) const = 0;

    /**
     * Return the name to use in places like DPRINTF.
     * Having each concrete superclass redefine this member
     * is useful in situations where the class of the regCache
     * can change on the fly.
     */
    virtual const std::string name() const = 0;

    BaseGdbRegCache(BaseRemoteGDB *g) : gdb(g)
    {}
    virtual ~BaseGdbRegCache()
    {}

  protected:
    BaseRemoteGDB *gdb;
};

class BaseRemoteGDB
{
    friend class HardBreakpoint;
  public:

    /*
     * Interface to other parts of the simulator.
     */
    BaseRemoteGDB(System *system, ThreadContext *context, int _port);
    virtual ~BaseRemoteGDB();

    std::string name();

    void listen();
    void connect();

    int port() const;

    void attach(int fd);
    void detach();
    bool isAttached() { return attached; }

    void replaceThreadContext(ThreadContext *_tc) { tc = _tc; }

    bool trap(int type);
    bool breakpoint() { return trap(SIGTRAP); }

  private:
    /*
     * Connection to the external GDB.
     */
    void incomingData(int revent);
    void connectWrapper(int revent) { connect(); }

    template <void (BaseRemoteGDB::*F)(int revent)>
    class SocketEvent : public PollEvent
    {
      protected:
        BaseRemoteGDB *gdb;

      public:
        SocketEvent(BaseRemoteGDB *gdb, int fd, int e) :
            PollEvent(fd, e), gdb(gdb)
        {}

        void process(int revent) { (gdb->*F)(revent); }
    };

    typedef SocketEvent<&BaseRemoteGDB::connectWrapper> ConnectEvent;
    typedef SocketEvent<&BaseRemoteGDB::incomingData> DataEvent;

    friend ConnectEvent;
    friend DataEvent;

    ConnectEvent *connectEvent;
    DataEvent *dataEvent;

    ListenSocket listener;
    int _port;

    // The socket commands come in through.
    int fd;

    // Transfer data to/from GDB.
    uint8_t getbyte();
    void putbyte(uint8_t b);

    void recv(std::vector<char> &bp);
    void send(const char *data);

    /*
     * Simulator side debugger state.
     */
    bool active;
    bool attached;

    System *sys;
    ThreadContext *tc;

    BaseGdbRegCache *regCachePtr;

    class TrapEvent : public Event
    {
      protected:
        int _type;
        BaseRemoteGDB *gdb;

      public:
        TrapEvent(BaseRemoteGDB *g) : gdb(g)
        {}

        void type(int t) { _type = t; }
        void process() { gdb->trap(_type); }
    } trapEvent;

    /*
     * The interface to the simulated system.
     */
    // Machine memory.
    bool read(Addr addr, size_t size, char *data);
    bool write(Addr addr, size_t size, const char *data);

    template <class T> T read(Addr addr);
    template <class T> void write(Addr addr, T data);

    // Single step.
    void singleStep();
    EventWrapper<BaseRemoteGDB, &BaseRemoteGDB::singleStep> singleStepEvent;

    void clearSingleStep();
    void setSingleStep();

    /// Schedule an event which will be triggered "delta" instructions later.
    void scheduleInstCommitEvent(Event *ev, int delta);
    /// Deschedule an instruction count based event.
    void descheduleInstCommitEvent(Event *ev);

    // Breakpoints.
    void insertSoftBreak(Addr addr, size_t len);
    void removeSoftBreak(Addr addr, size_t len);
    void insertHardBreak(Addr addr, size_t len);
    void removeHardBreak(Addr addr, size_t len);

    void clearTempBreakpoint(Addr &bkpt);
    void setTempBreakpoint(Addr bkpt);

    /*
     * GDB commands.
     */
    struct GdbCommand
    {
      public:
        struct Context
        {
            const GdbCommand *cmd;
            char cmd_byte;
            int type;
            char *data;
            int len;
        };

        typedef bool (BaseRemoteGDB::*Func)(Context &ctx);

        const char * const name;
        const Func func;

        GdbCommand(const char *_name, Func _func) : name(_name), func(_func) {}
    };

    static std::map<char, GdbCommand> command_map;

    bool cmd_unsupported(GdbCommand::Context &ctx);

    bool cmd_signal(GdbCommand::Context &ctx);
    bool cmd_cont(GdbCommand::Context &ctx);
    bool cmd_async_cont(GdbCommand::Context &ctx);
    bool cmd_detach(GdbCommand::Context &ctx);
    bool cmd_reg_r(GdbCommand::Context &ctx);
    bool cmd_reg_w(GdbCommand::Context &ctx);
    bool cmd_set_thread(GdbCommand::Context &ctx);
    bool cmd_mem_r(GdbCommand::Context &ctx);
    bool cmd_mem_w(GdbCommand::Context &ctx);
    bool cmd_query_var(GdbCommand::Context &ctx);
    bool cmd_step(GdbCommand::Context &ctx);
    bool cmd_async_step(GdbCommand::Context &ctx);
    bool cmd_clr_hw_bkpt(GdbCommand::Context &ctx);
    bool cmd_set_hw_bkpt(GdbCommand::Context &ctx);

  protected:
    ThreadContext *context() { return tc; }
    System *system() { return sys; }

    void encodeBinaryData(const std::string &unencoded,
            std::string &encoded) const;

    void encodeXferResponse(const std::string &unencoded,
        std::string &encoded, size_t offset, size_t unencoded_length) const;

    // To be implemented by subclasses.
    virtual bool checkBpLen(size_t len);

    virtual BaseGdbRegCache *gdbRegs() = 0;

    virtual bool acc(Addr addr, size_t len) = 0;

    virtual std::vector<std::string> availableFeatures() const;

    /**
     * Get an XML target description.
     *
     * @param[in] annex the XML filename
     * @param[out] output set to the decoded XML
     * @return true if the given annex was found
     */
    virtual bool getXferFeaturesRead(const std::string &annex,
            std::string &output);
};

template <class T>
inline T
BaseRemoteGDB::read(Addr addr)
{
    T temp;
    read(addr, sizeof(T), (char *)&temp);
    return temp;
}

template <class T>
inline void
BaseRemoteGDB::write(Addr addr, T data)
{
    write(addr, sizeof(T), (const char *)&data);
}

#endif /* __REMOTE_GDB_H__ */
<commit_msg>base: Tag API methods in remote_gdb.hh<commit_after>/*
 * Copyright (c) 2018 ARM Limited
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright 2015 LabWare
 * Copyright 2014 Google, Inc.
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __REMOTE_GDB_HH__
#define __REMOTE_GDB_HH__

#include <sys/signal.h>

#include <exception>
#include <map>
#include <string>

#include "arch/types.hh"
#include "base/intmath.hh"
#include "base/pollevent.hh"
#include "base/socket.hh"
#include "cpu/pc_event.hh"

class System;
class ThreadContext;

class BaseRemoteGDB;
class HardBreakpoint;

/**
 * Concrete subclasses of this abstract class represent how the
 * register values are transmitted on the wire.  Usually each
 * architecture should define one subclass, but there can be more
 * if there is more than one possible wire format.  For example,
 * ARM defines both AArch32GdbRegCache and AArch64GdbRegCache.
 */
class BaseGdbRegCache
{
  public:

    /**
     * Return the pointer to the raw bytes buffer containing the
     * register values.  Each byte of this buffer is literally
     * encoded as two hex digits in the g or G RSP packet.
     *
     * @ingroup api_remote_gdb
     */
    virtual char *data() const = 0;

    /**
     * Return the size of the raw buffer, in bytes
     * (i.e., half of the number of digits in the g/G packet).
     *
     * @ingroup api_remote_gdb
     */
    virtual size_t size() const = 0;

    /**
     * Fill the raw buffer from the registers in the ThreadContext.
     *
     * @ingroup api_remote_gdb
     */
    virtual void getRegs(ThreadContext*) = 0;

    /**
     * Set the ThreadContext's registers from the values
     * in the raw buffer.
     *
     * @ingroup api_remote_gdb
     */
    virtual void setRegs(ThreadContext*) const = 0;

    /**
     * Return the name to use in places like DPRINTF.
     * Having each concrete superclass redefine this member
     * is useful in situations where the class of the regCache
     * can change on the fly.
     *
     * @ingroup api_remote_gdb
     */
    virtual const std::string name() const = 0;

    /**
     * @ingroup api_remote_gdb
     */
    BaseGdbRegCache(BaseRemoteGDB *g) : gdb(g)
    {}
    virtual ~BaseGdbRegCache()
    {}

  protected:
    BaseRemoteGDB *gdb;
};

class BaseRemoteGDB
{
    friend class HardBreakpoint;
  public:

    /**
     * @ingroup api_remote_gdb
     * @{
     */

    /**
     * Interface to other parts of the simulator.
     */
    BaseRemoteGDB(System *system, ThreadContext *context, int _port);
    virtual ~BaseRemoteGDB();

    std::string name();

    void listen();
    void connect();

    int port() const;

    void attach(int fd);
    void detach();
    bool isAttached() { return attached; }

    void replaceThreadContext(ThreadContext *_tc) { tc = _tc; }

    bool trap(int type);
    bool breakpoint() { return trap(SIGTRAP); }

    /** @} */ // end of api_remote_gdb

  private:
    /*
     * Connection to the external GDB.
     */
    void incomingData(int revent);
    void connectWrapper(int revent) { connect(); }

    template <void (BaseRemoteGDB::*F)(int revent)>
    class SocketEvent : public PollEvent
    {
      protected:
        BaseRemoteGDB *gdb;

      public:
        SocketEvent(BaseRemoteGDB *gdb, int fd, int e) :
            PollEvent(fd, e), gdb(gdb)
        {}

        void process(int revent) { (gdb->*F)(revent); }
    };

    typedef SocketEvent<&BaseRemoteGDB::connectWrapper> ConnectEvent;
    typedef SocketEvent<&BaseRemoteGDB::incomingData> DataEvent;

    friend ConnectEvent;
    friend DataEvent;

    ConnectEvent *connectEvent;
    DataEvent *dataEvent;

    ListenSocket listener;
    int _port;

    // The socket commands come in through.
    int fd;

    // Transfer data to/from GDB.
    uint8_t getbyte();
    void putbyte(uint8_t b);

    void recv(std::vector<char> &bp);
    void send(const char *data);

    /*
     * Simulator side debugger state.
     */
    bool active;
    bool attached;

    System *sys;
    ThreadContext *tc;

    BaseGdbRegCache *regCachePtr;

    class TrapEvent : public Event
    {
      protected:
        int _type;
        BaseRemoteGDB *gdb;

      public:
        TrapEvent(BaseRemoteGDB *g) : gdb(g)
        {}

        void type(int t) { _type = t; }
        void process() { gdb->trap(_type); }
    } trapEvent;

    /*
     * The interface to the simulated system.
     */
    // Machine memory.
    bool read(Addr addr, size_t size, char *data);
    bool write(Addr addr, size_t size, const char *data);

    template <class T> T read(Addr addr);
    template <class T> void write(Addr addr, T data);

    // Single step.
    void singleStep();
    EventWrapper<BaseRemoteGDB, &BaseRemoteGDB::singleStep> singleStepEvent;

    void clearSingleStep();
    void setSingleStep();

    /// Schedule an event which will be triggered "delta" instructions later.
    void scheduleInstCommitEvent(Event *ev, int delta);
    /// Deschedule an instruction count based event.
    void descheduleInstCommitEvent(Event *ev);

    // Breakpoints.
    void insertSoftBreak(Addr addr, size_t len);
    void removeSoftBreak(Addr addr, size_t len);
    void insertHardBreak(Addr addr, size_t len);
    void removeHardBreak(Addr addr, size_t len);

    void clearTempBreakpoint(Addr &bkpt);
    void setTempBreakpoint(Addr bkpt);

    /*
     * GDB commands.
     */
    struct GdbCommand
    {
      public:
        struct Context
        {
            const GdbCommand *cmd;
            char cmd_byte;
            int type;
            char *data;
            int len;
        };

        typedef bool (BaseRemoteGDB::*Func)(Context &ctx);

        const char * const name;
        const Func func;

        GdbCommand(const char *_name, Func _func) : name(_name), func(_func) {}
    };

    static std::map<char, GdbCommand> command_map;

    bool cmd_unsupported(GdbCommand::Context &ctx);

    bool cmd_signal(GdbCommand::Context &ctx);
    bool cmd_cont(GdbCommand::Context &ctx);
    bool cmd_async_cont(GdbCommand::Context &ctx);
    bool cmd_detach(GdbCommand::Context &ctx);
    bool cmd_reg_r(GdbCommand::Context &ctx);
    bool cmd_reg_w(GdbCommand::Context &ctx);
    bool cmd_set_thread(GdbCommand::Context &ctx);
    bool cmd_mem_r(GdbCommand::Context &ctx);
    bool cmd_mem_w(GdbCommand::Context &ctx);
    bool cmd_query_var(GdbCommand::Context &ctx);
    bool cmd_step(GdbCommand::Context &ctx);
    bool cmd_async_step(GdbCommand::Context &ctx);
    bool cmd_clr_hw_bkpt(GdbCommand::Context &ctx);
    bool cmd_set_hw_bkpt(GdbCommand::Context &ctx);

  protected:
    ThreadContext *context() { return tc; }
    System *system() { return sys; }

    void encodeBinaryData(const std::string &unencoded,
            std::string &encoded) const;

    void encodeXferResponse(const std::string &unencoded,
        std::string &encoded, size_t offset, size_t unencoded_length) const;

    // To be implemented by subclasses.
    virtual bool checkBpLen(size_t len);

    virtual BaseGdbRegCache *gdbRegs() = 0;

    virtual bool acc(Addr addr, size_t len) = 0;

    virtual std::vector<std::string> availableFeatures() const;

    /**
     * Get an XML target description.
     *
     * @param[in] annex the XML filename
     * @param[out] output set to the decoded XML
     * @return true if the given annex was found
     */
    virtual bool getXferFeaturesRead(const std::string &annex,
            std::string &output);
};

template <class T>
inline T
BaseRemoteGDB::read(Addr addr)
{
    T temp;
    read(addr, sizeof(T), (char *)&temp);
    return temp;
}

template <class T>
inline void
BaseRemoteGDB::write(Addr addr, T data)
{
    write(addr, sizeof(T), (const char *)&data);
}

#endif /* __REMOTE_GDB_H__ */
<|endoftext|>