<commit_before>/*
 * Implements a Time Varying Linear Quadratic Regulator using trajectories.
 *
 * Author: Andrew Barry, <abarry@csail.mit.edu> 2015
 *
 */

#include "tvlqr-controller.hpp"

using namespace std;

lcm_t * lcm;

mav_pose_t_subscription_t *mav_pose_t_sub;
lcmt_tvlqr_controller_action_subscription_t *tvlqr_controller_action_sub;
pronto_utime_t_subscription_t *pronto_reset_handler_sub;
mav_filter_state_t_subscription_t *pronto_state_handler_sub;

// global trajectory library
TrajectoryLibrary trajlib;

TvlqrControl *control;
ServoConverter *converter;

bot_lcmgl_t* lcmgl;
string deltawing_u_channel = "deltawing_u";
string pronto_init_channel = "MAV_STATE_EST_INITIALIZER";
string pronto_reset_complete_channel = "MAV_STATE_EST_INIT_COMPLETE";

bool state_estimator_init = true;

mav_pose_t *last_pose_msg;

mav_filter_state_t *last_filter_state = NULL;

double sigma0_vb;

double sigma0_delta_xy;
double sigma0_delta_z;

double sigma0_chi_xy;
double sigma0_chi_z;

void pronto_reset_complete_handler(const lcm_recv_buf_t *rbuf, const char* channel, const pronto_utime_t *msg, void *user) {

    // a pronto-reset has happened!  Charge forward with the new trajectory
    state_estimator_init = true;

}

void mav_filter_state_t_handler(const lcm_recv_buf_t *rbuf, const char* channel, const mav_filter_state_t *msg, void *user) {

    if (last_filter_state != NULL) {
        mav_filter_state_t_destroy(last_filter_state);
    }

    last_filter_state = mav_filter_state_t_copy(msg);

}

void mav_pose_t_handler(const lcm_recv_buf_t *rbuf, const char* channel, const mav_pose_t *msg, void *user) {

    if (!control->HasTrajectory()) {

        return;
    }

    if (!state_estimator_init) {
        cout << "Waiting for state estimator init..." << endl;
        return;
    }

    if (last_pose_msg != NULL) {
        mav_pose_t_destroy(last_pose_msg);
    }
    last_pose_msg = mav_pose_t_copy(msg);

    // whenever we get a state estimate, we want to output a new control action

    Eigen::VectorXd state_vec = StateEstimatorToDrakeVector(msg);

    Eigen::VectorXi control_vec = control->GetControl(state_vec);

    // send control out through LCM

    lcmt_deltawing_u u_msg;

    u_msg.timestamp = GetTimestampNow();

    u_msg.elevonL = control_vec(0);
    u_msg.elevonR = control_vec(1);
    u_msg.throttle = control_vec(2);

    u_msg.is_autonomous = true;
    u_msg.video_record = true; // todo, this isn't quite how this should be designed

    lcmt_deltawing_u_publish(lcm, deltawing_u_channel.c_str(), &u_msg);

}

void lcmt_tvlqr_controller_action_handler(const lcm_recv_buf_t *rbuf, const char* channel, const lcmt_tvlqr_controller_action *msg, void *user) {

    // getting an action means we should start a new TVLQR controller!

    Trajectory *traj = trajlib.GetTrajectoryByNumber(msg->trajectory_number);

    if (traj == NULL) {
        cerr << "Warning: trajectory number " << msg->trajectory_number << " was NULL!  Aborting trajectory run." << endl;
        return;
    }

    control->SetTrajectory(traj);

    cout << "Starting trajectory " << msg->trajectory_number << endl;

    state_estimator_init = false;

    // request a state estimator init

    SendStateEstimatorResetRequest();

}

void SendStateEstimatorResetRequest() {
    if (last_filter_state == NULL) {
        SendStateEstimatorDefaultResetRequest();
        return;
    }

    // if we are here, then we have an old state to copy from

    mav_filter_state_t *reset_request = mav_filter_state_t_copy(last_filter_state);

    // reset the covariances on velocity
    reset_request->cov[66] = sigma0_vb * sigma0_vb;
    reset_request->cov[67] = 0;
    reset_request->cov[68] = 0;
    reset_request->cov[69] = 0;
    reset_request->cov[70] = 0;
    reset_request->cov[71] = 0;
    reset_request->cov[72] = 0;
    reset_request->cov[73] = 0;
    reset_request->cov[74] = 0;

    reset_request->cov[87] = 0;
    reset_request->cov[88] = sigma0_vb * sigma0_vb;
    reset_request->cov[89] = 0;
    reset_request->cov[90] = 0;
    reset_request->cov[91] = 0;
    reset_request->cov[92] = 0;
    reset_request->cov[93] = 0;
    reset_request->cov[94] = 0;
    reset_request->cov[95] = 0;
/*
    reset_request->cov[108] = 0;
    reset_request->cov[109] = 0;
    reset_request->cov[110] = sigma0_vb * sigma0_vb;
    reset_request->cov[111] = 0;
    reset_request->cov[112] = 0;
    reset_request->cov[113] = 0;
    reset_request->cov[114] = 0;
    reset_request->cov[115] = 0;
    reset_request->cov[116] = 0;
*/

    // reset the covariances on position (x, y)
    reset_request->cov[192] = 0;
    reset_request->cov[193] = 0;
    reset_request->cov[194] = 0;
    reset_request->cov[195] = 0;
    reset_request->cov[196] = 0;
    reset_request->cov[197] = 0;
    reset_request->cov[198] = sigma0_delta_xy * sigma0_delta_xy;
    reset_request->cov[199] = 0;
    reset_request->cov[200] = 0;

    reset_request->cov[213] = 0;
    reset_request->cov[214] = 0;
    reset_request->cov[215] = 0;
    reset_request->cov[216] = 0;
    reset_request->cov[217] = 0;
    reset_request->cov[218] = 0;
    reset_request->cov[219] = 0;
    reset_request->cov[220] = sigma0_delta_xy * sigma0_delta_xy;
    reset_request->cov[221] = 0;

    mav_filter_state_t_publish(lcm, pronto_init_channel.c_str(), reset_request);

    cout << "State estimator reset message sent." << endl;

    mav_filter_state_t_destroy(reset_request);
}

void SendStateEstimatorDefaultResetRequest() {

    mav_filter_state_t msg;

    msg.utime = GetTimestampNow();

    // copy in the states from the last position, but reset the covariance
    if (last_pose_msg != NULL) {
        msg.quat[0] = last_pose_msg->orientation[0];
        msg.quat[1] = last_pose_msg->orientation[1];
        msg.quat[2] = last_pose_msg->orientation[2];
        msg.quat[3] = last_pose_msg->orientation[3];
    } else {
        msg.quat[0] = 1;
        msg.quat[1] = 0;
        msg.quat[2] = 0;
        msg.quat[3] = 0;
    }

    msg.num_states = 21;

    double states[msg.num_states];

    if (last_pose_msg != NULL) {
        states[0] = last_pose_msg->rotation_rate[0];
        states[1] = last_pose_msg->rotation_rate[1];
        states[2] = last_pose_msg->rotation_rate[2];

        states[3] = last_pose_msg->vel[0];
        states[4] = last_pose_msg->vel[1];
        states[5] = last_pose_msg->vel[2];

    } else {
        states[0] = 0;
        states[1] = 0;
        states[2] = 0;

        states[3] = 0;
        states[4] = 0;
        states[5] = 0;
    }

    states[6] = 0;
    states[7] = 0;
    states[8] = 0;

    if (last_pose_msg != NULL) {

        states[9] = last_pose_msg->pos[0];
        states[10] = last_pose_msg->pos[1];
        states[11] = last_pose_msg->pos[2];

        states[12] = last_pose_msg->accel[0];
        states[13] = last_pose_msg->accel[1];
        states[14] = last_pose_msg->accel[2];

    } else {
        states[9] = 0;
        states[10] = 0;
        states[11] = 0;

        states[12] = 0;
        states[13] = 0;
        states[14] = 0;
    }

    states[15] = 0;
    states[16] = 0;
    states[17] = 0;
    states[18] = 0;
    states[19] = 0;
    states[20] = 0;

    msg.state = states;

    msg.num_cov_elements = 441;

    double covs[msg.num_cov_elements];

    for (int i = 0; i < msg.num_cov_elements; i++) {
        covs[i] = 0;
    }

    covs[66] = sigma0_vb * sigma0_vb;
    covs[88] = sigma0_vb * sigma0_vb;
    covs[110] = sigma0_vb * sigma0_vb;
    covs[132] = sigma0_chi_xy * sigma0_chi_xy;
    covs[154] = sigma0_chi_xy * sigma0_chi_xy;
    covs[176] = sigma0_chi_z * sigma0_chi_z;
    covs[198] = sigma0_delta_xy * sigma0_delta_xy;
    covs[220] = sigma0_delta_xy * sigma0_delta_xy;
    covs[242] = sigma0_delta_z * sigma0_delta_z;

    msg.cov = covs;

    mav_filter_state_t_publish(lcm, pronto_init_channel.c_str(), &msg);

    cout << "State estimator DEFAULT reset message sent." << endl;
}

void sighandler(int dum)
{
    printf("\n\nclosing... ");

    mav_pose_t_unsubscribe(lcm, mav_pose_t_sub);
    lcmt_tvlqr_controller_action_unsubscribe(lcm, tvlqr_controller_action_sub);
    mav_filter_state_t_unsubscribe(lcm, pronto_state_handler_sub);

    lcm_destroy (lcm);

    if (converter != NULL) {
        delete converter;
    }

    if (control != NULL) {
        delete control;
    }

    printf("done.\n");

    exit(0);
}
<commit_msg>Working commit.<commit_after>/*
 * Implements a Time Varying Linear Quadratic Regulator using trajectories.
 *
 * Author: Andrew Barry, <abarry@csail.mit.edu> 2015
 *
 */

#include "tvlqr-controller.hpp"

using namespace std;

lcm_t * lcm;

mav_pose_t_subscription_t *mav_pose_t_sub;
lcmt_tvlqr_controller_action_subscription_t *tvlqr_controller_action_sub;
pronto_utime_t_subscription_t *pronto_reset_handler_sub;
mav_filter_state_t_subscription_t *pronto_state_handler_sub;

// global trajectory library
TrajectoryLibrary trajlib;

TvlqrControl *control;
ServoConverter *converter;

bot_lcmgl_t* lcmgl;
string deltawing_u_channel = "deltawing_u";
string pronto_init_channel = "MAV_STATE_EST_INITIALIZER";
string pronto_reset_complete_channel = "MAV_STATE_EST_INIT_COMPLETE";

bool state_estimator_init = true;

mav_pose_t *last_pose_msg;

mav_filter_state_t *last_filter_state = NULL;

double sigma0_vb;

double sigma0_delta_xy;
double sigma0_delta_z;

double sigma0_chi_xy;
double sigma0_chi_z;

void pronto_reset_complete_handler(const lcm_recv_buf_t *rbuf, const char* channel, const pronto_utime_t *msg, void *user) {

    // a pronto-reset has happened!  Charge forward with the new trajectory
    state_estimator_init = true;

    cout << "Got state estimator reset" << endl;

}

void mav_filter_state_t_handler(const lcm_recv_buf_t *rbuf, const char* channel, const mav_filter_state_t *msg, void *user) {

    if (last_filter_state != NULL) {
        mav_filter_state_t_destroy(last_filter_state);
    }

    last_filter_state = mav_filter_state_t_copy(msg);

}

