<commit_before>#include "audiocapturefilter.h"

#include "audiocapturedevice.h"
#include "statisticsinterface.h"

#include "common.h"

#include <QAudioInput>
#include <QDebug>
#include <QTime>
#include <QSettings>
#include <QRegularExpression>

const int AUDIO_BUFFER_SIZE = 65536;

AudioCaptureFilter::AudioCaptureFilter(QString id, QAudioFormat format, StatisticsInterface *stats) :
  Filter(id, "Audio_Capture", stats, NONE, RAWAUDIO),
  deviceInfo_(),
  device_(nullptr),
  format_(format),
  audioInput_(nullptr),
  input_(nullptr),
  buffer_(AUDIO_BUFFER_SIZE, 0)
{}

AudioCaptureFilter::~AudioCaptureFilter(){}

bool AudioCaptureFilter::init()
{
  printNormal(this, "Initializing audio capture filter.");

  QList<QAudioDeviceInfo> microphones = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);

  if (microphones.empty())
  {
    printWarning(this, "No microphone detected!");
    return false;
  }

  QSettings settings("kvazzup.ini", QSettings::IniFormat);
  QString deviceName = settings.value("audio/Device").toString();
  int deviceID = settings.value("audio/DeviceID").toInt();

  if (deviceID < microphones.size())
  {
    QString parsedName = microphones[deviceID].deviceName();
    // take only the device name from: "Microphone (device name)"
    QRegularExpression re_mic (".*\\((.+)\\).*");
    QRegularExpressionMatch mic_match = re_mic.match(microphones[deviceID].deviceName());

    if (mic_match.hasMatch() && mic_match.lastCapturedIndex() == 1)
    {
      // parsed extra text succesfully
      parsedName = mic_match.captured(1);
    }

    // if the device has changed between recording the settings and now.
    if (parsedName != deviceName)
    {
      // search for device with same name
      for(int i = 0; i < microphones.size(); ++i)
      {
        if(parsedName == deviceName)
        {
          qDebug() << "Found mic with name:" << microphones.at(i).deviceName()
                   << "and id:" << i;
          deviceID = i;
          break;
        }
      }
      // previous camera could not be found, use first.
      qDebug() << "Did not find microphone name:" << deviceName << " Using first";
      deviceID = 0;
    }
  }

  deviceInfo_ = microphones.at(deviceID);

  QAudioDeviceInfo info(deviceInfo_);

  printDebug(DEBUG_NORMAL, this, "", {"Chosen Device"}, {info.deviceName()});

  if (!info.isFormatSupported(format_)) {
    printDebug(DEBUG_WARNING, this, "Default audio format not supported - trying to use nearest");
    format_ = info.nearestFormat(format_);
  }

  if(format_.sampleRate() != -1)
    getStats()->audioInfo(format_.sampleRate(), format_.channelCount());
  else
    getStats()->audioInfo(0, 0);

  if (device_)
    delete device_;
  device_  = new AudioCaptureDevice(format_, this);

  createAudioInput();
  printDebug(DEBUG_NORMAL, this, "Audio initializing completed.");
  return true;
}

void AudioCaptureFilter::createAudioInput()
{
  qDebug() << "Iniating," << metaObject()->className() << ": Creating audio input";
  audioInput_ = new QAudioInput(deviceInfo_, format_, this);

  if (device_)
    device_->start();

  if (audioInput_)
    input_ = audioInput_->start();
  if (input_)
    connect(input_, SIGNAL(readyRead()), SLOT(readMore()));
}

void AudioCaptureFilter::readMore()
{
  if (!audioInput_)
  {
    printDebug(DEBUG_WARNING, this,  "No audio input in readMore");
    return;
  }
  qint64 len = audioInput_->bytesReady();
  if (len > AUDIO_BUFFER_SIZE)
  {
    len = AUDIO_BUFFER_SIZE;
  }
  quint64 l = 0;

  if (input_)
    l = input_->read(buffer_.data(), len);

  if (l > 0 && device_)
  {
    device_->write(buffer_.constData(), l);

    Data* newSample = new Data;

    // create audio data packet to be sent to filter graph
    timeval present_time;
    present_time.tv_sec = QDateTime::currentMSecsSinceEpoch()/1000;
    present_time.tv_usec = (QDateTime::currentMSecsSinceEpoch()%1000) * 1000;
    newSample->presentationTime = present_time;
    newSample->type = RAWAUDIO;
    newSample->data = std::unique_ptr<uint8_t[]>(new uint8_t[len]);

    memcpy(newSample->data.get(), buffer_.constData(), len);

    newSample->data_size = len;
    newSample->width = 0;
    newSample->height = 0;
    newSample->source = LOCAL;
    newSample->framerate = format_.sampleRate();

    std::unique_ptr<Data> u_newSample( newSample );
    sendOutput(std::move(u_newSample));

    //qDebug() << "Audio capture: Generated sample with size:" << l;
  }
}

void AudioCaptureFilter::start()
{
  qDebug() << "Audio," << metaObject()->className() << ": Resuming audio input.";

  if (audioInput_ && (audioInput_->state() == QAudio::SuspendedState
      || audioInput_->state() == QAudio::StoppedState))
  {
    audioInput_->resume();
  }
}

void AudioCaptureFilter::stop()
{
  qDebug() << "Audio," << metaObject()->className() << ": Suspending input.";

  if (audioInput_ && audioInput_->state() == QAudio::ActiveState)
  {
    audioInput_->suspend();
  }

  // just in case the filter part was running
  Filter::stop();

  qDebug() << "Audio," << metaObject()->className() << ": input suspended.";
}

// changing of audio device mid stream.
void AudioCaptureFilter::updateSettings()
{
  printNormal(this, "Updating audio settings");
  if (device_)
    device_->stop();

  if (audioInput_)
  {
    audioInput_->stop();
    audioInput_->disconnect(this);
   delete audioInput_;
  }

  init();
}

void AudioCaptureFilter::volumeChanged(int value)
{
  if(audioInput_)
  {
    audioInput_->setVolume(qreal(value) / 100);
  }
}

void AudioCaptureFilter::process()
{}
<commit_msg>feature(Processing): Try default audioinputdevice even if no devices was found.<commit_after>#include "audiocapturefilter.h"

#include "audiocapturedevice.h"
#include "statisticsinterface.h"

#include "common.h"

#include <QAudioInput>
#include <QDebug>
#include <QTime>
#include <QSettings>
#include <QRegularExpression>

const int AUDIO_BUFFER_SIZE = 65536;

AudioCaptureFilter::AudioCaptureFilter(QString id, QAudioFormat format, StatisticsInterface *stats) :
  Filter(id, "Audio_Capture", stats, NONE, RAWAUDIO),
  deviceInfo_(),
  device_(nullptr),
  format_(format),
  audioInput_(nullptr),
  input_(nullptr),
  buffer_(AUDIO_BUFFER_SIZE, 0)
{}

AudioCaptureFilter::~AudioCaptureFilter(){}

bool AudioCaptureFilter::init()
{
  printNormal(this, "Initializing audio capture filter.");

  QList<QAudioDeviceInfo> microphones = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);

  if (!microphones.empty())
  {
    QSettings settings("kvazzup.ini", QSettings::IniFormat);
    QString deviceName = settings.value("audio/Device").toString();
    int deviceID = settings.value("audio/DeviceID").toInt();

    if (deviceID < microphones.size())
    {
      QString parsedName = microphones[deviceID].deviceName();
      // take only the device name from: "Microphone (device name)"
      QRegularExpression re_mic (".*\\((.+)\\).*");
      QRegularExpressionMatch mic_match = re_mic.match(microphones[deviceID].deviceName());

      if (mic_match.hasMatch() && mic_match.lastCapturedIndex() == 1)
      {
        // parsed extra text succesfully
        parsedName = mic_match.captured(1);
      }

      // if the device has changed between recording the settings and now.
      if (parsedName != deviceName)
      {
        // search for device with same name
        for(int i = 0; i < microphones.size(); ++i)
        {
          if(parsedName == deviceName)
          {
            qDebug() << "Found mic with name:" << microphones.at(i).deviceName()
                     << "and id:" << i;
            deviceID = i;
            break;
          }
        }
        // previous camera could not be found, use first.
        qDebug() << "Did not find microphone name:" << deviceName << " Using first";
        deviceID = 0;
      }
    }
    deviceInfo_ = microphones.at(deviceID);
  }
  else
  {
    printWarning(this, "No available microphones found. Trying default");
    deviceInfo_ = QAudioDeviceInfo::defaultInputDevice();
  }

  QAudioDeviceInfo info(deviceInfo_);

  printDebug(DEBUG_NORMAL, this, "", {"Chosen Device"}, {info.deviceName()});

  if (!info.isFormatSupported(format_)) {
    printDebug(DEBUG_WARNING, this, "Default audio format not supported - trying to use nearest");
    format_ = info.nearestFormat(format_);
  }

  if(format_.sampleRate() != -1)
    getStats()->audioInfo(format_.sampleRate(), format_.channelCount());
  else
    getStats()->audioInfo(0, 0);

  if (device_)
    delete device_;
  device_  = new AudioCaptureDevice(format_, this);

  createAudioInput();
  printNormal(this, "Audio initializing completed.");
  return true;
}

void AudioCaptureFilter::createAudioInput()
{
  qDebug() << "Iniating," << metaObject()->className() << ": Creating audio input";
  audioInput_ = new QAudioInput(deviceInfo_, format_, this);

  if (device_)
    device_->start();

  if (audioInput_)
    input_ = audioInput_->start();
  if (input_)
    connect(input_, SIGNAL(readyRead()), SLOT(readMore()));
}

void AudioCaptureFilter::readMore()
{
  if (!audioInput_)
  {
    printDebug(DEBUG_WARNING, this,  "No audio input in readMore");
    return;
  }
  qint64 len = audioInput_->bytesReady();
  if (len > AUDIO_BUFFER_SIZE)
  {
    len = AUDIO_BUFFER_SIZE;
  }
  quint64 l = 0;

  if (input_)
    l = input_->read(buffer_.data(), len);

  if (l > 0 && device_)
  {
    device_->write(buffer_.constData(), l);

    Data* newSample = new Data;

    // create audio data packet to be sent to filter graph
    timeval present_time;
    present_time.tv_sec = QDateTime::currentMSecsSinceEpoch()/1000;
    present_time.tv_usec = (QDateTime::currentMSecsSinceEpoch()%1000) * 1000;
    newSample->presentationTime = present_time;
    newSample->type = RAWAUDIO;
    newSample->data = std::unique_ptr<uint8_t[]>(new uint8_t[len]);

    memcpy(newSample->data.get(), buffer_.constData(), len);

    newSample->data_size = len;
    newSample->width = 0;
    newSample->height = 0;
    newSample->source = LOCAL;
    newSample->framerate = format_.sampleRate();

    std::unique_ptr<Data> u_newSample( newSample );
    sendOutput(std::move(u_newSample));

    //qDebug() << "Audio capture: Generated sample with size:" << l;
  }
}

void AudioCaptureFilter::start()
{
  qDebug() << "Audio," << metaObject()->className() << ": Resuming audio input.";

  if (audioInput_ && (audioInput_->state() == QAudio::SuspendedState
      || audioInput_->state() == QAudio::StoppedState))
  {
    audioInput_->resume();
  }
}

void AudioCaptureFilter::stop()
{
  qDebug() << "Audio," << metaObject()->className() << ": Suspending input.";

  if (audioInput_ && audioInput_->state() == QAudio::ActiveState)
  {
    audioInput_->suspend();
  }

  // just in case the filter part was running
  Filter::stop();

  qDebug() << "Audio," << metaObject()->className() << ": input suspended.";
}

// changing of audio device mid stream.
void AudioCaptureFilter::updateSettings()
{
  printNormal(this, "Updating audio settings");
  if (device_)
    device_->stop();

  if (audioInput_)
  {
    audioInput_->stop();
    audioInput_->disconnect(this);
   delete audioInput_;
  }

  init();
}

void AudioCaptureFilter::volumeChanged(int value)
{
  if(audioInput_)
  {
    audioInput_->setVolume(qreal(value) / 100);
  }
}

void AudioCaptureFilter::process()
{}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Sony Corporation. 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 <algorithm>
#include <cmath>
#include <limits>
#include <nbla/solver/adabelief.hpp>
#include <nbla/solver/clip_grad.hpp>
#include <nbla/solver/mixed_precision_training.hpp>
#include <nbla/solver/weight_decay.hpp>

namespace nbla {
using std::make_shared;
using std::shared_ptr;

NBLA_REGISTER_SOLVER_SOURCE(AdaBelief, float, float, float, float, bool, bool,
                            bool, bool);

template <typename T>
AdaBelief<T>::AdaBelief(const Context &ctx, float alpha, float beta1,
                        float beta2, float eps, bool amsgrad,
                        bool weight_decouple, bool fixed_decay, bool rectify)
    : Solver(ctx), alpha_(alpha), beta1_(beta1), beta2_(beta2), eps_(eps),
      amsgrad_(amsgrad), weight_decouple_(weight_decouple),
      fixed_decay_(fixed_decay), rectify_(rectify) {}

template <typename T> AdaBelief<T>::~AdaBelief() {}

template <typename T>
void AdaBelief<T>::set_state_impl(const string &key, VariablePtr param) {
  // Implement here
}
template <typename T> void AdaBelief<T>::remove_state_impl(const string &key) {
  // Implement here
}

template <typename T>
void AdaBelief<T>::update_impl(const string &key, VariablePtr param) {
  // Implement here
}

NBLA_DEF_WEIGHT_DECAY(AdaBelief, weight_decay_cpu);
NBLA_DEF_CLIP_GRAD_BY_NORM(AdaBelief, clip_grad_by_norm_cpu);
NBLA_DEF_CHECK_INF_GRAD(AdaBelief, check_inf_grad_cpu);
NBLA_DEF_CHECK_NAN_GRAD(AdaBelief, check_nan_grad_cpu);
NBLA_DEF_CHECK_INF_OR_NAN_GRAD(AdaBelief, check_inf_or_nan_grad_cpu);
NBLA_DEF_SCALE_GRAD(AdaBelief, scale_grad_impl_cpu);
}
<commit_msg>Add adabelief solver .cpp code<commit_after>// Copyright (c) 2017 Sony Corporation. 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 <algorithm>
#include <cmath>
#include <limits>
#include <nbla/solver/adabelief.hpp>
#include <nbla/solver/clip_grad.hpp>
#include <nbla/solver/mixed_precision_training.hpp>
#include <nbla/solver/weight_decay.hpp>

namespace nbla {
using std::make_shared;
using std::shared_ptr;

NBLA_REGISTER_SOLVER_SOURCE(AdaBelief, float, float, float, float, float, bool,
                            bool, bool, bool);

template <typename T>
AdaBelief<T>::AdaBelief(const Context &ctx, float alpha, float beta1,
                        float beta2, float eps, float wd, bool amsgrad,
                        bool weight_decouple, bool fixed_decay, bool rectify)
    : Solver(ctx), alpha_(alpha), beta1_(beta1), beta2_(beta2), eps_(eps),
      wd_(wd), amsgrad_(amsgrad), weight_decouple_(weight_decouple),
      fixed_decay_(fixed_decay), rectify_(rectify) {}

template <typename T> AdaBelief<T>::~AdaBelief() {}

template <typename T>
void AdaBelief<T>::set_state_impl(const string &key, VariablePtr param) {
  auto shape = param->shape();
  auto m = make_shared<Variable>(shape);
  auto s = make_shared<Variable>(shape);
  auto max_s = make_shared<Variable>(shape);
  m->data()->zero();
  s->data()->zero();
  max_s->data()->zero();
  unordered_map<string, VariablePtr> pstate{
      {"mean", m}, {"sqr_var", s}, {"max_sqr_var", max_s}};
  SolverState state{pstate, 0};
  states_.insert({key, state});
}
template <typename T> void AdaBelief<T>::remove_state_impl(const string &key) {
  states_.erase(key);
}

template <typename T>
void AdaBelief<T>::update_impl(const string &key, VariablePtr param) {
  Size_t size = param->size();
  auto &state = states_.at(key);
  auto &t = state.t;
  const T *g = param->get_grad_pointer<T>(this->ctx_);
  VariablePtr s1 = state.pstate["mean"];
  VariablePtr s2 = state.pstate["sqr_var"];
  VariablePtr s3 = state.pstate["max_sqr_var"];
  T *m = s1->cast_data_and_get_pointer<T>(this->ctx_);
  T *s = s2->cast_data_and_get_pointer<T>(this->ctx_);
  T *max_s = s3->cast_data_and_get_pointer<T>(this->ctx_);
  T *theta = param->cast_data_and_get_pointer<T>(this->ctx_);
  t = std::min(t + 1, std::numeric_limits<uint32_t>::max() - 1);

  const T beta1_t = std::pow(beta1_, t);
  const T beta2_t = std::pow(beta2_, t);
  const T bias_correction = std::sqrt(1 - beta2_t) / (1 - beta1_t);
  T alpha_t = alpha_ * bias_correction;
  bool update_in_sgd_style = false;

  if (rectify_) {
    const T rho_inf = 2 / (1 - beta2_) - 1;
    const T rho_t =
        rho_inf - 2 * t * std::pow(beta2_, t) / (1 - std::pow(beta2_, t));

    if (rho_t > 4.0) {
      const T rt = std::sqrt((rho_t - 4) * (rho_t - 2) * rho_inf /
                             (rho_inf - 4) / (rho_inf - 2) / rho_t);
      alpha_t = rt * alpha_t;
    } else {
      alpha_t = alpha_;
      update_in_sgd_style = true;
    }
  }

  for (int i = 0; i < size; ++i) {
    m[i] = beta1_ * m[i] + (1 - beta1_) * g[i];
    s[i] = beta2_ * s[i] + (1 - beta2_) * std::pow(g[i] - m[i], 2);

    T denom = std::sqrt(s[i] + eps_);
    if (amsgrad_) {
      max_s[i] = std::max(s[i], max_s[i]);
      denom = std::sqrt(max_s[i] + eps_);
    }

    if (weight_decouple_) {
      if (fixed_decay_) {
        theta[i] = theta[i] - theta[i] * wd_;
      } else {
        theta[i] = theta[i] - theta[i] * wd_ * alpha_;
      }
    }

    if (update_in_sgd_style) {
      theta[i] = theta[i] - alpha_t * m[i];
    } else {
      theta[i] = theta[i] - alpha_t * m[i] / denom;
    }
  }
}

NBLA_DEF_WEIGHT_DECAY(AdaBelief, weight_decay_cpu);
NBLA_DEF_CLIP_GRAD_BY_NORM(AdaBelief, clip_grad_by_norm_cpu);
NBLA_DEF_CHECK_INF_GRAD(AdaBelief, check_inf_grad_cpu);
NBLA_DEF_CHECK_NAN_GRAD(AdaBelief, check_nan_grad_cpu);
NBLA_DEF_CHECK_INF_OR_NAN_GRAD(AdaBelief, check_inf_or_nan_grad_cpu);
NBLA_DEF_SCALE_GRAD(AdaBelief, scale_grad_impl_cpu);
} // namespace nbla
<|endoftext|>