void mav_pose_t_handler(const lcm_recv_buf_t *rbuf, const char* channel, const mav_pose_t *msg, void *user) {

    if (!control->HasTrajectory()) {

        return;
    }

    if (!state_estimator_init) {
        cout << "Waiting for state estimator init..." << endl;
        return;
    }

    if (last_pose_msg != NULL) {
        mav_pose_t_destroy(last_pose_msg);
    }
    last_pose_msg = mav_pose_t_copy(msg);

    // whenever we get a state estimate, we want to output a new control action

    Eigen::VectorXd state_vec = StateEstimatorToDrakeVector(msg);

    Eigen::VectorXi control_vec = control->GetControl(state_vec);

    // send control out through LCM

    lcmt_deltawing_u u_msg;

    u_msg.timestamp = GetTimestampNow();

    u_msg.elevonL = control_vec(0);
    u_msg.elevonR = control_vec(1);
    u_msg.throttle = control_vec(2);

    u_msg.is_autonomous = true;
    u_msg.video_record = true; // todo, this isn't quite how this should be designed

    lcmt_deltawing_u_publish(lcm, deltawing_u_channel.c_str(), &u_msg);

}

void lcmt_tvlqr_controller_action_handler(const lcm_recv_buf_t *rbuf, const char* channel, const lcmt_tvlqr_controller_action *msg, void *user) {

    // getting an action means we should start a new TVLQR controller!

    Trajectory *traj = trajlib.GetTrajectoryByNumber(msg->trajectory_number);

    if (traj == NULL) {
        cerr << "Warning: trajectory number " << msg->trajectory_number << " was NULL!  Aborting trajectory run." << endl;
        return;
    }

    control->SetTrajectory(traj);

    cout << "Starting trajectory " << msg->trajectory_number << endl;

    state_estimator_init = false;

    // request a state estimator init

    SendStateEstimatorResetRequest();

}

void SendStateEstimatorResetRequest() {
    if (last_filter_state == NULL) {
        SendStateEstimatorDefaultResetRequest();
        return;
    }

    // if we are here, then we have an old state to copy from

    mav_filter_state_t *reset_request = mav_filter_state_t_copy(last_filter_state);

    // reset the covariances on velocity
/*
    reset_request->cov[66] = sigma0_vb * sigma0_vb;
    reset_request->cov[67] = 0;
    reset_request->cov[68] = 0;
    reset_request->cov[69] = 0;
    reset_request->cov[70] = 0;
    reset_request->cov[71] = 0;
    reset_request->cov[72] = 0;
    reset_request->cov[73] = 0;
    reset_request->cov[74] = 0;

    reset_request->cov[87] = 0;
    reset_request->cov[88] = sigma0_vb * sigma0_vb;
    reset_request->cov[89] = 0;
    reset_request->cov[90] = 0;
    reset_request->cov[91] = 0;
    reset_request->cov[92] = 0;
    reset_request->cov[93] = 0;
    reset_request->cov[94] = 0;
    reset_request->cov[95] = 0;

    reset_request->cov[108] = 0;
    reset_request->cov[109] = 0;
    reset_request->cov[110] = sigma0_vb * sigma0_vb;
    reset_request->cov[111] = 0;
    reset_request->cov[112] = 0;
    reset_request->cov[113] = 0;
    reset_request->cov[114] = 0;
    reset_request->cov[115] = 0;
    reset_request->cov[116] = 0;
*/

/*
    // reset the covariances on position (x, y)
    reset_request->cov[192] = 0;
    reset_request->cov[193] = 0;
    reset_request->cov[194] = 0;
    reset_request->cov[195] = 0;
    reset_request->cov[196] = 0;
    reset_request->cov[197] = 0;
    reset_request->cov[198] = sigma0_delta_xy * sigma0_delta_xy;
    reset_request->cov[199] = 0;
    reset_request->cov[200] = 0;

    reset_request->cov[213] = 0;
    reset_request->cov[214] = 0;
    reset_request->cov[215] = 0;
    reset_request->cov[216] = 0;
    reset_request->cov[217] = 0;
    reset_request->cov[218] = 0;
    reset_request->cov[219] = 0;
    reset_request->cov[220] = sigma0_delta_xy * sigma0_delta_xy;
    reset_request->cov[221] = 0;

*/
reset_request->cov[66] = sigma0_vb * sigma0_vb;
reset_request->cov[88] = sigma0_vb * sigma0_vb;
reset_request->cov[110] = sigma0_vb * sigma0_vb;

reset_request->cov[198] = sigma0_delta_xy * sigma0_delta_xy;
reset_request->cov[220] = sigma0_delta_xy * sigma0_delta_xy;

    mav_filter_state_t_publish(lcm, pronto_init_channel.c_str(), reset_request);

    cout << "State estimator reset message sent." << endl;

    mav_filter_state_t_destroy(reset_request);
}

void SendStateEstimatorDefaultResetRequest() {

    mav_filter_state_t msg;

    msg.utime = GetTimestampNow();

    // copy in the states from the last position, but reset the covariance
    if (last_pose_msg != NULL) {
        msg.quat[0] = last_pose_msg->orientation[0];
        msg.quat[1] = last_pose_msg->orientation[1];
        msg.quat[2] = last_pose_msg->orientation[2];
        msg.quat[3] = last_pose_msg->orientation[3];
    } else {
        msg.quat[0] = 1;
        msg.quat[1] = 0;
        msg.quat[2] = 0;
        msg.quat[3] = 0;
    }

    msg.num_states = 21;

    double states[msg.num_states];

    if (last_pose_msg != NULL) {
        states[0] = last_pose_msg->rotation_rate[0];
        states[1] = last_pose_msg->rotation_rate[1];
        states[2] = last_pose_msg->rotation_rate[2];

        states[3] = last_pose_msg->vel[0];
        states[4] = last_pose_msg->vel[1];
        states[5] = last_pose_msg->vel[2];

    } else {
        states[0] = 0;
        states[1] = 0;
        states[2] = 0;

        states[3] = 0;
        states[4] = 0;
        states[5] = 0;
    }

    states[6] = 0;
    states[7] = 0;
    states[8] = 0;

    if (last_pose_msg != NULL) {

        states[9] = last_pose_msg->pos[0];
        states[10] = last_pose_msg->pos[1];
        states[11] = last_pose_msg->pos[2];

        states[12] = last_pose_msg->accel[0];
        states[13] = last_pose_msg->accel[1];
        states[14] = last_pose_msg->accel[2];

    } else {
        states[9] = 0;
        states[10] = 0;
        states[11] = 0;

        states[12] = 0;
        states[13] = 0;
        states[14] = 0;
    }

    states[15] = 0;
    states[16] = 0;
    states[17] = 0;
    states[18] = 0;
    states[19] = 0;
    states[20] = 0;

    msg.state = states;

    msg.num_cov_elements = 441;

    double covs[msg.num_cov_elements];

    for (int i = 0; i < msg.num_cov_elements; i++) {
        covs[i] = 0;
    }

    covs[66] = sigma0_vb * sigma0_vb;
    covs[88] = sigma0_vb * sigma0_vb;
    covs[110] = sigma0_vb * sigma0_vb;
    covs[132] = sigma0_chi_xy * sigma0_chi_xy;
    covs[154] = sigma0_chi_xy * sigma0_chi_xy;
    covs[176] = sigma0_chi_z * sigma0_chi_z;
    covs[198] = sigma0_delta_xy * sigma0_delta_xy;
    covs[220] = sigma0_delta_xy * sigma0_delta_xy;
    covs[242] = sigma0_delta_z * sigma0_delta_z;

    msg.cov = covs;

    mav_filter_state_t_publish(lcm, pronto_init_channel.c_str(), &msg);

    cout << "State estimator DEFAULT reset message sent." << endl;
}

void sighandler(int dum)
{
    printf("\n\nclosing... ");

    mav_pose_t_unsubscribe(lcm, mav_pose_t_sub);
    lcmt_tvlqr_controller_action_unsubscribe(lcm, tvlqr_controller_action_sub);
    mav_filter_state_t_unsubscribe(lcm, pronto_state_handler_sub);

    lcm_destroy (lcm);

    if (converter != NULL) {
        delete converter;
    }

    if (control != NULL) {
        delete control;
    }

    printf("done.\n");

    exit(0);
}
<|endoftext|>


<commit_before>#include "OsdConfig.h"
#include <QMessageBox>

OsdConfig::OsdConfig(QWidget *parent) : AP2ConfigWidget(parent)
{
    ui.setupUi(this);
    connect(ui.enablePushButton,SIGNAL(clicked()),this,SLOT(enableButtonClicked()));
}

OsdConfig::~OsdConfig()
{
}
void OsdConfig::enableButtonClicked()
{
    if (!m_uas)
    {
        showNullMAVErrorMessageBox();
        return;
    }
    m_uas->getParamManager()->setParameter(1,"SR0_EXT_STAT",2);
    m_uas->getParamManager()->setParameter(1,"SR0_EXTRA1",10);
    m_uas->getParamManager()->setParameter(1,"SR0_EXTRA2",10);
    m_uas->getParamManager()->setParameter(1,"SR0_EXTRA3",2);
    m_uas->getParamManager()->setParameter(1,"SR0_POSITION",3);
    m_uas->getParamManager()->setParameter(1,"SR0_RAW_CTRL",2);
    m_uas->getParamManager()->setParameter(1,"SR0_RAW_SENS",2);
    m_uas->getParamManager()->setParameter(1,"SR0_RC_CHAN",2);

    m_uas->getParamManager()->setParameter(1,"SR3_EXT_STAT",2);
    m_uas->getParamManager()->setParameter(1,"SR3_EXTRA1",10);
    m_uas->getParamManager()->setParameter(1,"SR3_EXTRA2",10);
    m_uas->getParamManager()->setParameter(1,"SR3_EXTRA3",2);
    m_uas->getParamManager()->setParameter(1,"SR3_POSITION",3);
    m_uas->getParamManager()->setParameter(1,"SR3_RAW_CTRL",2);
    m_uas->getParamManager()->setParameter(1,"SR3_RAW_SENS",2);
    m_uas->getParamManager()->setParameter(1,"SR3_RC_CHAN",2);
}
<commit_msg>Change so OsdConfig only sends requests to start telemetry on a single serial port<commit_after>#include "OsdConfig.h"
#include <QMessageBox>

OsdConfig::OsdConfig(QWidget *parent) : AP2ConfigWidget(parent)
{
    ui.setupUi(this);
    connect(ui.enablePushButton,SIGNAL(clicked()),this,SLOT(enableButtonClicked()));
}