<commit_before>/**
 * Copyright 2016-2017 MICRORISC s.r.o.
 *
 * 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 "LaunchUtils.h"
#include "BaseService.h"
#include "DpaTransactionTask.h"
#include "DpaRaw.h"
#include "IDaemon.h"
#include "IqrfLogging.h"

INIT_COMPONENT(IService, BaseService)

BaseService::BaseService(const std::string & name)
  :m_name(name)
  , m_messaging(nullptr)
  , m_daemon(nullptr)
{
}

BaseService::~BaseService()
{
}

void BaseService::setDaemon(IDaemon* daemon)
{
  m_daemon = daemon;
}

void BaseService::setSerializer(ISerializer* serializer)
{
  m_serializerVect.push_back(serializer);
}

void BaseService::setMessaging(IMessaging* messaging)
{
  m_messaging = messaging;
  m_messaging->registerMessageHandler([&](const ustring& msg) {
    handleMsgFromMessaging(msg);
  });
}

void BaseService::update(const rapidjson::Value& cfg)
{
  TRC_ENTER("");
  m_asyncDpaMessage = jutils::getPossibleMemberAs<bool>("AsyncDpaMessage", cfg, m_asyncDpaMessage);
  TRC_LEAVE("");
}

void BaseService::start()
{
  TRC_ENTER("");

  m_daemon->getScheduler()->registerMessageHandler(m_name, [&](const std::string& msg) {
    ustring msgu((unsigned char*)msg.data(), msg.size());
    handleMsgFromMessaging(msgu);
  });

  if (m_asyncDpaMessage) {
    TRC_INF("Set AsyncDpaMessageHandler :" << PAR(m_name));
    m_daemon->registerAsyncMessageHandler(m_name, [&](const DpaMessage& dpaMessage) {
      handleAsyncDpaMessage(dpaMessage);
    });
  }

  TRC_INF("BaseService :" << PAR(m_name) << " started");

  TRC_LEAVE("");
}

void BaseService::stop()
{
  TRC_ENTER("");

  m_daemon->getScheduler()->unregisterMessageHandler(m_name);

  TRC_INF("BaseService :" << PAR(m_name) << " stopped");
  TRC_LEAVE("");
}

void BaseService::handleMsgFromMessaging(const ustring& msg)
{
  TRC_DBG("==================================" << std::endl <<
    "Received from MESSAGING: " << std::endl << FORM_HEX(msg.data(), msg.size()));

  //to encode output message
  std::ostringstream os;

  //get input message
  std::string msgs((const char*)msg.data(), msg.size());
  std::istringstream is(msgs);

  std::unique_ptr<DpaTask> dpaTask;
  std::string command;

  //parse
  bool handled = false;
  std::string ctype;
  std::string lastError = "Unknown ctype";
  for (auto ser : m_serializerVect) {
    ctype = ser->parseCategory(msgs);
    if (ctype == CAT_DPA_STR) {
      dpaTask = ser->parseRequest(msgs);
      if (dpaTask) {
        DpaTransactionTask trans(*dpaTask);
        m_daemon->executeDpaTransaction(trans);
        int result = trans.waitFinish();
        os << dpaTask->encodeResponse(trans.getErrorStr());
        //TODO
        //just stupid hack for test async - remove it
        ///////
        //handleAsyncDpaMessage(dpaTask->getResponse());
        //handleAsyncDpaMessage(dpaTask->getRequest());
        ///////
        lastError = ser->getLastError();
        handled = true;
        break;
      }
    }
    else if (ctype == CAT_CONF_STR) {
      command = ser->parseConfig(msgs);
      if (!command.empty()) {
        std::string response = m_daemon->doCommand(command);
        lastError = ser->getLastError();
        os << ser->encodeConfig(msgs, response);
        handled = true;
        break;
      }
    }
  }

  if (!handled) {
    os << "PARSE ERROR: " << PAR(ctype) << PAR(lastError);
  }

  ustring msgu((unsigned char*)os.str().data(), os.str().size());
  m_messaging->sendMessage(msgu);
}

void BaseService::handleAsyncDpaMessage(const DpaMessage& dpaMessage)
{
  //TRC_ENTER("");
  std::string sr = m_serializerVect[0]->encodeAsyncAsDpaRaw(dpaMessage);
  ustring msgu((unsigned char*)sr.data(), sr.size());
  m_messaging->sendMessage(msgu);
  //TRC_LEAVE("");
}
<commit_msg>Fix misleading report JsonDpaRequest parse error<commit_after>/**
 * Copyright 2016-2017 MICRORISC s.r.o.
 *
 * 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 "LaunchUtils.h"
#include "BaseService.h"
#include "DpaTransactionTask.h"
#include "DpaRaw.h"
#include "IDaemon.h"
#include "IqrfLogging.h"

INIT_COMPONENT(IService, BaseService)

BaseService::BaseService(const std::string & name)
  :m_name(name)
  , m_messaging(nullptr)
  , m_daemon(nullptr)
{
}

BaseService::~BaseService()
{
}

void BaseService::setDaemon(IDaemon* daemon)
{
  m_daemon = daemon;
}

void BaseService::setSerializer(ISerializer* serializer)
{
  m_serializerVect.push_back(serializer);
}

void BaseService::setMessaging(IMessaging* messaging)
{
  m_messaging = messaging;
  m_messaging->registerMessageHandler([&](const ustring& msg) {
    handleMsgFromMessaging(msg);
  });
}

void BaseService::update(const rapidjson::Value& cfg)
{
  TRC_ENTER("");
  m_asyncDpaMessage = jutils::getPossibleMemberAs<bool>("AsyncDpaMessage", cfg, m_asyncDpaMessage);
  TRC_LEAVE("");
}

void BaseService::start()
{
  TRC_ENTER("");

  m_daemon->getScheduler()->registerMessageHandler(m_name, [&](const std::string& msg) {
    ustring msgu((unsigned char*)msg.data(), msg.size());
    handleMsgFromMessaging(msgu);
  });

  if (m_asyncDpaMessage) {
    TRC_INF("Set AsyncDpaMessageHandler :" << PAR(m_name));
    m_daemon->registerAsyncMessageHandler(m_name, [&](const DpaMessage& dpaMessage) {
      handleAsyncDpaMessage(dpaMessage);
    });
  }

  TRC_INF("BaseService :" << PAR(m_name) << " started");

  TRC_LEAVE("");
}

void BaseService::stop()
{
  TRC_ENTER("");

  m_daemon->getScheduler()->unregisterMessageHandler(m_name);

  TRC_INF("BaseService :" << PAR(m_name) << " stopped");
  TRC_LEAVE("");
}

void BaseService::handleMsgFromMessaging(const ustring& msg)
{
  TRC_DBG("==================================" << std::endl <<
    "Received from MESSAGING: " << std::endl << FORM_HEX(msg.data(), msg.size()));

  //to encode output message
  std::ostringstream os;

  //get input message
  std::string msgs((const char*)msg.data(), msg.size());
  std::istringstream is(msgs);

  std::unique_ptr<DpaTask> dpaTask;
  std::string command;

  //parse
  bool handled = false;
  std::string ctype;
  std::string lastError = "Unknown ctype";
  for (auto ser : m_serializerVect) {
    ctype = ser->parseCategory(msgs);
    if (ctype == CAT_DPA_STR) {
      dpaTask = ser->parseRequest(msgs);
      if (dpaTask) {
        DpaTransactionTask trans(*dpaTask);
        m_daemon->executeDpaTransaction(trans);
        int result = trans.waitFinish();
        os << dpaTask->encodeResponse(trans.getErrorStr());
        //TODO
        //just stupid hack for test async - remove it
        ///////
        //handleAsyncDpaMessage(dpaTask->getResponse());
        //handleAsyncDpaMessage(dpaTask->getRequest());
        ///////
        handled = true;
      }
      lastError = ser->getLastError();
      break;
    }
    else if (ctype == CAT_CONF_STR) {
      command = ser->parseConfig(msgs);
      if (!command.empty()) {
        std::string response = m_daemon->doCommand(command);
        lastError = ser->getLastError();
        os << ser->encodeConfig(msgs, response);
        handled = true;
      }
      lastError = ser->getLastError();
      break;
    }
  }

  if (!handled) {
    os << "PARSE ERROR: " << PAR(ctype) << PAR(lastError);
  }

  ustring msgu((unsigned char*)os.str().data(), os.str().size());
  m_messaging->sendMessage(msgu);
}

void BaseService::handleAsyncDpaMessage(const DpaMessage& dpaMessage)
{
  //TRC_ENTER("");
  std::string sr = m_serializerVect[0]->encodeAsyncAsDpaRaw(dpaMessage);
  ustring msgu((unsigned char*)sr.data(), sr.size());
  m_messaging->sendMessage(msgu);
  //TRC_LEAVE("");
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fieldmappingpage.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-06 18:38:33 $
 *
 *  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
 *
 ************************************************************************/

#ifndef EXTENSIONS_ABP_FIELDMAPPINGPAGE_HXX
#define EXTENSIONS_ABP_FIELDMAPPINGPAGE_HXX

#ifndef EXTENSIONS_ABP_ABSPAGE_HXX
#include "abspage.hxx"
#endif

//.........................................................................
namespace abp
{
//.........................................................................

    //=====================================================================
    //= FieldMappingPage
    //=====================================================================
    class FieldMappingPage : public AddressBookSourcePage
    {
    protected:
        FixedText       m_aExplanation;
        PushButton      m_aInvokeDialog;
        FixedText       m_aHint;

    public:
        FieldMappingPage( OAddessBookSourcePilot* _pParent );

    protected:
        // OWizardPage overridables
        virtual void        initializePage();

        // TabDialog overridables
        virtual void        ActivatePage();
        virtual void        DeactivatePage();

    private:
        DECL_LINK( OnInvokeDialog, void* );

        void implUpdateHint();
    };

//.........................................................................
}   // namespace abp
//.........................................................................

#endif // EXTENSIONS_ABP_FIELDMAPPINGPAGE_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.6.14); FILE MERGED 2008/04/01 12:29:40 thb 1.6.14.2: #i85898# Stripping all external header guards 2008/03/31 12:31:20 rt 1.6.14.1: #i87441# Change license header to LPGL v3.<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: fieldmappingpage.hxx,v $
 * $Revision: 1.7 $
 *
 * 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.
 *
 ************************************************************************/

#ifndef EXTENSIONS_ABP_FIELDMAPPINGPAGE_HXX
#define EXTENSIONS_ABP_FIELDMAPPINGPAGE_HXX

#include "abspage.hxx"

//.........................................................................
namespace abp
{
//.........................................................................

    //=====================================================================
    //= FieldMappingPage
    //=====================================================================
    class FieldMappingPage : public AddressBookSourcePage
    {
    protected:
        FixedText       m_aExplanation;
        PushButton      m_aInvokeDialog;
        FixedText       m_aHint;

    public:
        FieldMappingPage( OAddessBookSourcePilot* _pParent );

    protected:
        // OWizardPage overridables
        virtual void        initializePage();

        // TabDialog overridables
        virtual void        ActivatePage();
        virtual void        DeactivatePage();

    private:
        DECL_LINK( OnInvokeDialog, void* );

        void implUpdateHint();
    };

//.........................................................................
}   // namespace abp
//.........................................................................

#endif // EXTENSIONS_ABP_FIELDMAPPINGPAGE_HXX

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: propertyeditor.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 20:24:37 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_
#define _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_

#ifndef _SV_TABCTRL_HXX
#include <vcl/tabctrl.hxx>
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PCRCOMMON_HXX_
#include "pcrcommon.hxx"
#endif

#include <map>

//............................................................................
namespace pcr
{
//............................................................................

    class IBrowserControl;
    class IPropertyLineListener;
    class OBrowserPage;
    struct OLineDescriptor;

    //========================================================================
    //= OPropertyEditor
    //========================================================================
    class OPropertyEditor : public Control
    {
    private:
                typedef ::std::map< ::rtl::OUString, sal_uInt16 >   MapStringToPageId;
                struct HiddenPage
                {
                    sal_uInt16  nPos;
                    TabPage*    pPage;
                    HiddenPage() : nPos( 0 ), pPage( NULL ) { }
                    HiddenPage( sal_uInt16 _nPos, TabPage* _pPage ) : nPos( _nPos ), pPage( _pPage ) { }
                };

    private:
                TabControl                  m_aTabControl;
                IPropertyLineListener*      m_pListener;
                sal_uInt16                  m_nNextId;
                Link                        m_aPageActivationHandler;

                MapStringToPageId                       m_aPropertyPageIds;
                ::std::map< sal_uInt16, HiddenPage >    m_aHiddenPages;

    protected:
                void                        Resize();
                void                        GetFocus();

    public:
                                            OPropertyEditor (Window* pParent, WinBits nWinStyle = WB_DIALOGCONTROL);

                                            ~OPropertyEditor();

                sal_uInt16                  CalcVisibleLines();
                void                        EnableUpdate();
                void                        DisableUpdate();

                void                        SetLineListener(IPropertyLineListener *);

                void                        SetHelpId( sal_uInt32 nHelpId );
                sal_uInt16                  AppendPage( const String& r,sal_uInt32 nHelpId=0);
                void                        SetPage( sal_uInt16 );
                void                        RemovePage(sal_uInt16 nID);
                sal_uInt16                  GetCurPage();
                void                        ClearAll();

                void                        SetPropertyValue(const ::rtl::OUString & rEntryName, const ::rtl::OUString & rValue );
                ::rtl::OUString             GetPropertyValue(const ::rtl::OUString & rEntryName ) const;
                sal_uInt16                  GetPropertyPos(const ::rtl::OUString& rEntryName ) const;
                IBrowserControl*            GetPropertyControl( const ::rtl::OUString& rEntryName );
                void                        EnablePropertyLine( const ::rtl::OUString& _rEntryName, bool _bEnable );
                void                        EnablePropertyControls( const ::rtl::OUString& _rEntryName, bool _bEnableInput, bool _bEnablePrimaryButton, bool _bEnableSecondaryButton = false );
                sal_Bool                    IsPropertyInputEnabled( const ::rtl::OUString& _rEntryName ) const;

                void                        ShowPropertyPage( sal_uInt16 _nPageId, bool _bShow );

                sal_uInt16                  InsertEntry( const OLineDescriptor&, sal_uInt16 nPos = EDITOR_LIST_APPEND, sal_uInt16 _nPageId = EDITOR_PAGE_CURRENT );
                void                        RemoveEntry( const ::rtl::OUString& _rName );
                void                        ChangeEntry( const OLineDescriptor& );

                void                        SetFirstVisibleEntry(sal_uInt16 nPos);
                sal_uInt16                  GetFirstVisibleEntry();

                void                        SetSelectedEntry(sal_uInt16 nPos);
                sal_uInt16                  GetSelectedEntry();

        void    setPageActivationHandler(const Link& _rHdl) { m_aPageActivationHandler = _rHdl; }
        Link    getPageActivationHandler() const { return m_aPageActivationHandler; }

        // #95343# -------------------------------
        sal_Int32 getMinimumWidth();

                void                        CommitModified();

    private:
        OBrowserPage* getPage( sal_uInt16& _rPageId );
        const OBrowserPage* getPage( sal_uInt16& _rPageId ) const;