OsdConfig::~OsdConfig()
{
}
void OsdConfig::enableButtonClicked()
{
    if (!m_uas)
    {
        showNullMAVErrorMessageBox();
        return;
    }
    m_uas->getParamManager()->setParameter(1,"SR0_EXT_STAT",2);
    m_uas->getParamManager()->setParameter(1,"SR0_EXTRA1",10);
    m_uas->getParamManager()->setParameter(1,"SR0_EXTRA2",10);
    m_uas->getParamManager()->setParameter(1,"SR0_EXTRA3",2);
    m_uas->getParamManager()->setParameter(1,"SR0_POSITION",3);
    m_uas->getParamManager()->setParameter(1,"SR0_RAW_CTRL",2);
    m_uas->getParamManager()->setParameter(1,"SR0_RAW_SENS",2);
    m_uas->getParamManager()->setParameter(1,"SR0_RC_CHAN",2);
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include "utilities/CUnitDefinitionDB.h"
#include "utilities/CUnitDefinition.h"
#include "utilities/CCopasiMessage.h"

//CCopasiVectorN(const std::string & name = "NoName",
//               const CCopasiContainer * pParent = NULL):

CUnitDefinitionDB::CUnitDefinitionDB(const std::string & name,
                                     const CCopasiContainer * pParent):
  CCopasiVectorN< CUnitDefinition >(name, pParent),
  mSymbolToUnitDefinitions()
{
}

//virtual
bool CUnitDefinitionDB::add(const CUnitDefinition & src)
{
  if (containsSymbol(src.getSymbol())) return false;

  // This form will construct a copy, before adding (inherited
  // from CCopasiVectorN). When the CUnitDefinition
  // copy constructor is called, an exception will be thrown if
  // the symbol is already in use.

  CUnitDefinition * pCopy = NULL;

  try
    {
      pCopy = new CUnitDefinition(src, CUnit::Avogadro, this);
    }

  catch (...)
    {
      return false;
    }

  return add(pCopy, true);
}

//virtual
bool CUnitDefinitionDB::add(CUnitDefinition * src, bool adopt)
{

  // If it's symbol is already present, this form will not add
  // a pointer to the src object, and will return false.
  bool success = false;

  if (containsSymbol(src->getSymbol()))
    success = false;
  else
    {
      CCopasiVectorN< CUnitDefinition >::add(src, adopt);
      mSymbolToUnitDefinitions[src->getSymbol()] = src;

      if (src->getSymbol() == "\xCE\xA9")
        {
          mSymbolToUnitDefinitions["O"] = src;
        }

      success = true;
    }

  return success;
}

//virtual
void CUnitDefinitionDB::remove(const size_t & index)
{
  mSymbolToUnitDefinitions.erase(operator [](index)->getSymbol());
  CCopasiVector< CUnitDefinition >::remove(index);
}

//virtual
bool CUnitDefinitionDB::remove(CCopasiObject * pObject)
{
  CUnitDefinition * pUnitDef = dynamic_cast< CUnitDefinition * >(pObject);

  if (pUnitDef)
    {
      mSymbolToUnitDefinitions.erase(pUnitDef->getSymbol());
    }

  return CCopasiVector< CUnitDefinition >::remove(pObject);
}

//virtual
void CUnitDefinitionDB::remove(const std::string & name)
{
  mSymbolToUnitDefinitions.erase(operator [](name)->getSymbol());
  CCopasiVectorN< CUnitDefinition >::remove(name);
}

bool CUnitDefinitionDB::containsSymbol(std::string symbol)
{
  if (mSymbolToUnitDefinitions.count(symbol))
    return true;
  else
    return false;
}

const CUnitDefinition * CUnitDefinitionDB::getUnitDefFromSymbol(std::string symbol)
{
  std::map<std::string, CUnitDefinition *>::const_iterator found = mSymbolToUnitDefinitions.find(symbol);

  if (found != mSymbolToUnitDefinitions.end())
    {
      return found->second;
    }

  return NULL;
}

bool CUnitDefinitionDB::changeSymbol(CUnitDefinition *pUnitDef, const std::string & symbol)
{
  if (pUnitDef->getObjectParent() != this) return true;

  std::map<std::string, CUnitDefinition *>::iterator found = mSymbolToUnitDefinitions.find(symbol);

  if (found != mSymbolToUnitDefinitions.end() &&
      found->second != pUnitDef) return false;

  found = mSymbolToUnitDefinitions.find(pUnitDef->getSymbol());

  if (found != mSymbolToUnitDefinitions.end())
    {
      if (pUnitDef->getSymbol() == symbol) return true;

      if (found->second == pUnitDef)
        {
          mSymbolToUnitDefinitions.erase(found);
        }
    }

  mSymbolToUnitDefinitions.insert(std::make_pair(symbol, pUnitDef));

  return true;
}
<commit_msg>Improved add functionality to assure symbol and name are unique.<commit_after>// Copyright (C) 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include "utilities/CUnitDefinitionDB.h"
#include "utilities/CUnitDefinition.h"
#include "utilities/CCopasiMessage.h"

//CCopasiVectorN(const std::string & name = "NoName",
//               const CCopasiContainer * pParent = NULL):

CUnitDefinitionDB::CUnitDefinitionDB(const std::string & name,
                                     const CCopasiContainer * pParent):
  CCopasiVectorN< CUnitDefinition >(name, pParent),
  mSymbolToUnitDefinitions()
{
}

//virtual
bool CUnitDefinitionDB::add(const CUnitDefinition & src)
{
  // This form will construct a copy, before adding (inherited
  // from CCopasiVectorN). When the CUnitDefinition
  // copy constructor is called, an exception will be thrown if
  // the symbol is already in use.
  // If it's symbol is already present, this form will not add
  // a pointer to the src object, and will return false.

  if (containsSymbol(src.getSymbol()) ||
      getIndex(src.getObjectName()) == C_INVALID_INDEX)
    {
      return false;
    }

  CUnitDefinition * pCopy = NULL;

  try
    {
      pCopy = new CUnitDefinition(src, CUnit::Avogadro, this);
    }

  catch (...)
    {
      return false;
    }

  return true;
}

//virtual
bool CUnitDefinitionDB::add(CUnitDefinition * src, bool adopt)
{

  // If it's symbol is already present, this form will not add
  // a pointer to the src object, and will return false.
  if (containsSymbol(src->getSymbol()) ||
      getIndex(src->getObjectName()) == C_INVALID_INDEX)
    {
      return false;
    }

  CCopasiVectorN< CUnitDefinition >::add(src, adopt);
  mSymbolToUnitDefinitions[src->getSymbol()] = src;

  if (src->getSymbol() == "\xCE\xA9")
    {
      mSymbolToUnitDefinitions["O"] = src;
    }

  return true;
}

//virtual
void CUnitDefinitionDB::remove(const size_t & index)
{
  remove(operator [](index));
}

//virtual
bool CUnitDefinitionDB::remove(CCopasiObject * pObject)
{
  CUnitDefinition * pUnitDef = dynamic_cast< CUnitDefinition * >(pObject);

  if (pUnitDef)
    {
      mSymbolToUnitDefinitions.erase(pUnitDef->getSymbol());
    }

  return CCopasiVector< CUnitDefinition >::remove(pObject);
}

//virtual
void CUnitDefinitionDB::remove(const std::string & name)
{
  remove(operator [](name));
}

bool CUnitDefinitionDB::containsSymbol(std::string symbol)
{
  if (mSymbolToUnitDefinitions.count(symbol))
    return true;
  else
    return false;
}

const CUnitDefinition * CUnitDefinitionDB::getUnitDefFromSymbol(std::string symbol)
{
  std::map<std::string, CUnitDefinition *>::const_iterator found = mSymbolToUnitDefinitions.find(symbol);

  if (found != mSymbolToUnitDefinitions.end())
    {
      return found->second;
    }

  return NULL;
}

bool CUnitDefinitionDB::changeSymbol(CUnitDefinition *pUnitDef, const std::string & symbol)
{
  if (pUnitDef->getObjectParent() != this) return true;

  std::map<std::string, CUnitDefinition *>::iterator found = mSymbolToUnitDefinitions.find(symbol);

  if (found != mSymbolToUnitDefinitions.end() &&
      found->second != pUnitDef) return false;

  found = mSymbolToUnitDefinitions.find(pUnitDef->getSymbol());

  if (found != mSymbolToUnitDefinitions.end())
    {
      if (pUnitDef->getSymbol() == symbol) return true;

      if (found->second == pUnitDef)
        {
          mSymbolToUnitDefinitions.erase(found);
        }
    }

  mSymbolToUnitDefinitions.insert(std::make_pair(symbol, pUnitDef));

  return true;
}
<|endoftext|>


<commit_before>#include "unittest/gtest.hpp"

#include "arch/streamed_tcp.hpp"

namespace unittest {

namespace {

/* `run_in_thread_pool()` starts a RethinkDB IO layer thread pool and calls the
given function within a coroutine inside of it. */

struct starter_t : public thread_message_t {
    thread_pool_t *tp;
    boost::function<void()> fun;
    starter_t(thread_pool_t *tp, boost::function<void()> fun) : tp(tp), fun(fun) { }
    void run() {
        fun();
        tp->shutdown();
    }
    void on_thread_switch() {
        coro_t::spawn_now(boost::bind(&starter_t::run, this));
    }
};
void run_in_thread_pool(boost::function<void()> fun) {
    thread_pool_t thread_pool(1);
    starter_t starter(&thread_pool, fun);
    thread_pool.run(&starter);
}

void handle_echo_conn(boost::scoped_ptr<streamed_tcp_conn_t> &conn) {
    while (conn->get_istream().good()) {
        // Read a line and send it back
        std::string str;
        conn->get_istream() >> str;
        if (!conn->get_istream().fail()) {
            conn->get_ostream() << str << std::endl; // endl causes flush()
        }
    }
}

}   /* anonymous namespace */

void run_tcp_stream_test() {
    int port = 10000 + rand() % 20000;
    streamed_tcp_listener_t listener(port, boost::bind(&handle_echo_conn, _1));

    streamed_tcp_conn_t conn("localhost", port);
    std::string test_str = "0";
    for (int i = 0; i < 8192 / 32; ++i, test_str += std::string(32, static_cast<char>('a' + (i % 26)))) {
        conn.get_ostream() << test_str.substr(0, i);
        conn.get_ostream() << test_str.substr(i) << std::endl; // endl causes flush()
        //fprintf(stderr, "sent stuff of size %lu\n", test_str.length());
        std::string str;
        conn.get_istream() >> str;
        //fprintf(stderr, "got stuff\n");
        EXPECT_TRUE(!conn.get_istream().fail());
        EXPECT_EQ(str, test_str);
    }
    conn.get_ostream().flush();
}
TEST(TCPStreamTest, StartStop) {
    run_in_thread_pool(&run_tcp_stream_test);
}

}<commit_msg>Added a test for boost::serialize in conjunction with streamed_tcp_conn_t.<commit_after>#include "unittest/gtest.hpp"

#include "arch/streamed_tcp.hpp"
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

namespace unittest {

namespace {

/* `run_in_thread_pool()` starts a RethinkDB IO layer thread pool and calls the
given function within a coroutine inside of it. */

struct starter_t : public thread_message_t {
    thread_pool_t *tp;
    boost::function<void()> fun;
    starter_t(thread_pool_t *tp, boost::function<void()> fun) : tp(tp), fun(fun) { }
    void run() {
        fun();
        tp->shutdown();
    }
    void on_thread_switch() {
        coro_t::spawn_now(boost::bind(&starter_t::run, this));
    }
};
void run_in_thread_pool(boost::function<void()> fun) {
    thread_pool_t thread_pool(1);
    starter_t starter(&thread_pool, fun);
    thread_pool.run(&starter);
}

void handle_echo_conn(boost::scoped_ptr<streamed_tcp_conn_t> &conn) {
    while (conn->get_istream().good()) {
        // Read a line and send it back
        std::string str;
        conn->get_istream() >> str;
        if (!conn->get_istream().fail()) {
            conn->get_ostream() << str << std::endl; // endl causes flush()
        }
    }
}

void handle_charwise_echo_conn(boost::scoped_ptr<streamed_tcp_conn_t> &conn) {
    while (conn->get_istream().good()) {
        // Read a char and send it back
        char c;
        conn->get_istream().read(&c, 1);
        if (!conn->get_istream().fail()) {
            conn->get_ostream().write(&c, 1).flush();
        }
    }
}

}   /* anonymous namespace */

void run_transmit_lines_test() {
    int port = 10000 + rand() % 20000;
    streamed_tcp_listener_t listener(port, boost::bind(&handle_echo_conn, _1));

    streamed_tcp_conn_t conn("localhost", port);
    std::string test_str = "0";
    for (int i = 0; i < 8192 / 32; ++i, test_str += std::string(32, static_cast<char>('a' + (i % 26)))) {
        conn.get_ostream() << test_str.substr(0, i);
        conn.get_ostream() << test_str.substr(i) << std::endl; // endl causes flush()
        //fprintf(stderr, "sent stuff of size %lu\n", test_str.length());
        std::string str;
        conn.get_istream() >> str;
        //fprintf(stderr, "got stuff\n");
        EXPECT_TRUE(!conn.get_istream().fail());
        EXPECT_EQ(str, test_str);
    }
    conn.get_ostream().flush();
}
TEST(TCPStreamTest, TransmitLines) {
    run_in_thread_pool(&run_transmit_lines_test);
}

void run_boost_serialize_test() {
    int port = 10000 + rand() % 20000;
    streamed_tcp_listener_t listener(port, boost::bind(&handle_charwise_echo_conn, _1));
    streamed_tcp_conn_t conn("localhost", port);

    {
        int i = 123;
        boost::archive::text_oarchive sender(conn.get_ostream());
        sender << i;
    }

    EXPECT_FALSE(conn.get_istream().fail());
    EXPECT_FALSE(conn.get_ostream().fail());

    {
        boost::archive::text_iarchive receiver(conn.get_istream());
        int i;
        receiver >> i;
        EXPECT_EQ(i, 123);
    }

    EXPECT_FALSE(conn.get_istream().fail());
    EXPECT_FALSE(conn.get_ostream().fail());
}
TEST(TCPStreamTest, BoostSerialize) {
    run_in_thread_pool(&run_boost_serialize_test);
}

}<|endoftext|>


<commit_before>// Copyright 2014 BitPay Inc.
// Copyright 2015 Syscoin Core Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdexcept>
#include <vector>
#include <limits>
#include <string>

#include "univalue.h"

namespace
{
static bool ParsePrechecks(const std::string& str)
{
    if (str.empty()) // No empty string allowed
        return false;
    if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed
        return false;
    if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
        return false;
    return true;
}

bool ParseInt32(const std::string& str, int32_t *out)
{
    if (!ParsePrechecks(str))
        return false;
    char *endp = NULL;
    errno = 0; // strtol will not set errno if valid
    long int n = strtol(str.c_str(), &endp, 10);
    if(out) *out = (int32_t)n;
    // Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow
    // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
    // platforms the size of these types may be different.
    return endp && *endp == 0 && !errno &&
        n >= std::numeric_limits<int32_t>::min() &&
        n <= std::numeric_limits<int32_t>::max();
}
// SYSCOIN
bool ParseUInt32(const std::string& str, uint32_t *out)
{
    if (!ParsePrechecks(str))
        return false;
    if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoul accepts these by default if they fit in the range
        return false;
    char *endp = NULL;
    errno = 0; // strtoul will not set errno if valid
    unsigned long int n = strtoul(str.c_str(), &endp, 10);
    if(out) *out = (uint32_t)n;
    // Note that strtoul returns a *unsigned long int*, so even if it doesn't report an over/underflow
    // we still have to check that the returned value is within the range of an *uint32_t*. On 64-bit
    // platforms the size of these types may be different.
    return endp && *endp == 0 && !errno &&
        n <= std::numeric_limits<uint32_t>::max();
}
bool ParseUInt64(const std::string& str, uint64_t *out)
{
    if (!ParsePrechecks(str))
        return false;
    if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoull accepts these by default if they fit in the range
        return false;
    char *endp = nullptr;
    errno = 0; // strtoull will not set errno if valid
    unsigned long long int n = strtoull(str.c_str(), &endp, 10);
    if(out) *out = (uint64_t)n;
    // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report an over/underflow
    // we still have to check that the returned value is within the range of an *uint64_t*.
    return endp && *endp == 0 && !errno &&
        n <= std::numeric_limits<uint64_t>::max();
}
bool ParseInt64(const std::string& str, int64_t *out)
{
    if (!ParsePrechecks(str))
        return false;
    char *endp = NULL;
    errno = 0; // strtoll will not set errno if valid
    long long int n = strtoll(str.c_str(), &endp, 10);
    if(out) *out = (int64_t)n;
    // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
    // we still have to check that the returned value is within the range of an *int64_t*.
    return endp && *endp == 0 && !errno &&
        n >= std::numeric_limits<int64_t>::min() &&
        n <= std::numeric_limits<int64_t>::max();
}

bool ParseDouble(const std::string& str, double *out)
{
    if (!ParsePrechecks(str))
        return false;
    if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
        return false;
    std::istringstream text(str);
    text.imbue(std::locale::classic());
    double result;
    text >> result;
    if(out) *out = result;
    return text.eof() && !text.fail();
}
}

const std::vector<std::string>& UniValue::getKeys() const
{
    if (typ != VOBJ)
        throw std::runtime_error("JSON value is not an object as expected");
    return keys;
}

const std::vector<UniValue>& UniValue::getValues() const
{
    if (typ != VOBJ && typ != VARR)
        throw std::runtime_error("JSON value is not an object or array as expected");
    return values;
}

bool UniValue::get_bool() const
{
    if (typ != VBOOL)
        throw std::runtime_error("JSON value is not a boolean as expected");
    return getBool();
}

const std::string& UniValue::get_str() const
{
    if (typ != VSTR)
        throw std::runtime_error("JSON value is not a string as expected");
    return getValStr();
}

int UniValue::get_int() const
{
    if (typ != VNUM)
        throw std::runtime_error("JSON value is not an integer as expected");
    int32_t retval;
    if (!ParseInt32(getValStr(), &retval))
        throw std::runtime_error("JSON integer out of range");
    return retval;
}
// SYSCOIN
uint32_t UniValue::get_uint() const
{
    if (typ != VNUM && typ != VSTR)
        throw std::runtime_error("JSON value is not an integer or string as expected");
    uint32_t retval;
    if (!ParseUInt32(getValStr(), &retval))
        throw std::runtime_error("JSON integer out of range, value: " + getValStr());
    return retval;
}
int64_t UniValue::get_int64() const
{
    if (typ != VNUM)
        throw std::runtime_error("JSON value is not an integer as expected");
    int64_t retval;
    if (!ParseInt64(getValStr(), &retval))
        throw std::runtime_error("JSON integer out of range");
    return retval;
}

double UniValue::get_real() const
{
    if (typ != VNUM)
        throw std::runtime_error("JSON value is not a number as expected");
    double retval;
    if (!ParseDouble(getValStr(), &retval))
        throw std::runtime_error("JSON double out of range");
    return retval;
}

const UniValue& UniValue::get_obj() const
{
    if (typ != VOBJ)
        throw std::runtime_error("JSON value is not an object as expected");
    return *this;
}

const UniValue& UniValue::get_array() const
{
    if (typ != VARR)
        throw std::runtime_error("JSON value is not an array as expected");
    return *this;
}

<commit_msg>fix nullptr issue in univalue<commit_after>// Copyright 2014 BitPay Inc.
// Copyright 2015 Syscoin Core Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdexcept>
#include <vector>
#include <limits>
#include <string>

#include "univalue.h"

namespace
{
static bool ParsePrechecks(const std::string& str)
{
    if (str.empty()) // No empty string allowed
        return false;
    if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed
        return false;
    if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
        return false;
    return true;
}

bool ParseInt32(const std::string& str, int32_t *out)
{
    if (!ParsePrechecks(str))
        return false;
    char *endp = NULL;
    errno = 0; // strtol will not set errno if valid
    long int n = strtol(str.c_str(), &endp, 10);
    if(out) *out = (int32_t)n;
    // Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow
    // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
    // platforms the size of these types may be different.
    return endp && *endp == 0 && !errno &&
        n >= std::numeric_limits<int32_t>::min() &&
        n <= std::numeric_limits<int32_t>::max();
}
// SYSCOIN
bool ParseUInt32(const std::string& str, uint32_t *out)
{
    if (!ParsePrechecks(str))
        return false;
    if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoul accepts these by default if they fit in the range
        return false;
    char *endp = NULL;
    errno = 0; // strtoul will not set errno if valid
    unsigned long int n = strtoul(str.c_str(), &endp, 10);
    if(out) *out = (uint32_t)n;
    // Note that strtoul returns a *unsigned long int*, so even if it doesn't report an over/underflow
    // we still have to check that the returned value is within the range of an *uint32_t*. On 64-bit
    // platforms the size of these types may be different.
    return endp && *endp == 0 && !errno &&
        n <= std::numeric_limits<uint32_t>::max();
}
bool ParseUInt64(const std::string& str, uint64_t *out)
{
    if (!ParsePrechecks(str))
        return false;
    if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoull accepts these by default if they fit in the range
        return false;
    char *endp = NULL;
    errno = 0; // strtoull will not set errno if valid
    unsigned long long int n = strtoull(str.c_str(), &endp, 10);
    if(out) *out = (uint64_t)n;
    // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report an over/underflow
    // we still have to check that the returned value is within the range of an *uint64_t*.
    return endp && *endp == 0 && !errno &&
        n <= std::numeric_limits<uint64_t>::max();
}
bool ParseInt64(const std::string& str, int64_t *out)
{
    if (!ParsePrechecks(str))
        return false;
    char *endp = NULL;
    errno = 0; // strtoll will not set errno if valid
    long long int n = strtoll(str.c_str(), &endp, 10);
    if(out) *out = (int64_t)n;
    // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
    // we still have to check that the returned value is within the range of an *int64_t*.
    return endp && *endp == 0 && !errno &&
        n >= std::numeric_limits<int64_t>::min() &&
        n <= std::numeric_limits<int64_t>::max();
}

bool ParseDouble(const std::string& str, double *out)
{
    if (!ParsePrechecks(str))
        return false;
    if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
        return false;
    std::istringstream text(str);
    text.imbue(std::locale::classic());
    double result;
    text >> result;
    if(out) *out = result;
    return text.eof() && !text.fail();
}
}

const std::vector<std::string>& UniValue::getKeys() const
{
    if (typ != VOBJ)
        throw std::runtime_error("JSON value is not an object as expected");
    return keys;
}

const std::vector<UniValue>& UniValue::getValues() const
{
    if (typ != VOBJ && typ != VARR)
        throw std::runtime_error("JSON value is not an object or array as expected");
    return values;
}

bool UniValue::get_bool() const
{
    if (typ != VBOOL)
        throw std::runtime_error("JSON value is not a boolean as expected");
    return getBool();
}

const std::string& UniValue::get_str() const
{
    if (typ != VSTR)
        throw std::runtime_error("JSON value is not a string as expected");
    return getValStr();
}

int UniValue::get_int() const
{
    if (typ != VNUM)
        throw std::runtime_error("JSON value is not an integer as expected");
    int32_t retval;
    if (!ParseInt32(getValStr(), &retval))
        throw std::runtime_error("JSON integer out of range");
    return retval;
}
// SYSCOIN
uint32_t UniValue::get_uint() const
{
    if (typ != VNUM && typ != VSTR)
        throw std::runtime_error("JSON value is not an integer or string as expected");
    uint32_t retval;
    if (!ParseUInt32(getValStr(), &retval))
        throw std::runtime_error("JSON integer out of range, value: " + getValStr());
    return retval;
}
int64_t UniValue::get_int64() const
{
    if (typ != VNUM)
        throw std::runtime_error("JSON value is not an integer as expected");
    int64_t retval;
    if (!ParseInt64(getValStr(), &retval))
        throw std::runtime_error("JSON integer out of range");
    return retval;
}

double UniValue::get_real() const
{
    if (typ != VNUM)
        throw std::runtime_error("JSON value is not a number as expected");
    double retval;
    if (!ParseDouble(getValStr(), &retval))
        throw std::runtime_error("JSON double out of range");
    return retval;
}

const UniValue& UniValue::get_obj() const
{
    if (typ != VOBJ)
        throw std::runtime_error("JSON value is not an object as expected");
    return *this;
}

const UniValue& UniValue::get_array() const
{
    if (typ != VARR)
        throw std::runtime_error("JSON value is not an array as expected");
    return *this;
}

<|endoftext|>


<commit_before>#include "Components/Wizard.hpp"
#include "Components/Weapon.hpp"
#include "Components/Item.hpp"
#include "Collision/CollisionRect.hpp"
#include "Collision/CollisionHandler.hpp"
#include "Calc.hpp"
#include <iostream>

Wizard::Wizard(RenderLayers layer, const int health, Textures textureId,
        const ResourceHolder<sf::Texture, Textures> &textureHolder,
        const SpriteSheetMapHolder &spriteSheetMapHolder,
        std::vector<Warrior*> &possibleTargetsInWord)
: Warrior(layer, health, textureId, textureHolder, spriteSheetMapHolder,
        possibleTargetsInWord)

, m_animFireballAttack( nullptr, false )
//, m_animStrongAttack( nullptr, false )
// Close Attack
, m_fireballAttackStanima{ 10.f }
/*
, m_closeAttackDamageMul{ 1.f }
// Round Attack
, m_isRoundAttacking{ false }
, m_roundAttackStanima{ 40.f }
, m_roundAttackDamageMul{ 1.5f }
, m_roundAttackCurRot{ 0.f }
, m_roundAttackTotalRot{ 360.f }
, m_roundAttackAngleVel{ 720.f }
, m_startRotationRoundAttack{ 0.f }
//, m_strongAttackStanima{ 30.f }
//, m_strongAttackDamageMul{ 3.f }
, m_isDodging{ false }
, m_dodgeStanima{ 30.f }
, m_dodgeVelocity{ 300.f }
, m_totalDodgeTime{ 0.2 }
, m_curDodgeTime{ 0.f }
*/
{
    setVelocity(70.f);
    // Animation
    std::vector<AnimationStepMovement>  stickMovementStepsFireball;
    stickMovementStepsFireball.push_back({ -2.f, { 0, 1 },  0.1f });
    stickMovementStepsFireball.push_back({ 2.f, { 0, 1 },  0.1f });
    m_animFireballAttack.setMovementSteps(stickMovementStepsFireball);
    /*
    std::vector<AnimationStepRotation>  swordRoationStepsCloseAtt;
    swordRoationStepsCloseAtt.push_back({ 0.f, -60.f,  0.3f });
    m_animFireballAttack.setRotationSteps(swordRoationStepsCloseAtt);
    */
    std::unique_ptr<Weapon> stick(new Weapon(RenderLayers::WEAPON, 10.f,
                textureHolder.get(textureId),
                spriteSheetMapHolder.getRectData(textureId, "stick")));
    stick->setType(WorldObjectTypes::WEAPON);
    stick->setPosition(0.f, 0.f);
    stick->setOrigin(-10.f, 0.f);
    std::unique_ptr<CollisionShape> collisionShapeSword(new CollisionRect(
                { stick->getSpriteWidth(), stick->getSpriteHeight() }));
    stick->setCollisionShape(std::move(collisionShapeSword));
    setWeapon(stick.get());
    attachChild(std::move(stick));

    std::unique_ptr<CollisionShape> closeCombatArea(new CollisionCircle(9.f));
    m_closeCombatArea = std::move(closeCombatArea);
    m_closeCombatArea->setParent(this);
    m_closeCombatArea->setPosition(9.f, 0.f);
    m_closeCombatArea->setDraw(true);
}

Wizard::~Wizard()
{

}

void Wizard::drawCurrent(sf::RenderTarget &target, sf::RenderStates states) const
{
    Warrior::drawCurrent(target, states);
}

void Wizard::updateCurrent(float dt)
{
    Warrior::updateCurrent(dt);
    if (m_animFireballAttack.isRunning())
    {
        m_animFireballAttack.update(dt);
    }
    /*
    if(m_isDodging)
    {
        m_curDodgeTime += dt;
        moveInDirection(m_dodgeDir, m_dodgeVelocity * dt);
        if (m_curDodgeTime > m_totalDodgeTime)
        {
            stopDodging();
        }
    }
    else if(m_isRoundAttacking)
    {
        m_roundAttackCurRot += m_roundAttackAngleVel * dt;
        setRotation(m_startRotationRoundAttack + m_roundAttackCurRot);
        if (m_roundAttackCurRot >= m_roundAttackTotalRot)
        {
            stopRoundAttack();
        }
    }
    else
    {
        Warrior::updateCurrent(dt);
        if (m_weapon)
        {
            if (m_animCloseAttack.isRunning())
            {
                m_animCloseAttack.update(dt);
            }
            else
            {
                m_weapon->setIsCollisionCheckOn(false);
            }
        }
    }
    */
}

void Wizard::onCommandCurrent(const Command &command, float dt)
{
    // Do command handling of parent class
    //Entity::onCommand(command, dt);
    Warrior::onCommandCurrent(command, dt);
    if (command.getWorldObjectType() & m_type)
    {
        m_currentVelocity = 0.f;
        m_currentDirection.x = 0.f;
        m_currentDirection.y = 0.f;
        switch (command.getCommandType())
        {
            case CommandTypes::ACTION1:
                startFireballAttack();
                break;
            case CommandTypes::ACTION2:
                //startDodging();
                break;
            case CommandTypes::ACTION3:
                //startRoundAttack();
                break;
            /*
            case CommandTypes::START_BLOCKING:
                startBlocking();
                break;
            case CommandTypes::STOP_BLOCKING:
                stopBlocking();
                break;
            */
            default:
                break;

        }

        // Move is the same as setPosition(getPosition() + offset) of the sf::Transformable class
        //move(m_currentVelocity * dt);
        //moveInDirection(m_currentDirection, m_currentVelocity * dt);
        moveInActualDirection(m_currentVelocity * dt);
    }
}

void Wizard::updateAI(float dt)
{
    /*
    m_isMoving = false;
    Warrior::updateAI(dt);
    if (!m_actualTarget)
    {
        return;
    }

    lookAt(m_actualTarget->getPosition());
    CollisionInfo collisionInfo = m_closeCombatArea->isColliding(*m_actualTarget->getCollisionShape());
    if (collisionInfo.isCollision())
    {
        startCloseAttack();
    }
    else
    {
        // Follow target
        m_currentVelocity = m_velocity;
        m_currentDirection = m_actualTarget->getWorldPosition() - getWorldPosition();
        m_isMoving = true;
        moveInActualDirection(m_currentVelocity * dt);
    }
    */
}

void Wizard::startFireballAttack()
{
    if (m_weapon && !m_animFireballAttack.isRunning() &&
            m_currentStamina >= m_fireballAttackStanima)
    {
        m_animFireballAttack.start();
        SceneNode* rootNode{ getRootSceneNode() };

        std::vector<sf::IntRect> frameRects;
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_1"));
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_2"));
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_3"));
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_4"));
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_5"));
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_6"));
        std::unique_ptr<SpriteNode> fireball{
            std::make_unique<SpriteNode>(RenderLayers::WEAPON,
                    m_textureHolder.get(Textures::FIREBALL),
                    frameRects,
                    true,
                    0.5f) };
        fireball->setVelocity(200.f);
        fireball->setPosition(getWorldPosition());
        fireball->setRotation(getRotation());
        fireball->setCurrentDirection(
                Calc::degAngleToDirectionVector(fireball->getRotation() + 90.f));
        rootNode->attachChild(std::move(fireball));
        //removeStanima(m_fireballAttackStanima);
    }
    /*
    if (m_weapon && !m_animCloseAttack.isRunning() &&
            m_currentStamina >= m_closeAttackStanima)
    {
        m_animCloseAttack.start();
        m_weapon->setIsCollisionCheckOn(true);
        m_weapon->setDamageMultiplicator(m_closeAttackDamageMul);
        m_weapon->startNewAttack();
        removeStanima(m_closeAttackStanima);
    }
    */
}
/*
void Wizard::startCloseAttack()
{
    if (m_weapon != nullptr)
    {
        std::cout << "Weapon is not null\n";
    }
    if (m_weapon && !m_animCloseAttack.isRunning() &&
            m_currentStamina >= m_closeAttackStanima)
    {
        m_animCloseAttack.start();
        m_weapon->setIsCollisionCheckOn(true);
        m_weapon->setDamageMultiplicator(m_closeAttackDamageMul);
        m_weapon->startNewAttack();
        removeStanima(m_closeAttackStanima);
    }
}
void Wizard::startCloseAttack()
{
    if (m_weapon != nullptr)
    {
        std::cout << "Weapon is not null\n";
    }
    if (m_weapon && !m_animCloseAttack.isRunning() &&
            m_currentStamina >= m_closeAttackStanima)
    {
        m_animCloseAttack.start();
        m_weapon->setIsCollisionCheckOn(true);
        m_weapon->setDamageMultiplicator(m_closeAttackDamageMul);
        m_weapon->startNewAttack();
        removeStanima(m_closeAttackStanima);
    }
}

void Wizard::startRoundAttack()
{
    if (!m_isDodging && !m_isRoundAttacking &&
            m_currentStamina >= m_roundAttackStanima && m_weapon)
    {
        m_isRoundAttacking = true;
        m_roundAttackCurRot = 0.f;
        m_startRotationRoundAttack = getRotation();
        m_weapon->setRotation(270.f);
        m_weapon->setIsCollisionCheckOn(true);
        m_weapon->setDamageMultiplicator(m_roundAttackDamageMul);
        m_weapon->startNewAttack();
        removeStanima(m_roundAttackStanima);
    }
}

void Wizard::stopRoundAttack()
{
    m_isRoundAttacking = false;
    m_weapon->setRotation(0.f);
    m_weapon->setIsCollisionCheckOn(false);
}

void Wizard::startDodging()
{
    if (!m_isRoundAttacking && m_currentStamina >= m_dodgeStanima)
    {
        makeTransparent();
        setIsCollisionCheckOn(false);
        m_isDodging = true;
        m_curDodgeTime = 0.f;
        // The dodge direction is the direction where the runner looking at
        m_dodgeDir = Calc::degAngleToDirectionVector(getRotation());
        removeStanima(m_dodgeStanima);
    }
}

void Wizard::stopDodging()
{
    m_isDodging = false;
    setIsCollisionCheckOn(true);
    makeInTransparent();
}
*/
void Wizard::weaponAdded()
{
    m_animFireballAttack.setParent(m_weapon);
}
<commit_msg>Fix position of wizards stick<commit_after>#include "Components/Wizard.hpp"
#include "Components/Weapon.hpp"
#include "Components/Item.hpp"
#include "Collision/CollisionRect.hpp"
#include "Collision/CollisionHandler.hpp"
#include "Calc.hpp"
#include <iostream>

Wizard::Wizard(RenderLayers layer, const int health, Textures textureId,
        const ResourceHolder<sf::Texture, Textures> &textureHolder,
        const SpriteSheetMapHolder &spriteSheetMapHolder,
        std::vector<Warrior*> &possibleTargetsInWord)
: Warrior(layer, health, textureId, textureHolder, spriteSheetMapHolder,
        possibleTargetsInWord)

, m_animFireballAttack( nullptr, false )
//, m_animStrongAttack( nullptr, false )
// Close Attack
, m_fireballAttackStanima{ 10.f }
/*
, m_closeAttackDamageMul{ 1.f }
// Round Attack
, m_isRoundAttacking{ false }
, m_roundAttackStanima{ 40.f }
, m_roundAttackDamageMul{ 1.5f }
, m_roundAttackCurRot{ 0.f }
, m_roundAttackTotalRot{ 360.f }
, m_roundAttackAngleVel{ 720.f }
, m_startRotationRoundAttack{ 0.f }
//, m_strongAttackStanima{ 30.f }
//, m_strongAttackDamageMul{ 3.f }
, m_isDodging{ false }
, m_dodgeStanima{ 30.f }
, m_dodgeVelocity{ 300.f }
, m_totalDodgeTime{ 0.2 }
, m_curDodgeTime{ 0.f }
*/
{
    setVelocity(70.f);
    // Animation
    std::vector<AnimationStepMovement>  stickMovementStepsFireball;
    stickMovementStepsFireball.push_back({ -2.f, { 0, 1 },  0.1f });
    stickMovementStepsFireball.push_back({ 2.f, { 0, 1 },  0.1f });
    m_animFireballAttack.setMovementSteps(stickMovementStepsFireball);
    /*
    std::vector<AnimationStepRotation>  swordRoationStepsCloseAtt;
    swordRoationStepsCloseAtt.push_back({ 0.f, -60.f,  0.3f });
    m_animFireballAttack.setRotationSteps(swordRoationStepsCloseAtt);
    */
    std::unique_ptr<Weapon> stick(new Weapon(RenderLayers::WEAPON, 10.f,
                textureHolder.get(textureId),
                spriteSheetMapHolder.getRectData(textureId, "stick")));
    stick->setType(WorldObjectTypes::WEAPON);
    stick->setPosition(0.f, 0.f);
    stick->setOrigin(0.f, -10.f);
    std::unique_ptr<CollisionShape> collisionShapeSword(new CollisionRect(
                { stick->getSpriteWidth(), stick->getSpriteHeight() }));
    stick->setCollisionShape(std::move(collisionShapeSword));
    setWeapon(stick.get());
    attachChild(std::move(stick));

    std::unique_ptr<CollisionShape> closeCombatArea(new CollisionCircle(9.f));
    m_closeCombatArea = std::move(closeCombatArea);
    m_closeCombatArea->setParent(this);
    m_closeCombatArea->setPosition(9.f, 0.f);
    m_closeCombatArea->setDraw(true);
}

Wizard::~Wizard()
{

}

void Wizard::drawCurrent(sf::RenderTarget &target, sf::RenderStates states) const
{
    Warrior::drawCurrent(target, states);
}

void Wizard::updateCurrent(float dt)
{
    Warrior::updateCurrent(dt);
    if (m_animFireballAttack.isRunning())
    {
        m_animFireballAttack.update(dt);
    }
    /*
    if(m_isDodging)
    {
        m_curDodgeTime += dt;
        moveInDirection(m_dodgeDir, m_dodgeVelocity * dt);
        if (m_curDodgeTime > m_totalDodgeTime)
        {
            stopDodging();
        }
    }
    else if(m_isRoundAttacking)
    {
        m_roundAttackCurRot += m_roundAttackAngleVel * dt;
        setRotation(m_startRotationRoundAttack + m_roundAttackCurRot);
        if (m_roundAttackCurRot >= m_roundAttackTotalRot)
        {
            stopRoundAttack();
        }
    }
    else
    {
        Warrior::updateCurrent(dt);
        if (m_weapon)
        {
            if (m_animCloseAttack.isRunning())
            {
                m_animCloseAttack.update(dt);
            }
            else
            {
                m_weapon->setIsCollisionCheckOn(false);
            }
        }
    }
    */
}

void Wizard::onCommandCurrent(const Command &command, float dt)
{
    // Do command handling of parent class
    //Entity::onCommand(command, dt);
    Warrior::onCommandCurrent(command, dt);
    if (command.getWorldObjectType() & m_type)
    {
        m_currentVelocity = 0.f;
        m_currentDirection.x = 0.f;
        m_currentDirection.y = 0.f;
        switch (command.getCommandType())
        {
            case CommandTypes::ACTION1:
                startFireballAttack();
                break;
            case CommandTypes::ACTION2:
                //startDodging();
                break;
            case CommandTypes::ACTION3:
                //startRoundAttack();
                break;
            /*
            case CommandTypes::START_BLOCKING:
                startBlocking();
                break;
            case CommandTypes::STOP_BLOCKING:
                stopBlocking();
                break;
            */
            default:
                break;

        }

        // Move is the same as setPosition(getPosition() + offset) of the sf::Transformable class
        //move(m_currentVelocity * dt);
        //moveInDirection(m_currentDirection, m_currentVelocity * dt);
        moveInActualDirection(m_currentVelocity * dt);
    }
}

void Wizard::updateAI(float dt)
{
    /*
    m_isMoving = false;
    Warrior::updateAI(dt);
    if (!m_actualTarget)
    {
        return;
    }

    lookAt(m_actualTarget->getPosition());
    CollisionInfo collisionInfo = m_closeCombatArea->isColliding(*m_actualTarget->getCollisionShape());
    if (collisionInfo.isCollision())
    {
        startCloseAttack();
    }
    else
    {
        // Follow target
        m_currentVelocity = m_velocity;
        m_currentDirection = m_actualTarget->getWorldPosition() - getWorldPosition();
        m_isMoving = true;
        moveInActualDirection(m_currentVelocity * dt);
    }
    */
}

void Wizard::startFireballAttack()
{
    if (m_weapon && !m_animFireballAttack.isRunning() &&
            m_currentStamina >= m_fireballAttackStanima)
    {
        m_animFireballAttack.start();
        SceneNode* rootNode{ getRootSceneNode() };

        std::vector<sf::IntRect> frameRects;
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_1"));
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_2"));
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_3"));
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_4"));
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_5"));
        frameRects.push_back(
            m_spriteSheetMapHolder.getRectData(Textures::FIREBALL, "fireball_6"));
        std::unique_ptr<SpriteNode> fireball{
            std::make_unique<SpriteNode>(RenderLayers::WEAPON,
                    m_textureHolder.get(Textures::FIREBALL),
                    frameRects,
                    true,
                    0.5f) };
        fireball->setVelocity(200.f);
        fireball->setPosition(getWorldPosition());
        fireball->setRotation(getRotation());
        fireball->setCurrentDirection(
                Calc::degAngleToDirectionVector(fireball->getRotation() + 90.f));
        rootNode->attachChild(std::move(fireball));
        //removeStanima(m_fireballAttackStanima);
    }
    /*
    if (m_weapon && !m_animCloseAttack.isRunning() &&
            m_currentStamina >= m_closeAttackStanima)
    {
        m_animCloseAttack.start();
        m_weapon->setIsCollisionCheckOn(true);
        m_weapon->setDamageMultiplicator(m_closeAttackDamageMul);
        m_weapon->startNewAttack();
        removeStanima(m_closeAttackStanima);
    }
    */
}
/*
void Wizard::startCloseAttack()
{
    if (m_weapon != nullptr)
    {
        std::cout << "Weapon is not null\n";
    }
    if (m_weapon && !m_animCloseAttack.isRunning() &&
            m_currentStamina >= m_closeAttackStanima)
    {
        m_animCloseAttack.start();
        m_weapon->setIsCollisionCheckOn(true);
        m_weapon->setDamageMultiplicator(m_closeAttackDamageMul);
        m_weapon->startNewAttack();
        removeStanima(m_closeAttackStanima);
    }
}
void Wizard::startCloseAttack()
{
    if (m_weapon != nullptr)
    {
        std::cout << "Weapon is not null\n";
    }
    if (m_weapon && !m_animCloseAttack.isRunning() &&
            m_currentStamina >= m_closeAttackStanima)
    {
        m_animCloseAttack.start();
        m_weapon->setIsCollisionCheckOn(true);
        m_weapon->setDamageMultiplicator(m_closeAttackDamageMul);
        m_weapon->startNewAttack();
        removeStanima(m_closeAttackStanima);
    }
}

void Wizard::startRoundAttack()
{
    if (!m_isDodging && !m_isRoundAttacking &&
            m_currentStamina >= m_roundAttackStanima && m_weapon)
    {
        m_isRoundAttacking = true;
        m_roundAttackCurRot = 0.f;
        m_startRotationRoundAttack = getRotation();
        m_weapon->setRotation(270.f);
        m_weapon->setIsCollisionCheckOn(true);
        m_weapon->setDamageMultiplicator(m_roundAttackDamageMul);
        m_weapon->startNewAttack();
        removeStanima(m_roundAttackStanima);
    }
}

void Wizard::stopRoundAttack()
{
    m_isRoundAttacking = false;
    m_weapon->setRotation(0.f);
    m_weapon->setIsCollisionCheckOn(false);
}

void Wizard::startDodging()
{
    if (!m_isRoundAttacking && m_currentStamina >= m_dodgeStanima)
    {
        makeTransparent();
        setIsCollisionCheckOn(false);
        m_isDodging = true;
        m_curDodgeTime = 0.f;
        // The dodge direction is the direction where the runner looking at
        m_dodgeDir = Calc::degAngleToDirectionVector(getRotation());
        removeStanima(m_dodgeStanima);
    }
}

void Wizard::stopDodging()
{
    m_isDodging = false;
    setIsCollisionCheckOn(true);
    makeInTransparent();
}
*/
void Wizard::weaponAdded()
{
    m_animFireballAttack.setParent(m_weapon);
}
<|endoftext|>


<commit_before>/****************************************************************************
** libebml : parse EBML files, see http://embl.sourceforge.net/
**
** <file/class description>
**
** Copyright (C) 2002-2010 Steve Lhomme.  All rights reserved.
**
** This file is part of libebml.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
** See http://www.gnu.org/licenses/lgpl-2.1.html for LGPL licensing information.
**
** Contact license@matroska.org if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/

/*!
  \file
  \version \$Id$
  \author Steve Lhomme     <robux4 @ users.sf.net>
  \author Jory Stone       <jcsston @ toughguy.net>
*/

#include <cassert>

#include "ebml/EbmlUnicodeString.h"

#include "lib/utf8-cpp/source/utf8/checked.h"

START_LIBEBML_NAMESPACE

// ===================== UTFstring class ===================

UTFstring::UTFstring()
  :_Length(0)
  ,_Data(NULL)
{}

UTFstring::UTFstring(const wchar_t * _aBuf)
  :_Length(0)
  ,_Data(NULL)
{
  *this = _aBuf;
}

UTFstring::UTFstring(std::wstring const &_aBuf)
  :_Length(0)
  ,_Data(NULL)
{
  *this = _aBuf.c_str();
}

UTFstring::~UTFstring()
{
  delete [] _Data;
}

UTFstring::UTFstring(const UTFstring & _aBuf)
  :_Length(0)
  ,_Data(NULL)
{
  *this = _aBuf.c_str();
}

UTFstring & UTFstring::operator=(const UTFstring & _aBuf)
{
  *this = _aBuf.c_str();
  return *this;
}

UTFstring::operator const wchar_t*() const {return _Data;}

UTFstring & UTFstring::operator=(const wchar_t * _aBuf)
{
  delete [] _Data;
  if (_aBuf == NULL) {
    _Data = new wchar_t[1];
    _Data[0] = 0;
    UpdateFromUCS2();
    return *this;
  }

  size_t aLen;
  for (aLen=0; _aBuf[aLen] != 0; aLen++);
  _Length = aLen;
  _Data = new wchar_t[_Length+1];
  for (aLen=0; _aBuf[aLen] != 0; aLen++) {
    _Data[aLen] = _aBuf[aLen];
  }
  _Data[aLen] = 0;
  UpdateFromUCS2();
  return *this;
}

UTFstring & UTFstring::operator=(wchar_t _aChar)
{
  delete [] _Data;
  _Data = new wchar_t[2];
  _Length = 1;
  _Data[0] = _aChar;
  _Data[1] = 0;
  UpdateFromUCS2();
  return *this;
}

bool UTFstring::operator==(const UTFstring& _aStr) const
{
  if ((_Data == NULL) && (_aStr._Data == NULL))
    return true;
  if ((_Data == NULL) || (_aStr._Data == NULL))
    return false;
  return wcscmp_internal(_Data, _aStr._Data);
}

void UTFstring::SetUTF8(const std::string & _aStr)
{
  UTF8string = _aStr;
  UpdateFromUTF8();
}

/*!
  \see RFC 2279
*/
void UTFstring::UpdateFromUTF8()
{
  // Only convert up to the first \0 character if present.
  std::string::iterator End = UTF8string.end(), Current = UTF8string.begin();
  while ((Current != End) && *Current)
    ++Current;

  std::wstring Temp;
  ::utf8::utf8to16(UTF8string.begin(), Current, std::back_inserter(Temp));

  delete [] _Data;
  _Length = Temp.length();
  _Data   = new wchar_t[_Length + 1];

  std::memcpy(_Data, Temp.c_str(), sizeof(wchar_t) * (_Length + 1));
}

void UTFstring::UpdateFromUCS2()
{
  UTF8string.clear();

  if (!_Data)
    return;

  // Only convert up to the first \0 character if present.
  size_t Current = 0;
  while ((Current < _Length) && _Data[Current])
    ++Current;

  ::utf8::utf16to8(_Data, _Data + Current, std::back_inserter(UTF8string));
}

bool UTFstring::wcscmp_internal(const wchar_t *str1, const wchar_t *str2)
{
  size_t Index=0;
  while (str1[Index] == str2[Index] && str1[Index] != 0) {
    Index++;
  }
  return (str1[Index] == str2[Index]);
}

// ===================== EbmlUnicodeString class ===================

EbmlUnicodeString::EbmlUnicodeString()
  :EbmlElement(0, false)
{
  SetDefaultSize(0);
}

EbmlUnicodeString::EbmlUnicodeString(const UTFstring & aDefaultValue)
  :EbmlElement(0, true), Value(aDefaultValue), DefaultValue(aDefaultValue)
{
  SetDefaultSize(0);
  SetDefaultIsSet();
}

EbmlUnicodeString::EbmlUnicodeString(const EbmlUnicodeString & ElementToClone)
  :EbmlElement(ElementToClone)
  ,Value(ElementToClone.Value)
  ,DefaultValue(ElementToClone.DefaultValue)
{
}

void EbmlUnicodeString::SetDefaultValue(UTFstring & aValue)
{
  assert(!DefaultISset());
  DefaultValue = aValue;
  SetDefaultIsSet();
}

const UTFstring & EbmlUnicodeString::DefaultVal() const
{
  assert(DefaultISset());
  return DefaultValue;
}

/*!
\note limited to UCS-2
\todo handle exception on errors
*/
filepos_t EbmlUnicodeString::RenderData(IOCallback & output, bool /* bForceRender */, bool /* bWithDefault */)
{
  uint32 Result = Value.GetUTF8().length();

  if (Result != 0) {
    output.writeFully(Value.GetUTF8().c_str(), Result);
  }

  if (Result < GetDefaultSize()) {
    // pad the rest with 0
    binary *Pad = new (std::nothrow) binary[GetDefaultSize() - Result];
    if (Pad != NULL) {
      memset(Pad, 0x00, GetDefaultSize() - Result);
      output.writeFully(Pad, GetDefaultSize() - Result);

      Result = GetDefaultSize();
      delete [] Pad;
    }
  }

  return Result;
}

EbmlUnicodeString::operator const UTFstring &() const {return Value;}

EbmlUnicodeString & EbmlUnicodeString::operator=(const UTFstring & NewString)
{
  Value = NewString;
  SetValueIsSet();
  return *this;
}

EbmlUnicodeString &EbmlUnicodeString::SetValue(UTFstring const &NewValue) {
  return *this = NewValue;
}

EbmlUnicodeString &EbmlUnicodeString::SetValueUTF8(std::string const &NewValue) {
  UTFstring NewValueUTFstring;
  NewValueUTFstring.SetUTF8(NewValue);
  return *this = NewValueUTFstring;
}

UTFstring EbmlUnicodeString::GetValue() const {
  return Value;
}

std::string EbmlUnicodeString::GetValueUTF8() const {
  return Value.GetUTF8();
}

/*!
\note limited to UCS-2
*/
uint64 EbmlUnicodeString::UpdateSize(bool bWithDefault, bool /* bForceRender */)
{
  if (!bWithDefault && IsDefaultValue())
    return 0;

  SetSize_(Value.GetUTF8().length());
  if (GetSize() < GetDefaultSize())
    SetSize_(GetDefaultSize());

  return GetSize();
}

/*!
  \note limited to UCS-2
*/
filepos_t EbmlUnicodeString::ReadData(IOCallback & input, ScopeMode ReadFully)
{
  if (ReadFully != SCOPE_NO_DATA) {
    if (GetSize() == 0) {
      Value = UTFstring::value_type(0);
      SetValueIsSet();
    } else {
      char *Buffer = new (std::nothrow) char[GetSize()+1];
      if (Buffer == NULL) {
        // impossible to read, skip it
        input.setFilePointer(GetSize(), seek_current);
      } else {
        input.readFully(Buffer, GetSize());
        if (Buffer[GetSize()-1] != 0) {
          Buffer[GetSize()] = 0;
        }

        Value.SetUTF8(Buffer); // implicit conversion to std::string
        delete [] Buffer;
        SetValueIsSet();
      }
    }
  }

  return GetSize();
}

END_LIBEBML_NAMESPACE
<commit_msg>EbmlUnicodeString: catch UTF-8/UCS2 conversion exceptions<commit_after>/****************************************************************************
** libebml : parse EBML files, see http://embl.sourceforge.net/
**
** <file/class description>
**
** Copyright (C) 2002-2010 Steve Lhomme.  All rights reserved.
**
** This file is part of libebml.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
** See http://www.gnu.org/licenses/lgpl-2.1.html for LGPL licensing information.
**
** Contact license@matroska.org if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/

/*!
  \file
  \version \$Id$
  \author Steve Lhomme     <robux4 @ users.sf.net>
  \author Jory Stone       <jcsston @ toughguy.net>
*/

#include <cassert>

#include "ebml/EbmlUnicodeString.h"

#include "lib/utf8-cpp/source/utf8/checked.h"

START_LIBEBML_NAMESPACE

// ===================== UTFstring class ===================

UTFstring::UTFstring()
  :_Length(0)
  ,_Data(NULL)
{}

UTFstring::UTFstring(const wchar_t * _aBuf)
  :_Length(0)
  ,_Data(NULL)
{
  *this = _aBuf;
}

UTFstring::UTFstring(std::wstring const &_aBuf)
  :_Length(0)
  ,_Data(NULL)
{
  *this = _aBuf.c_str();
}

UTFstring::~UTFstring()
{
  delete [] _Data;
}

UTFstring::UTFstring(const UTFstring & _aBuf)
  :_Length(0)
  ,_Data(NULL)
{
  *this = _aBuf.c_str();
}

UTFstring & UTFstring::operator=(const UTFstring & _aBuf)
{
  *this = _aBuf.c_str();
  return *this;
}

UTFstring::operator const wchar_t*() const {return _Data;}

UTFstring & UTFstring::operator=(const wchar_t * _aBuf)
{
  delete [] _Data;
  if (_aBuf == NULL) {
    _Data = new wchar_t[1];
    _Data[0] = 0;
    UpdateFromUCS2();
    return *this;
  }

  size_t aLen;
  for (aLen=0; _aBuf[aLen] != 0; aLen++);
  _Length = aLen;
  _Data = new wchar_t[_Length+1];
  for (aLen=0; _aBuf[aLen] != 0; aLen++) {
    _Data[aLen] = _aBuf[aLen];
  }
  _Data[aLen] = 0;
  UpdateFromUCS2();
  return *this;
}

UTFstring & UTFstring::operator=(wchar_t _aChar)
{
  delete [] _Data;
  _Data = new wchar_t[2];
  _Length = 1;
  _Data[0] = _aChar;
  _Data[1] = 0;
  UpdateFromUCS2();
  return *this;
}

bool UTFstring::operator==(const UTFstring& _aStr) const
{
  if ((_Data == NULL) && (_aStr._Data == NULL))
    return true;
  if ((_Data == NULL) || (_aStr._Data == NULL))
    return false;
  return wcscmp_internal(_Data, _aStr._Data);
}

void UTFstring::SetUTF8(const std::string & _aStr)
{
  UTF8string = _aStr;
  UpdateFromUTF8();
}

/*!
  \see RFC 2279
*/
void UTFstring::UpdateFromUTF8()
{
  // Only convert up to the first \0 character if present.
  std::string::iterator End = UTF8string.end(), Current = UTF8string.begin();
  while ((Current != End) && *Current)
    ++Current;

  std::wstring Temp;
  try {
    ::utf8::utf8to16(UTF8string.begin(), Current, std::back_inserter(Temp));
  } catch (::utf8::invalid_code_point &) {
  } catch (::utf8::invalid_utf8 &) {
  }

  delete [] _Data;
  _Length = Temp.length();
  _Data   = new wchar_t[_Length + 1];

  std::memcpy(_Data, Temp.c_str(), sizeof(wchar_t) * (_Length + 1));
}

void UTFstring::UpdateFromUCS2()
{
  UTF8string.clear();

  if (!_Data)
    return;

  // Only convert up to the first \0 character if present.
  size_t Current = 0;
  while ((Current < _Length) && _Data[Current])
    ++Current;

  try {
    ::utf8::utf16to8(_Data, _Data + Current, std::back_inserter(UTF8string));
  } catch (::utf8::invalid_code_point &) {
  } catch (::utf8::invalid_utf16 &) {
  }
}

bool UTFstring::wcscmp_internal(const wchar_t *str1, const wchar_t *str2)
{
  size_t Index=0;
  while (str1[Index] == str2[Index] && str1[Index] != 0) {
    Index++;
  }
  return (str1[Index] == str2[Index]);
}

// ===================== EbmlUnicodeString class ===================

EbmlUnicodeString::EbmlUnicodeString()
  :EbmlElement(0, false)
{
  SetDefaultSize(0);
}

EbmlUnicodeString::EbmlUnicodeString(const UTFstring & aDefaultValue)
  :EbmlElement(0, true), Value(aDefaultValue), DefaultValue(aDefaultValue)
{
  SetDefaultSize(0);
  SetDefaultIsSet();
}

EbmlUnicodeString::EbmlUnicodeString(const EbmlUnicodeString & ElementToClone)
  :EbmlElement(ElementToClone)
  ,Value(ElementToClone.Value)
  ,DefaultValue(ElementToClone.DefaultValue)
{
}

void EbmlUnicodeString::SetDefaultValue(UTFstring & aValue)
{
  assert(!DefaultISset());
  DefaultValue = aValue;
  SetDefaultIsSet();
}

const UTFstring & EbmlUnicodeString::DefaultVal() const
{
  assert(DefaultISset());
  return DefaultValue;
}

/*!
\note limited to UCS-2
\todo handle exception on errors
*/
filepos_t EbmlUnicodeString::RenderData(IOCallback & output, bool /* bForceRender */, bool /* bWithDefault */)
{
  uint32 Result = Value.GetUTF8().length();

  if (Result != 0) {
    output.writeFully(Value.GetUTF8().c_str(), Result);
  }

  if (Result < GetDefaultSize()) {
    // pad the rest with 0
    binary *Pad = new (std::nothrow) binary[GetDefaultSize() - Result];
    if (Pad != NULL) {
      memset(Pad, 0x00, GetDefaultSize() - Result);
      output.writeFully(Pad, GetDefaultSize() - Result);

      Result = GetDefaultSize();
      delete [] Pad;
    }
  }

  return Result;
}

EbmlUnicodeString::operator const UTFstring &() const {return Value;}

EbmlUnicodeString & EbmlUnicodeString::operator=(const UTFstring & NewString)
{
  Value = NewString;
  SetValueIsSet();
  return *this;
}

EbmlUnicodeString &EbmlUnicodeString::SetValue(UTFstring const &NewValue) {
  return *this = NewValue;
}

EbmlUnicodeString &EbmlUnicodeString::SetValueUTF8(std::string const &NewValue) {
  UTFstring NewValueUTFstring;
  NewValueUTFstring.SetUTF8(NewValue);
  return *this = NewValueUTFstring;
}

UTFstring EbmlUnicodeString::GetValue() const {
  return Value;
}

std::string EbmlUnicodeString::GetValueUTF8() const {
  return Value.GetUTF8();
}

/*!
\note limited to UCS-2
*/
uint64 EbmlUnicodeString::UpdateSize(bool bWithDefault, bool /* bForceRender */)
{
  if (!bWithDefault && IsDefaultValue())
    return 0;

  SetSize_(Value.GetUTF8().length());
  if (GetSize() < GetDefaultSize())
    SetSize_(GetDefaultSize());

  return GetSize();
}

/*!
  \note limited to UCS-2
*/
filepos_t EbmlUnicodeString::ReadData(IOCallback & input, ScopeMode ReadFully)
{
  if (ReadFully != SCOPE_NO_DATA) {
    if (GetSize() == 0) {
      Value = UTFstring::value_type(0);
      SetValueIsSet();
    } else {
      char *Buffer = new (std::nothrow) char[GetSize()+1];
      if (Buffer == NULL) {
        // impossible to read, skip it
        input.setFilePointer(GetSize(), seek_current);
      } else {
        input.readFully(Buffer, GetSize());
        if (Buffer[GetSize()-1] != 0) {
          Buffer[GetSize()] = 0;
        }

        Value.SetUTF8(Buffer); // implicit conversion to std::string
        delete [] Buffer;
        SetValueIsSet();
      }
    }
  }

  return GetSize();
}

END_LIBEBML_NAMESPACE
<|endoftext|>


<commit_before>#include "volumebar.h"
#include "volumeoverlay.h"
#include "volumebarlogic.h"

#undef DEBUG
#include "../debug.h"

#include <MStatusIndicatorMenuPluginInterface>
#include <MLinearLayoutPolicy>
#include <MContainer>
#include <MSlider>
#include <MLabel>
#include <MLayout>
#include <MLocale>
#include <MTheme>

#include <QGraphicsLinearLayout>

#define SYSTEMUI_TRANSLATION "systemui-applets"

VolumeBar::VolumeBar (DuiStatusIndicatorMenuInterface &statusIndicatorMenu,
                      QGraphicsItem *parent) :
        MWidget (parent),
        m_bar (0),
        m_logic (0),
        m_overlay (0),
        m_hwkeys (0)
{
    SYS_DEBUG ("");
    Q_UNUSED(statusIndicatorMenu)

    m_logic = new VolumeBarLogic;
    m_overlay = new VolumeOverlay;

    QGraphicsLinearLayout *mainLayout =
        new QGraphicsLinearLayout (Qt::Vertical);

    setLayout (mainLayout);
    mainLayout->setContentsMargins (0, 0, 0, 0);

    MContainer *container = new MContainer;

    container->setHeaderVisible (false);

    MLayout *layout = new MLayout;
    MLinearLayoutPolicy *hbox =
        new MLinearLayoutPolicy (layout, Qt::Horizontal);
    container->setLayout (layout);

    //% "Volume"
    MLabel *label = new MLabel (qtTrId ("qtn_volume"));

    m_bar = new MSlider;
    m_bar->setMinLabelVisible (true);

    hbox->addItem (label, Qt::AlignLeft);
    hbox->addItem (m_bar, Qt::AlignRight);

    mainLayout->addItem (container);

    quint32 current_volume = m_logic->getVolume ();
    if (current_volume > 0)
        m_bar->setMinLabelIconID ("icon-m-common-volume");
    else
        m_bar->setMinLabelIconID ("icon-m-common-volume-off");

    m_bar->setRange (0, (int) m_logic->getMaxVolume () - 1);
    m_bar->setValue (current_volume);

    connect (m_bar, SIGNAL (valueChanged (int)),
             this, SLOT (sliderChanged (int)));

    connect (m_logic, SIGNAL (volumeChanged (quint32, quint32)),
             this, SLOT (volumeChanged (quint32, quint32)));

    connect (m_overlay, SIGNAL (VolumeChanged (int)),
             this, SLOT (overlayChanged (int)));

    m_hwkeys = new QmKeys (this);

    connect (m_hwkeys,
             SIGNAL (keyEvent (QmKeys::Key, QmKeys::State)),
             this,
             SLOT (hwKeyEvent (QmKeys::Key, QmKeys::State)));
}

VolumeBar::~VolumeBar ()
{
    //Free the resources here
    delete m_hwkeys;
    m_hwkeys = 0;

    delete m_logic;
    m_logic = 0;

    delete m_overlay;
    m_overlay = 0;
}

void
VolumeBar::sliderChanged (int val)
{
    m_logic->setVolume ((quint32) val);

    if (val > 0)
        m_bar->setMinLabelIconID ("icon-m-common-volume");
    else
        m_bar->setMinLabelIconID ("icon-m-common-volume-off");

#if defined (i386) && defined (DEBUG)
    m_overlay->UpdateVolume (val, (int) m_logic->getMaxVolume ());
#endif
}

void
VolumeBar::volumeChanged (quint32 val, quint32 max)
{
    SYS_DEBUG ("val = %d, max = %d", val, max);

    m_bar->blockSignals (true); // to avoid busy loop

    m_bar->setValue (0);
    m_bar->setRange (0, (int) max - 1);
    m_bar->setValue ((int) val);

    m_overlay->UpdateVolume ((int) val, (int) max);

    m_bar->blockSignals (false);
}

void
VolumeBar::overlayChanged (int val)
{
    // Set the volume value
    m_logic->setVolume ((quint32) val);

    // And then update the slider and its icon
    m_bar->blockSignals (true);
    m_bar->setValue (val);
    m_bar->blockSignals (false);

    if (val > 0)
        m_bar->setMinLabelIconID ("icon-m-common-volume");
    else
        m_bar->setMinLabelIconID ("icon-m-common-volume-off");
}

void
VolumeBar::hwKeyEvent (QmKeys::Key key, QmKeys::State state)
{
    SYS_DEBUG ("key = %d, state = %d");
    int change_val = 0;

    if (state == QmKeys::KeyUp)
        return;

    switch (key)
    {
        // TODO: check the orientation stuff from UI specs.
        case QmKeys::VolumeUp:
            change_val++;
            break;
        case QmKeys::VolumeDown:
            change_val--;
            break;
        default:
            // no-op for other hw-keys...
            return;
            break;
    }

    int current_volume = (int) m_logic->getVolume ();
    int max_volume = (int) m_logic->getMaxVolume ();

    current_volume += change_val;

    if (current_volume < 0)
        current_volume = 0;
    else if (current_volume >= max_volume)
        current_volume = max_volume - 1;

    // This sets the volume and update the slider ...
    overlayChanged (current_volume);
    // ... and show the overlay
    m_overlay->UpdateVolume (current_volume, max_volume);
}

<commit_msg>DuiControlPanelIf changed back<commit_after>#include "volumebar.h"
#include "volumeoverlay.h"
#include "volumebarlogic.h"

#undef DEBUG
#include "../debug.h"

#include <DuiStatusIndicatorMenuPluginInterface>
#include <MLinearLayoutPolicy>
#include <MContainer>
#include <MSlider>
#include <MLabel>
#include <MLayout>
#include <MLocale>
#include <MTheme>

#include <QGraphicsLinearLayout>

#define SYSTEMUI_TRANSLATION "systemui-applets"

VolumeBar::VolumeBar (DuiStatusIndicatorMenuInterface &statusIndicatorMenu,
                      QGraphicsItem *parent) :
        MWidget (parent),
        m_bar (0),
        m_logic (0),
        m_overlay (0),
        m_hwkeys (0)
{
    SYS_DEBUG ("");
    Q_UNUSED(statusIndicatorMenu)

    m_logic = new VolumeBarLogic;
    m_overlay = new VolumeOverlay;

    QGraphicsLinearLayout *mainLayout =
        new QGraphicsLinearLayout (Qt::Vertical);

    setLayout (mainLayout);
    mainLayout->setContentsMargins (0, 0, 0, 0);

    MContainer *container = new MContainer;

    container->setHeaderVisible (false);

    MLayout *layout = new MLayout;
    MLinearLayoutPolicy *hbox =
        new MLinearLayoutPolicy (layout, Qt::Horizontal);
    container->setLayout (layout);

    //% "Volume"
    MLabel *label = new MLabel (qtTrId ("qtn_volume"));

    m_bar = new MSlider;
    m_bar->setMinLabelVisible (true);

    hbox->addItem (label, Qt::AlignLeft);
    hbox->addItem (m_bar, Qt::AlignRight);

    mainLayout->addItem (container);

    quint32 current_volume = m_logic->getVolume ();
    if (current_volume > 0)
        m_bar->setMinLabelIconID ("icon-m-common-volume");
    else
        m_bar->setMinLabelIconID ("icon-m-common-volume-off");

    m_bar->setRange (0, (int) m_logic->getMaxVolume () - 1);
    m_bar->setValue (current_volume);

    connect (m_bar, SIGNAL (valueChanged (int)),
             this, SLOT (sliderChanged (int)));

    connect (m_logic, SIGNAL (volumeChanged (quint32, quint32)),
             this, SLOT (volumeChanged (quint32, quint32)));

    connect (m_overlay, SIGNAL (VolumeChanged (int)),
             this, SLOT (overlayChanged (int)));

    m_hwkeys = new QmKeys (this);

    connect (m_hwkeys,
             SIGNAL (keyEvent (QmKeys::Key, QmKeys::State)),
             this,
             SLOT (hwKeyEvent (QmKeys::Key, QmKeys::State)));
}

VolumeBar::~VolumeBar ()
{
    //Free the resources here
    delete m_hwkeys;
    m_hwkeys = 0;

    delete m_logic;
    m_logic = 0;

    delete m_overlay;
    m_overlay = 0;
}

void
VolumeBar::sliderChanged (int val)
{
    m_logic->setVolume ((quint32) val);

    if (val > 0)
        m_bar->setMinLabelIconID ("icon-m-common-volume");
    else
        m_bar->setMinLabelIconID ("icon-m-common-volume-off");

#if defined (i386) && defined (DEBUG)
    m_overlay->UpdateVolume (val, (int) m_logic->getMaxVolume ());
#endif
}

void
VolumeBar::volumeChanged (quint32 val, quint32 max)
{
    SYS_DEBUG ("val = %d, max = %d", val, max);

    m_bar->blockSignals (true); // to avoid busy loop

    m_bar->setValue (0);
    m_bar->setRange (0, (int) max - 1);
    m_bar->setValue ((int) val);

    m_overlay->UpdateVolume ((int) val, (int) max);

    m_bar->blockSignals (false);
}

void
VolumeBar::overlayChanged (int val)
{
    // Set the volume value
    m_logic->setVolume ((quint32) val);

    // And then update the slider and its icon
    m_bar->blockSignals (true);
    m_bar->setValue (val);
    m_bar->blockSignals (false);

    if (val > 0)
        m_bar->setMinLabelIconID ("icon-m-common-volume");
    else
        m_bar->setMinLabelIconID ("icon-m-common-volume-off");
}

void
VolumeBar::hwKeyEvent (QmKeys::Key key, QmKeys::State state)
{
    SYS_DEBUG ("key = %d, state = %d");
    int change_val = 0;

    if (state == QmKeys::KeyUp)
        return;

    switch (key)
    {
        // TODO: check the orientation stuff from UI specs.
        case QmKeys::VolumeUp:
            change_val++;
            break;
        case QmKeys::VolumeDown:
            change_val--;
            break;
        default:
            // no-op for other hw-keys...
            return;
            break;
    }

    int current_volume = (int) m_logic->getVolume ();
    int max_volume = (int) m_logic->getMaxVolume ();

    current_volume += change_val;

    if (current_volume < 0)
        current_volume = 0;
    else if (current_volume >= max_volume)
        current_volume = max_volume - 1;

    // This sets the volume and update the slider ...
    overlayChanged (current_volume);
    // ... and show the overlay
    m_overlay->UpdateVolume (current_volume, max_volume);
}

<|endoftext|>