        OBrowserPage* getPage( const ::rtl::OUString& _rPropertyName );
        const OBrowserPage* getPage( const ::rtl::OUString& _rPropertyName ) const;

    protected:
        DECL_LINK(OnPageDeactivate, TabControl*);
        DECL_LINK(OnPageActivate, TabControl*);
    };

//............................................................................
} // namespace pcr
//............................................................................

#endif // _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_

<commit_msg>INTEGRATION: CWS pbrwuno (1.10.158); FILE MERGED 2005/10/05 07:07:28 fs 1.10.158.5: RESYNC: (1.10-1.11); FILE MERGED 2005/09/05 07:41:54 fs 1.10.158.4: #i53095# phase 3, part 1: introduced XPropertyControl and relatives, describing one control in the ObjectInspector, responsible for one property known issues: - rebuildPropertyUI can cause problems now: If the user clicks into   the control for property A, which causes property B to be committed,   which causes the UI for property A to be rebuilt, then this will   crash currently. Reason: rebuildPropertyUI now synchronously replaces   the VCL-Window of the rebuilt control, which is exactly the one   which is still in some MouseButtonDown-handler.   possible solutions:   - see if rebuiltPropertyUI can be obsoleted - handlers should be able     to just obtain the XPropertyControl from the PropertyUI, and     re-initialize the control. Shouldn't they?`   - make one of the steps in the chain (mouse-click, handler-call,     rebuildPropertyUI-callback) asynchronous. 2005/08/18 12:44:34 fs 1.10.158.3: #i53095#, phase 2<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: propertyeditor.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: vg $ $Date: 2006-03-14 11:30:21 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_
#define _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_

#ifndef _EXTENSIONS_PROPCTRLR_PCRCOMMON_HXX_
#include "pcrcommon.hxx"
#endif

/** === begin UNO includes === **/
#ifndef _COM_SUN_STAR_INSPECTION_XPROPERTYCONTROL_HPP_
#include <com/sun/star/inspection/XPropertyControl.hpp>
#endif
/** === end UNO includes === **/

#ifndef _SV_TABCTRL_HXX
#include <vcl/tabctrl.hxx>
#endif

#include <map>

//............................................................................
namespace pcr
{
//............................................................................

    class IPropertyLineListener;
    class OBrowserPage;
    struct OLineDescriptor;

    //========================================================================
    //= OPropertyEditor
    //========================================================================
    class OPropertyEditor : public Control
    {
    private:
                typedef ::std::map< ::rtl::OUString, sal_uInt16 >   MapStringToPageId;
                struct HiddenPage
                {
                    sal_uInt16  nPos;
                    TabPage*    pPage;
                    HiddenPage() : nPos( 0 ), pPage( NULL ) { }
                    HiddenPage( sal_uInt16 _nPos, TabPage* _pPage ) : nPos( _nPos ), pPage( _pPage ) { }
                };

    private:
                TabControl                  m_aTabControl;
                IPropertyLineListener*      m_pListener;
                sal_uInt16                  m_nNextId;
                Link                        m_aPageActivationHandler;

                MapStringToPageId                       m_aPropertyPageIds;
                ::std::map< sal_uInt16, HiddenPage >    m_aHiddenPages;

    protected:
                void                        Resize();
                void                        GetFocus();

    public:
                                            OPropertyEditor (Window* pParent, WinBits nWinStyle = WB_DIALOGCONTROL);

                                            ~OPropertyEditor();

                sal_uInt16                  CalcVisibleLines();
                void                        EnableUpdate();
                void                        DisableUpdate();

                void                        SetLineListener(IPropertyLineListener *);

                void                        SetHelpId( sal_uInt32 nHelpId );
                sal_uInt16                  AppendPage( const String& r,sal_uInt32 nHelpId=0);
                void                        SetPage( sal_uInt16 );
                void                        RemovePage(sal_uInt16 nID);
                sal_uInt16                  GetCurPage();
                void                        ClearAll();

                void                        SetPropertyValue(const ::rtl::OUString& _rEntryName, const ::com::sun::star::uno::Any& _rValue );
                ::com::sun::star::uno::Any  GetPropertyValue(const ::rtl::OUString& rEntryName ) const;
                sal_uInt16                  GetPropertyPos(const ::rtl::OUString& rEntryName ) const;
                ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControl >
                                            GetPropertyControl( const ::rtl::OUString& rEntryName );
                void                        EnablePropertyLine( const ::rtl::OUString& _rEntryName, bool _bEnable );
                void                        EnablePropertyControls( const ::rtl::OUString& _rEntryName, sal_Int16 _nControls, bool _bEnable );
                sal_Bool                    IsPropertyInputEnabled( const ::rtl::OUString& _rEntryName ) const;

                void                        ShowPropertyPage( sal_uInt16 _nPageId, bool _bShow );

                sal_uInt16                  InsertEntry( const OLineDescriptor&, sal_uInt16 _nPageId, sal_uInt16 nPos = EDITOR_LIST_APPEND );
                void                        RemoveEntry( const ::rtl::OUString& _rName );
                void                        ChangeEntry( const OLineDescriptor& );

        void    setPageActivationHandler(const Link& _rHdl) { m_aPageActivationHandler = _rHdl; }
        Link    getPageActivationHandler() const { return m_aPageActivationHandler; }

        // #95343# -------------------------------
        sal_Int32 getMinimumWidth();

                void                        CommitModified();

    private:
        OBrowserPage* getPage( sal_uInt16& _rPageId );
        const OBrowserPage* getPage( sal_uInt16& _rPageId ) const;

        OBrowserPage* getPage( const ::rtl::OUString& _rPropertyName );
        const OBrowserPage* getPage( const ::rtl::OUString& _rPropertyName ) const;

    protected:
        DECL_LINK(OnPageDeactivate, TabControl*);
        DECL_LINK(OnPageActivate, TabControl*);
    };

//............................................................................
} // namespace pcr
//............................................................................

#endif // _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_

<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2016 musikcube team
//
// 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 author nor the names of other 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.
//
//////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TransportWindow.h"

#include <cursespp/Screen.h>
#include <cursespp/Colors.h>
#include <cursespp/Message.h>
#include <cursespp/Text.h>

#include <app/util/Duration.h>

#include <core/debug.h>
#include <core/library/LocalLibraryConstants.h>

#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/chrono.hpp>
#include <boost/lexical_cast.hpp>

#include <algorithm>
#include <memory>

using namespace musik::core;
using namespace musik::core::audio;
using namespace musik::core::library;
using namespace musik::core::db;
using namespace musik::box;
using namespace boost::chrono;
using namespace cursespp;

#define REFRESH_TRANSPORT_READOUT 1001
#define REFRESH_INTERVAL_MS 1000
#define DEFAULT_TIME -1.0f
#define TIME_SLOP 3.0f

#define DEBOUNCE_REFRESH(x) \
    this->RemoveMessage(REFRESH_TRANSPORT_READOUT); \
    this->PostMessage(REFRESH_TRANSPORT_READOUT, 0, 0, x);

#define DEBOUNCE_REFRESH_AND_SYNC_TIME() \
    this->lastTime = this->transport.Position(); \
    DEBOUNCE_REFRESH(0)

static std::string playingFormat = "playing $title from $album";

struct Token {
    enum Type { Normal, Placeholder };

    static std::unique_ptr<Token> New(const std::string& value, Type type) {
        return std::unique_ptr<Token>(new Token(value, type));
    }

    Token(const std::string& value, Type type) {
        this->value = value;
        this->type = type;
    }

    std::string value;
    Type type;
};

typedef std::unique_ptr<Token> TokenPtr;
typedef std::vector<TokenPtr> TokenList;

/* tokenizes an input string that has $placeholder values */
void tokenize(const std::string& format, TokenList& tokens) {
    tokens.clear();
    Token::Type type = Token::Normal;
    size_t i = 0;
    size_t start = 0;
    while (i < format.size()) {
        char c = format[i];
        if ((type == Token::Placeholder && c == ' ') ||
            (type == Token::Normal && c == '$')) {
            /* escape $ with $$ */
            if (c == '$' && i < format.size() - 1 && format[i + 1] == '$') {
                i++;
            }
            else {
                if (i > start) {
                    tokens.push_back(Token::New(format.substr(start, i - start), type));
                }
                start = i;
                type = (c == ' ')  ? Token::Normal : Token::Placeholder;
            }
        }
        ++i;
    }

    if (i > 0) {
        tokens.push_back(Token::New(format.substr(start, i - start), type));
    }
}

/* writes the colorized formatted string to the specified window. accounts for
utf8 characters and ellipsizing */
size_t writePlayingFormat(
    WINDOW *w,
    std::string title,
    std::string album,
    size_t width)
{
    TokenList tokens;
    tokenize(playingFormat, tokens);

    int64 gb = COLOR_PAIR(CURSESPP_TEXT_ACTIVE);
    size_t remaining = width;

    auto it = tokens.begin();
    while (it != tokens.end() && remaining > 0) {
        Token *token = it->get();

        int64 attr = -1;
        std::string value;

        if (token->type == Token::Placeholder) {
            attr = gb;
            if (token->value == "$title") {
                value = title;
            }
            else if (token->value == "$album") {
                value = album;
            }
        }

        if (!value.size()) {
            value = token->value;
        }

        size_t len = u8cols(value);
        if (len > remaining) {
            value = text::Ellipsize(value, remaining);
            len = remaining;
        }

        if (attr != -1) {
            wattron(w, attr);
        }

        wprintw(w, value.c_str());

        if (attr != -1) {
            wattroff(w, attr);
        }

        remaining -= len;
        ++it;
    }

    return (width - remaining);
}

TransportWindow::TransportWindow(musik::box::PlaybackService& playback)
: Window(NULL)
, playback(playback)
, transport(playback.GetTransport())
{
    this->SetFrameVisible(false);
    this->playback.TrackChanged.connect(this, &TransportWindow::OnPlaybackServiceTrackChanged);
    this->playback.ModeChanged.connect(this, &TransportWindow::OnPlaybackModeChanged);
    this->playback.Shuffled.connect(this, &TransportWindow::OnPlaybackShuffled);
    this->transport.VolumeChanged.connect(this, &TransportWindow::OnTransportVolumeChanged);
    this->transport.TimeChanged.connect(this, &TransportWindow::OnTransportTimeChanged);
    this->paused = false;
    this->lastTime = DEFAULT_TIME;
}

TransportWindow::~TransportWindow() {
}

void TransportWindow::Show() {
    Window::Show();
    this->Update();
}

void TransportWindow::ProcessMessage(IMessage &message) {
    int type = message.Type();

    if (type == REFRESH_TRANSPORT_READOUT) {
        this->Update();
        DEBOUNCE_REFRESH(REFRESH_INTERVAL_MS)
    }
}

void TransportWindow::OnPlaybackServiceTrackChanged(size_t index, TrackPtr track) {
    this->currentTrack = track;
    this->lastTime = DEFAULT_TIME;
    DEBOUNCE_REFRESH(0);
}

void TransportWindow::OnPlaybackModeChanged() {
    DEBOUNCE_REFRESH_AND_SYNC_TIME();
}

void TransportWindow::OnTransportVolumeChanged() {
    DEBOUNCE_REFRESH_AND_SYNC_TIME();
}

void TransportWindow::OnTransportTimeChanged(double time) {
    DEBOUNCE_REFRESH_AND_SYNC_TIME();
}

void TransportWindow::OnPlaybackShuffled(bool shuffled) {
    DEBOUNCE_REFRESH_AND_SYNC_TIME();
}

#define ON(w, a) if (a != -1) { wattron(w, a); }
#define OFF(w, a) if (a != -1) { wattroff(w, a); }

void TransportWindow::Update() {
    this->Clear();
    WINDOW *c = this->GetContent();
    size_t cx = (size_t) this->GetContentWidth();

    bool paused = (transport.GetPlaybackState() == ITransport::PlaybackPaused);
    bool stopped = (transport.GetPlaybackState() == ITransport::PlaybackStopped);

    int64 gb = COLOR_PAIR(CURSESPP_TEXT_ACTIVE);
    int64 disabled = COLOR_PAIR(CURSESPP_TEXT_DISABLED);

    /* prepare the "shuffle" label */

    std::string shuffleLabel = " shuffle";
    size_t shuffleLabelLen = u8cols(shuffleLabel);

    /* playing SONG TITLE from ALBUM NAME */

    std::string duration = "0";

    if (stopped) {
        ON(c, disabled);
        wprintw(c, "playback is stopped");
        OFF(c, disabled);
    }
    else {
        std::string title, album;

        if (this->currentTrack) {
            title = this->currentTrack->GetValue(constants::Track::TITLE);
            album = this->currentTrack->GetValue(constants::Track::ALBUM);
            duration = this->currentTrack->GetValue(constants::Track::DURATION);
        }

        title = title.size() ? title : "[song]";
        album = album.size() ? album : "[album]";
        duration = duration.size() ? duration : "0";

        writePlayingFormat(
            c,
            title,
            album,
            cx - shuffleLabelLen);
    }

    wmove(c, 0, cx - shuffleLabelLen);
    int64 shuffleAttrs = this->playback.IsShuffled() ? gb : disabled;
    ON(c, shuffleAttrs);
    wprintw(c, shuffleLabel.c_str());
    OFF(c, shuffleAttrs);

    wmove(c, 1, 0); /* move cursor to the second line */

    /* volume slider */

    int volumePercent = (size_t) round(this->transport.Volume() * 100.0f) - 1;
    int thumbOffset = std::min(9, (volumePercent * 10) / 100);

    std::string volume = "vol ";

    for (int i = 0; i < 10; i++) {
        volume += (i == thumbOffset) ? "■" : "─";
    }

    volume += "  ";

    wprintw(c, volume.c_str());

    /* repeat mode setup */

    PlaybackService::RepeatMode mode = this->playback.GetRepeatMode();
    std::string repeatLabel = " ∞ ";
    std::string repeatModeLabel;
    int64 repeatAttrs = -1;
    switch (mode) {
        case PlaybackService::RepeatList:
            repeatModeLabel = "list";
            repeatAttrs = gb;
            break;
        case PlaybackService::RepeatTrack:
            repeatModeLabel = "track";
            repeatAttrs = gb;
            break;
        default:
            repeatModeLabel = "off";
            repeatAttrs = disabled;
            break;
    }

    /* time slider */

    int64 timerAttrs = 0;

    if (paused) { /* blink the track if paused */
        int64 now = duration_cast<seconds>(
            system_clock::now().time_since_epoch()).count();

        if (now % 2 == 0) {
            timerAttrs = COLOR_PAIR(CURSESPP_TEXT_HIDDEN);
        }
    }

    transport.Position();

    /* calculating playback time is inexact because it's based on buffers that
    are sent to the output. here we use a simple smoothing function to hopefully
    mitigate jumping around. basically: draw the time as one second more than the
    last time we displayed, unless they are more than few seconds apart. note this
    only works if REFRESH_INTERVAL_MS is 1000. */
    double smoothedTime = this->lastTime += 1.0f; /* 1000 millis */
    double actualTime = transport.Position();

    if (paused || stopped || fabs(smoothedTime - actualTime) > TIME_SLOP) {
        smoothedTime = actualTime;
    }

    this->lastTime = smoothedTime;
    /* end time smoothing */

    int secondsCurrent = (int) round(smoothedTime);
    int secondsTotal = boost::lexical_cast<int>(duration);

    std::string currentTime = duration::Duration(std::min(secondsCurrent, secondsTotal));
    std::string totalTime = duration::Duration(secondsTotal);

    size_t timerWidth =
        this->GetContentWidth() -
        u8cols(volume) -
        (u8cols(repeatLabel) + u8cols(repeatModeLabel)) -
        currentTime.size() -
        totalTime.size() -
        2; /* padding */

    thumbOffset = 0;

    if (secondsTotal) {
        size_t progress = (secondsCurrent * 100) / secondsTotal;
        thumbOffset = std::min(timerWidth - 1, (progress * timerWidth) / 100);
    }

    std::string timerTrack = "";
    for (size_t i = 0; i < timerWidth; i++) {
        timerTrack += (i == thumbOffset) ? "■" : "─";
    }

    wattron(c, timerAttrs); /* blink if paused */
    wprintw(c, currentTime.c_str());
    wattroff(c, timerAttrs);

    /* using wprintw() here on large displays (1440p+) will exceed the internal
    buffer length of 512 characters, so use boost format. */
    std::string fmt = boost::str(boost::format(
        " %s %s") % timerTrack % totalTime);

    waddstr(c, fmt.c_str());

    /* repeat mode draw */
    wprintw(c, repeatLabel.c_str());
    wattron(c, repeatAttrs);
    wprintw(c, repeatModeLabel.c_str());
    wattroff(c, repeatAttrs);

    this->Repaint();
}
<commit_msg>Just experimenting with transport metadata -- added the artist name.<commit_after>//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2016 musikcube team
//
// 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 author nor the names of other 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.
//
//////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TransportWindow.h"

#include <cursespp/Screen.h>
#include <cursespp/Colors.h>
#include <cursespp/Message.h>
#include <cursespp/Text.h>

#include <app/util/Duration.h>

#include <core/debug.h>
#include <core/library/LocalLibraryConstants.h>

#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/chrono.hpp>
#include <boost/lexical_cast.hpp>

#include <algorithm>
#include <memory>

using namespace musik::core;
using namespace musik::core::audio;
using namespace musik::core::library;
using namespace musik::core::db;
using namespace musik::box;
using namespace boost::chrono;
using namespace cursespp;

#define REFRESH_TRANSPORT_READOUT 1001
#define REFRESH_INTERVAL_MS 1000
#define DEFAULT_TIME -1.0f
#define TIME_SLOP 3.0f

#define DEBOUNCE_REFRESH(x) \
    this->RemoveMessage(REFRESH_TRANSPORT_READOUT); \
    this->PostMessage(REFRESH_TRANSPORT_READOUT, 0, 0, x);

#define DEBOUNCE_REFRESH_AND_SYNC_TIME() \
    this->lastTime = this->transport.Position(); \
    DEBOUNCE_REFRESH(0)

#define ON(w, a) if (a != -1) { wattron(w, a); }
#define OFF(w, a) if (a != -1) { wattroff(w, a); }

static std::string playingFormat = "playing $title by $artist from $album";

struct Token {
    enum Type { Normal, Placeholder };

    static std::unique_ptr<Token> New(const std::string& value, Type type) {
        return std::unique_ptr<Token>(new Token(value, type));
    }

    Token(const std::string& value, Type type) {
        this->value = value;
        this->type = type;
    }

    std::string value;
    Type type;
};

typedef std::unique_ptr<Token> TokenPtr;
typedef std::vector<TokenPtr> TokenList;

/* tokenizes an input string that has $placeholder values */
void tokenize(const std::string& format, TokenList& tokens) {
    tokens.clear();
    Token::Type type = Token::Normal;
    size_t i = 0;
    size_t start = 0;
    while (i < format.size()) {
        char c = format[i];
        if ((type == Token::Placeholder && c == ' ') ||
            (type == Token::Normal && c == '$')) {
            /* escape $ with $$ */
            if (c == '$' && i < format.size() - 1 && format[i + 1] == '$') {
                i++;
            }
            else {
                if (i > start) {
                    tokens.push_back(Token::New(format.substr(start, i - start), type));
                }
                start = i;
                type = (c == ' ')  ? Token::Normal : Token::Placeholder;
            }
        }
        ++i;
    }

    if (i > 0) {
        tokens.push_back(Token::New(format.substr(start, i - start), type));
    }
}

/* writes the colorized formatted string to the specified window. accounts for
utf8 characters and ellipsizing */
size_t writePlayingFormat(
    WINDOW *w,
    std::string title,
    std::string album,
    std::string artist,
    size_t width)
{
    TokenList tokens;
    tokenize(playingFormat, tokens);

    int64 dim = COLOR_PAIR(CURSESPP_TEXT_DISABLED);
    int64 gb = COLOR_PAIR(CURSESPP_TEXT_ACTIVE);
    size_t remaining = width;

    auto it = tokens.begin();
    while (it != tokens.end() && remaining > 0) {
        Token *token = it->get();

        int64 attr = dim;
        std::string value;

        if (token->type == Token::Placeholder) {
            attr = gb;
            if (token->value == "$title") {
                value = title;
            }
            else if (token->value == "$album") {
                value = album;
            }
            else if (token->value == "$artist") {
                value = artist;
            }
        }

        if (!value.size()) {
            value = token->value;
        }

        size_t len = u8cols(value);
        if (len > remaining) {
            value = text::Ellipsize(value, remaining);
            len = remaining;
        }

        ON(w, attr);
        wprintw(w, value.c_str());
        OFF(w, attr);

        remaining -= len;
        ++it;
    }

    return (width - remaining);
}

TransportWindow::TransportWindow(musik::box::PlaybackService& playback)
: Window(NULL)
, playback(playback)
, transport(playback.GetTransport())
{
    this->SetFrameVisible(false);
    this->playback.TrackChanged.connect(this, &TransportWindow::OnPlaybackServiceTrackChanged);
    this->playback.ModeChanged.connect(this, &TransportWindow::OnPlaybackModeChanged);
    this->playback.Shuffled.connect(this, &TransportWindow::OnPlaybackShuffled);
    this->transport.VolumeChanged.connect(this, &TransportWindow::OnTransportVolumeChanged);
    this->transport.TimeChanged.connect(this, &TransportWindow::OnTransportTimeChanged);
    this->paused = false;
    this->lastTime = DEFAULT_TIME;
}

TransportWindow::~TransportWindow() {
}

void TransportWindow::Show() {
    Window::Show();
    this->Update();
}

void TransportWindow::ProcessMessage(IMessage &message) {
    int type = message.Type();

    if (type == REFRESH_TRANSPORT_READOUT) {
        this->Update();
        DEBOUNCE_REFRESH(REFRESH_INTERVAL_MS)
    }
}

void TransportWindow::OnPlaybackServiceTrackChanged(size_t index, TrackPtr track) {
    this->currentTrack = track;
    this->lastTime = DEFAULT_TIME;
    DEBOUNCE_REFRESH(0);
}

void TransportWindow::OnPlaybackModeChanged() {
    DEBOUNCE_REFRESH_AND_SYNC_TIME();
}

void TransportWindow::OnTransportVolumeChanged() {
    DEBOUNCE_REFRESH_AND_SYNC_TIME();
}

void TransportWindow::OnTransportTimeChanged(double time) {
    DEBOUNCE_REFRESH_AND_SYNC_TIME();
}

void TransportWindow::OnPlaybackShuffled(bool shuffled) {
    DEBOUNCE_REFRESH_AND_SYNC_TIME();
}

void TransportWindow::Update() {
    this->Clear();
    WINDOW *c = this->GetContent();
    size_t cx = (size_t) this->GetContentWidth();

    bool paused = (transport.GetPlaybackState() == ITransport::PlaybackPaused);
    bool stopped = (transport.GetPlaybackState() == ITransport::PlaybackStopped);

    int64 gb = COLOR_PAIR(CURSESPP_TEXT_ACTIVE);
    int64 disabled = COLOR_PAIR(CURSESPP_TEXT_DISABLED);

    /* prepare the "shuffle" label */

    std::string shuffleLabel = " shuffle";
    size_t shuffleLabelLen = u8cols(shuffleLabel);

    /* playing SONG TITLE from ALBUM NAME */

    std::string duration = "0";

    if (stopped) {
        ON(c, disabled);
        wprintw(c, "playback is stopped");
        OFF(c, disabled);
    }
    else {
        std::string title, album, artist;

        if (this->currentTrack) {
            title = this->currentTrack->GetValue(constants::Track::TITLE);
            album = this->currentTrack->GetValue(constants::Track::ALBUM);
            artist = this->currentTrack->GetValue(constants::Track::ARTIST);
            duration = this->currentTrack->GetValue(constants::Track::DURATION);
        }

        title = title.size() ? title : "[song]";
        album = album.size() ? album : "[album]";
        artist = artist.size() ? artist : "[artist]";
        duration = duration.size() ? duration : "0";

        writePlayingFormat(
            c,
            title,
            album,
            artist,
            cx - shuffleLabelLen);
    }

    wmove(c, 0, cx - shuffleLabelLen);
    int64 shuffleAttrs = this->playback.IsShuffled() ? gb : disabled;
    ON(c, shuffleAttrs);
    wprintw(c, shuffleLabel.c_str());
    OFF(c, shuffleAttrs);

    wmove(c, 1, 0); /* move cursor to the second line */

    /* volume slider */

    int volumePercent = (size_t) round(this->transport.Volume() * 100.0f) - 1;
    int thumbOffset = std::min(9, (volumePercent * 10) / 100);

    std::string volume = "vol ";

    for (int i = 0; i < 10; i++) {
        volume += (i == thumbOffset) ? "■" : "─";
    }

    volume += "  ";

    wprintw(c, volume.c_str());

    /* repeat mode setup */

    PlaybackService::RepeatMode mode = this->playback.GetRepeatMode();
    std::string repeatLabel = " ∞ ";
    std::string repeatModeLabel;
    int64 repeatAttrs = -1;
    switch (mode) {
        case PlaybackService::RepeatList:
            repeatModeLabel = "list";
            repeatAttrs = gb;
            break;
        case PlaybackService::RepeatTrack:
            repeatModeLabel = "track";
            repeatAttrs = gb;
            break;
        default:
            repeatModeLabel = "off";
            repeatAttrs = disabled;
            break;
    }

    /* time slider */

    int64 timerAttrs = 0;

    if (paused) { /* blink the track if paused */
        int64 now = duration_cast<seconds>(
            system_clock::now().time_since_epoch()).count();

        if (now % 2 == 0) {
            timerAttrs = COLOR_PAIR(CURSESPP_TEXT_HIDDEN);
        }
    }

    transport.Position();

    /* calculating playback time is inexact because it's based on buffers that
    are sent to the output. here we use a simple smoothing function to hopefully
    mitigate jumping around. basically: draw the time as one second more than the
    last time we displayed, unless they are more than few seconds apart. note this
    only works if REFRESH_INTERVAL_MS is 1000. */
    double smoothedTime = this->lastTime += 1.0f; /* 1000 millis */
    double actualTime = transport.Position();

    if (paused || stopped || fabs(smoothedTime - actualTime) > TIME_SLOP) {
        smoothedTime = actualTime;
    }

    this->lastTime = smoothedTime;
    /* end time smoothing */

    int secondsCurrent = (int) round(smoothedTime);
    int secondsTotal = boost::lexical_cast<int>(duration);

    std::string currentTime = duration::Duration(std::min(secondsCurrent, secondsTotal));
    std::string totalTime = duration::Duration(secondsTotal);

    size_t timerWidth =
        this->GetContentWidth() -
        u8cols(volume) -
        (u8cols(repeatLabel) + u8cols(repeatModeLabel)) -
        currentTime.size() -
        totalTime.size() -
        2; /* padding */

    thumbOffset = 0;

    if (secondsTotal) {
        size_t progress = (secondsCurrent * 100) / secondsTotal;
        thumbOffset = std::min(timerWidth - 1, (progress * timerWidth) / 100);
    }

    std::string timerTrack = "";
    for (size_t i = 0; i < timerWidth; i++) {
        timerTrack += (i == thumbOffset) ? "■" : "─";
    }

    wattron(c, timerAttrs); /* blink if paused */
    wprintw(c, currentTime.c_str());
    wattroff(c, timerAttrs);

    /* using wprintw() here on large displays (1440p+) will exceed the internal
    buffer length of 512 characters, so use boost format. */
    std::string fmt = boost::str(boost::format(
        " %s %s") % timerTrack % totalTime);

    waddstr(c, fmt.c_str());

    /* repeat mode draw */
    wprintw(c, repeatLabel.c_str());
    wattron(c, repeatAttrs);
    wprintw(c, repeatModeLabel.c_str());
    wattroff(c, repeatAttrs);

    this->Repaint();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <queue>
#include <stdio.h>
using namespace std;

#include "Binary-tree.hpp"
#include "pretty-print.hpp"

// Функция создает сбалансированное дерево и возращает корневой узел дерева
Node* createBalancedBTree(Node** node, int *&value, int cnt)
{
	if (cnt <= 0)
		return NULL;

	if (node == NULL) {
		Node* tmp = NULL;
		node = &tmp;
	}

	if ((*node) == NULL) {
		(*node) = new Node(*value);
		++value;
		--cnt;
	}

	int cntr = cnt / 2;
	int cntl = cnt - cntr;

	if (cntl > 0)
		createBalancedBTree(&(*node)->left, value, cntl);

	if (cntr > 0)
		createBalancedBTree(&(*node)->right, value, cntr);
	return (*node);
}

// Функция создает бинарное дерево поиска и возращает корневой узел дерева
Node* insertSearchBTree(Node** node, int value)
{
	if ((*node) == NULL) {
		(*node) = new Node(value);
		return *node;
	}

	if ((*node)->data > value) {
		return insertSearchBTree(&(*node)->left, value);
	} else if ((*node)->data < value) {
		return insertSearchBTree(&(*node)->right, value);
	} else {
		std::cout << "something going wrong! " << value << endl;
	}
}

// Функция создает бинарное дерево поиска и возращает корневой узел дерева
Node* createSearchBTree(int *array, int size)
{
	Node* node = NULL;
	for (int i = 0; i < size; ++i)
		insertSearchBTree(&node, array[i]);
	return node;
}

int main()
{
	int data[] = {25, 50, 55, 0, 10, 5, 30, 40, 35, 15, 45, 60, 75, 70};
	int size = sizeof(data) / (sizeof(data[0]));

	cout << "Exer.1 - Balanced B-Tree" << endl;
	int *it = (int *)&data;
	printPretty(createBalancedBTree(NULL, it, size));
	cout << endl;

	cout << "Exer.2 - Search B-Tree" << endl;
	printPretty(createSearchBTree(data, size));

	return 0;
}
<commit_msg>lab5 6<commit_after>#include <iostream>
#include <queue>
#include <stdio.h>
using namespace std;

#include "Binary-tree.hpp"
#include "pretty-print.hpp"

// Функция создает сбалансированное дерево и возращает корневой узел дерева
Node* createBalancedBTree(Node** node, int *&value, int cnt)
{
	if (cnt <= 0)
		return NULL;

	if (node == NULL) {
		Node* tmp = NULL;
		node = &tmp;
	}

	if ((*node) == NULL) {
		(*node) = new Node(*value);
		++value;
		--cnt;
	}

	int cntr = cnt / 2;
	int cntl = cnt - cntr;

	if (cntl > 0)
		createBalancedBTree(&(*node)->left, value, cntl);

	if (cntr > 0)
		createBalancedBTree(&(*node)->right, value, cntr);
	return (*node);
}

// Функция создает бинарное дерево поиска и возращает корневой узел дерева
Node* insertSearchBTree(Node** node, int value)
{
	if ((*node) == NULL) {
		(*node) = new Node(value);
		return *node;
	}

	if ((*node)->data > value) {
		return insertSearchBTree(&(*node)->left, value);
	} else if ((*node)->data < value) {
		return insertSearchBTree(&(*node)->right, value);
	} else {
		std::cout << "something going wrong! " << value << endl;
	}
}

// Функция создает бинарное дерево поиска и возращает корневой узел дерева
Node* createSearchBTree(int *array, int size)
{
	Node* node = NULL;
	for (int i = 0; i < size; ++i)
		insertSearchBTree(&node, array[i]);
	return node;
}

void findRowsSumm(Node *node, int *rows, int currentDepth)
{
	if (node == NULL)
		return;

	rows[currentDepth] += node->data;
	findRowsSumm(node->left, rows, currentDepth+1);
	findRowsSumm(node->right, rows, currentDepth+1);
}

int findRowWithMaxSumm(Node *node, int rowsCount)
{
	if (node == NULL)
		return -1;

	int *rowsSumm = new int[rowsCount];
	for (int i = 0; i < rowsCount; ++i)
		rowsSumm[i] = 0;

	findRowsSumm(node, rowsSumm, 0);

	int maxRow = -1;
	int maxValue = 0;
	for (int i = 0; i < rowsCount; i++)
	{
		if ((rowsSumm[i] >= 0) && (rowsSumm[i] > maxValue)) {
			maxRow = i;
			maxValue = rowsSumm[i];
		}
	}
	return maxRow;
}

int main()
{
	int data[] = {35, 55, 15, 50, 40, 0, 10, 45, 5, 30, 25};
	int size = sizeof(data) / (sizeof(data[0]));

	cout << "Exer.1 - Balanced B-Tree" << endl;
	int *it = (int *)&data;
	Node* balancedBTreeRoot = createBalancedBTree(NULL, it, size);
	printPretty(balancedBTreeRoot);
	cout << endl;

	cout << "Exer.2 - Search B-Tree" << endl;
	Node* searchBTreeRoot = createSearchBTree(data, size);
	printPretty(searchBTreeRoot);
	cout << endl;

	cout << "Exer.6 - Find row with max summ of values from search B-Tree" << endl;
	printPretty(searchBTreeRoot);
	cout << "Count starts from 0, -1 = no values found" << endl;
	cout << "Answer is " << findRowWithMaxSumm(searchBTreeRoot, size) << endl;
	cout << endl;

	return 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_gflags.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.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(::apollo::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_path);

  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 << "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 << "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 << "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);
  if (!status.ok()) {
    AERROR << "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);
  AINFO_EVERY(1000) << "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_.trajectory_point_size() == 0) {
    AWARN_EVERY(100) << "planning has no trajectory point. ";
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR,
                  "planning has no trajectory point.");
  }

  common::VehicleState::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";
    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";
    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";
    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: reduce warning text<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_gflags.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.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(::apollo::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_path);

  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 << "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 << "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);
  if (!status.ok()) {
    AERROR << "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);
  AINFO_EVERY(1000) << "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_.trajectory_point_size() == 0) {
    AWARN_EVERY(100) << "planning has no trajectory point. ";
    return Status(ErrorCode::CONTROL_COMPUTE_ERROR,
                  "planning has no trajectory point.");
  }

  common::VehicleState::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";
    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";
    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";
    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|>