<commit_before>#ifndef BFC_SOURCELOC_HPP
#define BFC_SOURCELOC_HPP

#include <cstddef>
#include <memory>
#include <ostream>
#include <string>

namespace bfc {

struct source_pos {
  off_t off;
  unsigned long row;
  unsigned long col;
};

static std::ostream &
operator<<(std::ostream &out, source_pos pos)
{
  return out << pos.row << ',' << pos.col;
}

class source_loc {

public:

  source_loc(source_pos begin, source_pos end, std::string name) noexcept :
    source_loc{begin, end, std::make_shared<std::string>(std::move(name))}
  {}

  source_loc(source_pos begin, source_pos end,
             std::shared_ptr<std::string> name) noexcept :
    begin_pos{begin}, end_pos{end}, source_name{name}
  {}

  source_pos begin(void) const noexcept
  {
    return begin_pos;
  }

  source_pos end(void) const noexcept
  {
    return end_pos;
  }

  const std::string &name(void) const noexcept
  {
    return *source_name;
  }

  source_loc with_pos(source_pos begin, source_pos end) const noexcept
  {
    return source_loc{begin, end, source_name};
  }

  void print(std::ostream &out) const
  {
    out << *source_name << ':' << begin_pos << '-' << end_pos;
  }

private:

  std::shared_ptr<std::string> source_name;
  source_pos begin_pos;
  source_pos end_pos;

};

static std::ostream &
operator<<(std::ostream &out, const source_loc &loc)
{
  loc.print(out);
  return out;
}

}

#endif /* !BFC_SOURCELOC_HPP */
<commit_msg>Remove off_t (since it's POSIX and not part of the C or C++ standards)<commit_after>#ifndef BFC_SOURCELOC_HPP
#define BFC_SOURCELOC_HPP

#include <cstddef>
#include <memory>
#include <ostream>
#include <string>

namespace bfc {

struct source_pos {
  unsigned long off;
  unsigned long row;
  unsigned long col;
};

static std::ostream &
operator<<(std::ostream &out, source_pos pos)
{
  return out << pos.row << ',' << pos.col;
}

class source_loc {

public:

  source_loc(source_pos begin, source_pos end, std::string name) noexcept :
    source_loc{begin, end, std::make_shared<std::string>(std::move(name))}
  {}

  source_loc(source_pos begin, source_pos end,
             std::shared_ptr<std::string> name) noexcept :
    begin_pos{begin}, end_pos{end}, source_name{name}
  {}

  source_pos begin(void) const noexcept
  {
    return begin_pos;
  }

  source_pos end(void) const noexcept
  {
    return end_pos;
  }

  const std::string &name(void) const noexcept
  {
    return *source_name;
  }

  source_loc with_pos(source_pos begin, source_pos end) const noexcept
  {
    return source_loc{begin, end, source_name};
  }

  void print(std::ostream &out) const
  {
    out << *source_name << ':' << begin_pos << '-' << end_pos;
  }

private:

  std::shared_ptr<std::string> source_name;
  source_pos begin_pos;
  source_pos end_pos;

};

static std::ostream &
operator<<(std::ostream &out, const source_loc &loc)
{
  loc.print(out);
  return out;
}

}

#endif /* !BFC_SOURCELOC_HPP */
<|endoftext|>


<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <iostream>
#include <fstream>
#include <exception>
#include <string>
#include <utility>
#include <map>
#include <iomanip>
#include <cstring>

#include <ArgumentList.hpp>
#include <utils.hpp>

int main(int argc, char * argv[]) {
  // DMs
  unsigned int nrDMs = 0;
  float firstDM = 0.0f;
  float stepDM = 0.0f;
  // Periods
  unsigned int nrPeriods = 0;
  unsigned int firstPeriod = 0;
  unsigned int stepPeriod = 0;
  // Sampling
  unsigned int nrSamplesPerSecond = 0;
  // I/O
  std::string outFilename;
  std::ifstream searchFile;
  std::ofstream outFile;
  // Data
  bool exclusive = false;
  bool * exclusionMapDM = 0;
  bool * exclusionMapP = 0;
  float percentile = 0;
  std::multimap< float, std::pair< unsigned int, unsigned int > > snrList;

  isa::utils::ArgumentList args(argc, argv);
  try {
    exclusive = args.getSwitch("-exclusive");
    if ( exclusive ) {
      nrDMs = args.getSwitchArgument< unsigned int >("-dms");
      nrPeriods = args.getSwitchArgument< unsigned int >("-periods");
    }
    outFilename = args.getSwitchArgument< std::string >("-output");
    firstDM = args.getSwitchArgument< float >("-dm_first");
    stepDM = args.getSwitchArgument< float >("-dm_step");
    firstPeriod = args.getSwitchArgument< unsigned int >("-period_first");
    stepPeriod = args.getSwitchArgument< unsigned int >("-period_step");
    nrSamplesPerSecond = args.getSwitchArgument< unsigned int >("-samples");
    percentile = args.getSwitchArgument< float >("-percentile");
  } catch ( isa::utils::EmptyCommandLine & err ) {
    std::cerr << args.getName() << " [-exclusive] -output ... -dm_first ... -dm_step ... -period_first ... -period_step ... -samples ... -percentile ... input" << std::endl;
    std::cerr << "\t -exclusive -dms ... -periods ..." << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  }

  // Read the SNR data
  try {
    while ( true ) {
      searchFile.open(args.getFirst< std::string >());

      while ( ! searchFile.eof() ) {
        std::string temp;
        unsigned int splitPoint = 0;
        unsigned int DM = 0;
        unsigned int period = 0;
        float snr = 0.0f;

        std::getline(searchFile, temp);
        if ( ! std::isdigit(temp[0]) ) {
          continue;
        }
        splitPoint = temp.find(" ");
        period = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        DM = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        snr = isa::utils::castToType< std::string, float >(temp);

        snrList.insert(std::make_pair(snr, std::make_pair(DM, period)));
      }
      searchFile.close();
    }
  } catch ( isa::utils::EmptyCommandLine & err ) {
  }

  // Print the percentile
  unsigned int lowerLimit = static_cast< unsigned int >((percentile * snrList.size()) / 100.0);
  unsigned int counter = snrList.size() - 1;

  if ( exclusive ) {
    exclusionMapDM = new bool [nrDMs];
    std::memset(reinterpret_cast< void * >(exclusionMapDM, 0, nrDMs * sizeof(bool)));
    exclusionMapP = new bool [nrPeriods];
    std::memset(reinterpret_cast< void * >(exclusionMapP, 0, nrDMs * sizeof(bool)));
  }
  outFile.open(outFilename);
  outFile << std::fixed;
  outFile << "# DMIndex DM periodIndex period snr" << std::endl;
  for ( std::multimap< float, std::pair< unsigned int, unsigned int> >::const_reverse_iterator item = snrList.crend(); counter >= lowerLimit; counter-- ) {
  ++item;
  if ( exclusive && (exclusionMapDM[(*item).second.first] || exclusionMapP[(*item).second.second]) ) {
    continue;
  } else if ( exclusionMapDM[(*item).second.first] || exclusionMapP[(*item).second.second] ) {
    exclusionMapDM[(*item).second.first] = true;
    exclusionMapP[(*item).second.second] = true;
  }
  outFile << std::setprecision(2);
  outFile << (*item).second.first << " " << firstDM + ((*item).second.first * stepDM) << " ";
  outFile << std::setprecision(6);
  outFile << (*item).second.second << " " << (firstPeriod + ((*item).second.second * stepPeriod)) / static_cast< float >(nrSamplesPerSecond) << " ";
  outFile << (*item).first << std::endl;
  }
  delete [] exclusionMapDM;
  delete [] exclusionMapP;
  outFile.close();

  return 0;
}

<commit_msg>Typo.<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <iostream>
#include <fstream>
#include <exception>
#include <string>
#include <utility>
#include <map>
#include <iomanip>
#include <cstring>

#include <ArgumentList.hpp>
#include <utils.hpp>

int main(int argc, char * argv[]) {
  // DMs
  unsigned int nrDMs = 0;
  float firstDM = 0.0f;
  float stepDM = 0.0f;
  // Periods
  unsigned int nrPeriods = 0;
  unsigned int firstPeriod = 0;
  unsigned int stepPeriod = 0;
  // Sampling
  unsigned int nrSamplesPerSecond = 0;
  // I/O
  std::string outFilename;
  std::ifstream searchFile;
  std::ofstream outFile;
  // Data
  bool exclusive = false;
  bool * exclusionMapDM = 0;
  bool * exclusionMapP = 0;
  float percentile = 0;
  std::multimap< float, std::pair< unsigned int, unsigned int > > snrList;

  isa::utils::ArgumentList args(argc, argv);
  try {
    exclusive = args.getSwitch("-exclusive");
    if ( exclusive ) {
      nrDMs = args.getSwitchArgument< unsigned int >("-dms");
      nrPeriods = args.getSwitchArgument< unsigned int >("-periods");
    }
    outFilename = args.getSwitchArgument< std::string >("-output");
    firstDM = args.getSwitchArgument< float >("-dm_first");
    stepDM = args.getSwitchArgument< float >("-dm_step");
    firstPeriod = args.getSwitchArgument< unsigned int >("-period_first");
    stepPeriod = args.getSwitchArgument< unsigned int >("-period_step");
    nrSamplesPerSecond = args.getSwitchArgument< unsigned int >("-samples");
    percentile = args.getSwitchArgument< float >("-percentile");
  } catch ( isa::utils::EmptyCommandLine & err ) {
    std::cerr << args.getName() << " [-exclusive] -output ... -dm_first ... -dm_step ... -period_first ... -period_step ... -samples ... -percentile ... input" << std::endl;
    std::cerr << "\t -exclusive -dms ... -periods ..." << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  }

  // Read the SNR data
  try {
    while ( true ) {
      searchFile.open(args.getFirst< std::string >());

      while ( ! searchFile.eof() ) {
        std::string temp;
        unsigned int splitPoint = 0;
        unsigned int DM = 0;
        unsigned int period = 0;
        float snr = 0.0f;

        std::getline(searchFile, temp);
        if ( ! std::isdigit(temp[0]) ) {
          continue;
        }
        splitPoint = temp.find(" ");
        period = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        DM = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        snr = isa::utils::castToType< std::string, float >(temp);

        snrList.insert(std::make_pair(snr, std::make_pair(DM, period)));
      }
      searchFile.close();
    }
  } catch ( isa::utils::EmptyCommandLine & err ) {
  }

  // Print the percentile
  unsigned int lowerLimit = static_cast< unsigned int >((percentile * snrList.size()) / 100.0);
  unsigned int counter = snrList.size() - 1;

  if ( exclusive ) {
    exclusionMapDM = new bool [nrDMs];
    std::memset(reinterpret_cast< void * >(exclusionMapDM), 0, nrDMs * sizeof(bool));
    exclusionMapP = new bool [nrPeriods];
    std::memset(reinterpret_cast< void * >(exclusionMapP), 0, nrDMs * sizeof(bool));
  }
  outFile.open(outFilename);
  outFile << std::fixed;
  outFile << "# DMIndex DM periodIndex period snr" << std::endl;
  for ( std::multimap< float, std::pair< unsigned int, unsigned int> >::const_reverse_iterator item = snrList.crend(); counter >= lowerLimit; counter-- ) {
  ++item;
  if ( exclusive && (exclusionMapDM[(*item).second.first] || exclusionMapP[(*item).second.second]) ) {
    continue;
  } else if ( exclusionMapDM[(*item).second.first] || exclusionMapP[(*item).second.second] ) {
    exclusionMapDM[(*item).second.first] = true;
    exclusionMapP[(*item).second.second] = true;
  }
  outFile << std::setprecision(2);
  outFile << (*item).second.first << " " << firstDM + ((*item).second.first * stepDM) << " ";
  outFile << std::setprecision(6);
  outFile << (*item).second.second << " " << (firstPeriod + ((*item).second.second * stepPeriod)) / static_cast< float >(nrSamplesPerSecond) << " ";
  outFile << (*item).first << std::endl;
  }
  delete [] exclusionMapDM;
  delete [] exclusionMapP;
  outFile.close();

  return 0;
}

<|endoftext|>


<commit_before>/***********************************************************************
    created:    Wed May 21 2014
    author:     Timotei Dolean <timotei21@gmail.com>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2014 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/views/ItemModel.h"

namespace CEGUI
{
//----------------------------------------------------------------------------//
const String ItemModel::EventChildrenWillBeAdded("ChildrenWillBeAdded");
const String ItemModel::EventChildrenAdded("ChildrenAdded");
const String ItemModel::EventChildrenWillBeRemoved("ChildrenWillBeRemoved");
const String ItemModel::EventChildrenRemoved("ChildrenRemoved");
const String ItemModel::EventChildrenDataWillChange;
const String ItemModel::EventChildrenDataChanged("ChildrenDataChanged");

//----------------------------------------------------------------------------//
std::ostream& operator<< (std::ostream& os, const ModelIndex& arg)
{
    return os << "CEGUI::ModelIndex(" << arg.d_modelData << ")";
}

//----------------------------------------------------------------------------//
ModelEventArgs::ModelEventArgs(ItemModel* item_model, ModelIndex parent_index, size_t start_id, size_t count /*= 1*/) :
    d_itemModel(item_model),
    d_parentIndex(parent_index),
    d_startId(start_id),
    d_count(count)
{
}

//----------------------------------------------------------------------------//
ModelIndex::ModelIndex(void* model_data /*= 0*/) :
    d_modelData(model_data)
{
}

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

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenWillBeAdded(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenWillBeAdded, args);
}

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenAdded(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenAdded, args);
}

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenWillBeRemoved(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenWillBeRemoved, args);
}

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenRemoved(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenRemoved, args);
}

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenDataWillChange(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenDataWillChange, args);
}

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenDataChanged(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenDataChanged, args);
}

//----------------------------------------------------------------------------//
bool ItemModel::areIndicesEqual(const ModelIndex& index1, const ModelIndex& index2) const
{
    return compareIndices(index1, index2) == 0;
}
}
<commit_msg>Add missing <ostream> include<commit_after>/***********************************************************************
    created:    Wed May 21 2014
    author:     Timotei Dolean <timotei21@gmail.com>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2014 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/views/ItemModel.h"

#include <ostream>

namespace CEGUI
{
//----------------------------------------------------------------------------//
const String ItemModel::EventChildrenWillBeAdded("ChildrenWillBeAdded");
const String ItemModel::EventChildrenAdded("ChildrenAdded");
const String ItemModel::EventChildrenWillBeRemoved("ChildrenWillBeRemoved");
const String ItemModel::EventChildrenRemoved("ChildrenRemoved");
const String ItemModel::EventChildrenDataWillChange;
const String ItemModel::EventChildrenDataChanged("ChildrenDataChanged");

//----------------------------------------------------------------------------//
std::ostream& operator<< (std::ostream& os, const ModelIndex& arg)
{
    return os << "CEGUI::ModelIndex(" << arg.d_modelData << ")";
}

//----------------------------------------------------------------------------//
ModelEventArgs::ModelEventArgs(ItemModel* item_model, ModelIndex parent_index, size_t start_id, size_t count /*= 1*/) :
    d_itemModel(item_model),
    d_parentIndex(parent_index),
    d_startId(start_id),
    d_count(count)
{
}

//----------------------------------------------------------------------------//
ModelIndex::ModelIndex(void* model_data /*= 0*/) :
    d_modelData(model_data)
{
}

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

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenWillBeAdded(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenWillBeAdded, args);
}

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenAdded(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenAdded, args);
}

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenWillBeRemoved(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenWillBeRemoved, args);
}

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenRemoved(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenRemoved, args);
}

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenDataWillChange(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenDataWillChange, args);
}

//----------------------------------------------------------------------------//
void ItemModel::notifyChildrenDataChanged(ModelIndex parent_index, size_t start_id, size_t count)
{
    ModelEventArgs args(this, parent_index, start_id, count);
    fireEvent(EventChildrenDataChanged, args);
}

//----------------------------------------------------------------------------//
bool ItemModel::areIndicesEqual(const ModelIndex& index1, const ModelIndex& index2) const
{
    return compareIndices(index1, index2) == 0;
}
}
<|endoftext|>


<commit_before>/***********************************************************************
	filename: 	CEGUISpinner.cpp
	created:	3/2/2005
	author:		Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/widgets/Spinner.h"
#include "CEGUI/widgets/PushButton.h"
#include "CEGUI/widgets/Editbox.h"
#include "CEGUI/Exceptions.h"
#include "CEGUI/WindowManager.h"
#include <stdio.h>
#include <sstream>
#include <iomanip>

// Start of CEGUI namespace section
namespace CEGUI
{
    const String Spinner::WidgetTypeName("CEGUI/Spinner");

    //////////////////////////////////////////////////////////////////////////
    // event strings
    const String Spinner::EventNamespace("Spinner");
    const String Spinner::EventValueChanged("ValueChanged");
    const String Spinner::EventStepChanged("StepChanged");
    const String Spinner::EventMaximumValueChanged("MaximumValueChanged");
    const String Spinner::EventMinimumValueChanged("MinimumValueChanged");
    const String Spinner::EventTextInputModeChanged("TextInputModeChanged");
    // Validator strings
    const String Spinner::FloatValidator("-?\\d*\\.?\\d*");
    const String Spinner::IntegerValidator("-?\\d*");
    const String Spinner::HexValidator("[0-9a-fA-F]*");
    const String Spinner::OctalValidator("[0-7]*");
    // component widget name strings
    const String Spinner::EditboxName( "__auto_editbox__" );
    const String Spinner::IncreaseButtonName( "__auto_incbtn__" );
    const String Spinner::DecreaseButtonName( "__auto_decbtn__" );
    //////////////////////////////////////////////////////////////////////////

    Spinner::Spinner(const String& type, const String& name) :
        Window(type, name),
        d_stepSize(1.0f),
        d_currentValue(1.0f),
        d_maxValue(32767.0f),
        d_minValue(-32768.0f),
        d_inputMode((TextInputMode)-1)
    {
        addSpinnerProperties();
    }

    Spinner::~Spinner(void)
    {
        // Nothing to do here.
    }

    void Spinner::initialiseComponents(void)
    {
        // get all the component widgets
        PushButton* increaseButton = getIncreaseButton();
        PushButton* decreaseButton = getDecreaseButton();
        Editbox* editbox = getEditbox();

        // setup component controls
        increaseButton->setPointerAutoRepeatEnabled(true);
        decreaseButton->setPointerAutoRepeatEnabled(true);

        // perform event subscriptions.
        increaseButton->subscribeEvent(Window::EventPointerPressHold, Event::Subscriber(&Spinner::handleIncreaseButton, this));
        decreaseButton->subscribeEvent(Window::EventPointerPressHold, Event::Subscriber(&Spinner::handleDecreaseButton, this));
        editbox->subscribeEvent(Window::EventTextChanged, Event::Subscriber(&Spinner::handleEditTextChange, this));

        // final initialisation
        setTextInputMode(Integer);
        setCurrentValue(0.0f);
        performChildWindowLayout();
    }

    double Spinner::getCurrentValue(void) const
    {
        return d_currentValue;
    }

    double Spinner::getStepSize(void) const
    {
        return d_stepSize;
    }

    double Spinner::getMaximumValue(void) const
    {
        return d_maxValue;
    }

    double Spinner::getMinimumValue(void) const
    {
        return d_minValue;
    }

    Spinner::TextInputMode Spinner::getTextInputMode(void) const
    {
        return d_inputMode;
    }

    void Spinner::setCurrentValue(double value)
    {
        if (value != d_currentValue)
        {
            // limit input value to within valid range for spinner
            value = ceguimax(ceguimin(value, d_maxValue), d_minValue);

            d_currentValue = value;

            WindowEventArgs args(this);
            onValueChanged(args);
        }
    }

    void Spinner::setStepSize(double step)
    {
        if (step != d_stepSize)
        {
            d_stepSize = step;

            WindowEventArgs args(this);
            onStepChanged(args);
        }
    }

    void Spinner::setMaximumValue(double maxValue)
    {
        if (maxValue != d_maxValue)
        {
            d_maxValue = maxValue;

            WindowEventArgs args(this);
            onMaximumValueChanged(args);
        }
    }

    void Spinner::setMinimumValue(double minVaue)
    {
        if (minVaue != d_minValue)
        {
            d_minValue = minVaue;

            WindowEventArgs args(this);
            onMinimumValueChanged(args);
        }
    }

    void Spinner::setTextInputMode(TextInputMode mode)
    {
        if (mode != d_inputMode)
        {
            switch (mode)
            {
            case FloatingPoint:
                getEditbox()->setValidationString(FloatValidator);
                break;
            case Integer:
                getEditbox()->setValidationString(IntegerValidator);
                break;
            case Hexadecimal:
                getEditbox()->setValidationString(HexValidator);
                break;
            case Octal:
                getEditbox()->setValidationString(OctalValidator);
                break;
            default:
                CEGUI_THROW(InvalidRequestException(
                    "An unknown TextInputMode was specified."));
            }

            d_inputMode = mode;

            WindowEventArgs args(this);
            onTextInputModeChanged(args);
        }
    }

    void Spinner::addSpinnerProperties(void)
    {
        const String& propertyOrigin = WidgetTypeName;

        CEGUI_DEFINE_PROPERTY(Spinner, double,
            "CurrentValue", "Property to get/set the current value of the spinner.  Value is a float.",
            &Spinner::setCurrentValue, &Spinner::getCurrentValue, 0.0f
        );

        CEGUI_DEFINE_PROPERTY(Spinner, double,
            "StepSize", "Property to get/set the step size of the spinner.  Value is a float.",
            &Spinner::setStepSize, &Spinner::getStepSize, 1.0f
        );

        CEGUI_DEFINE_PROPERTY(Spinner, double,
            "MinimumValue", "Property to get/set the minimum value setting of the spinner.  Value is a float.",
            &Spinner::setMinimumValue, &Spinner::getMinimumValue, -32768.000000f
        );

        CEGUI_DEFINE_PROPERTY(Spinner, double,
            "MaximumValue", "Property to get/set the maximum value setting of the spinner.  Value is a float.",
            &Spinner::setMaximumValue, &Spinner::getMaximumValue, 32767.000000f
        );

        CEGUI_DEFINE_PROPERTY(Spinner, Spinner::TextInputMode,
            "TextInputMode", "Property to get/set the TextInputMode setting for the spinner.  Value is \"FloatingPoint\", \"Integer\", \"Hexadecimal\", or \"Octal\".",
            &Spinner::setTextInputMode, &Spinner::getTextInputMode, Spinner::Integer
        );
    }

    double Spinner::getValueFromText(void) const
    {
        String tmpTxt(getEditbox()->getText());

        // handle empty and lone '-' or '.' cases
        if (tmpTxt.empty() || (tmpTxt == "-") || (tmpTxt == "."))
        {
            return 0.0f;
        }

        int res, tmp;
        uint utmp;
        double val;

        switch (d_inputMode)
        {
        case FloatingPoint:
            res = sscanf(tmpTxt.c_str(), "%lf", &val);
            break;
        case Integer:
            res = sscanf(tmpTxt.c_str(), "%d", &tmp);
            val = static_cast<double>(tmp);
            break;
        case Hexadecimal:
            res = sscanf(tmpTxt.c_str(), "%x", &utmp);
            val = static_cast<double>(utmp);
            break;
        case Octal:
            res = sscanf(tmpTxt.c_str(), "%o", &utmp);
            val = static_cast<double>(utmp);
            break;
        default:
            CEGUI_THROW(InvalidRequestException(
                "An unknown TextInputMode was encountered."));
        }

        if (res)
        {
            return val;
        }

        CEGUI_THROW(InvalidRequestException(
            "The string '" + getEditbox()->getText() +
            "' can not be converted to numerical representation."));
    }

    String Spinner::getTextFromValue(void) const
    {
        std::stringstream tmp;

        switch (d_inputMode)
        {
        case FloatingPoint:
            return CEGUI::PropertyHelper<float>::toString( static_cast<float>(d_currentValue) );
            break;
        case Integer:
            tmp << static_cast<int>(d_currentValue);
            break;
        case Hexadecimal:
            tmp << std::hex << std::uppercase << static_cast<int>(d_currentValue);
            break;
        case Octal:
            tmp << std::oct << static_cast<int>(d_currentValue);
            break;
        default:
            CEGUI_THROW(InvalidRequestException(
                "An unknown TextInputMode was encountered."));
        }

        return String(tmp.str().c_str());
    }

    void Spinner::onFontChanged(WindowEventArgs& e)
    {
        // Propagate to children
        getEditbox()->setFont(getFont());
        // Call base class handler
        Window::onFontChanged(e);
    }

    void Spinner::onTextChanged(WindowEventArgs& e)
    {
        Editbox* editbox = getEditbox();

        // update only if needed
        if (editbox->getText() != getText())
        {
            // done before doing base class processing so event subscribers see
            // 'updated' version.
            editbox->setText(getText());
            ++e.handled;

            Window::onTextChanged(e);
        }
    }

    void Spinner::onActivated(ActivationEventArgs& e)
    {
        if (!isActive())
        {
            Window::onActivated(e);

            Editbox* editbox = getEditbox();

            if (!editbox->isActive())
            {
                editbox->activate();
            }
        }
    }

    void Spinner::onValueChanged(WindowEventArgs& e)
    {
        Editbox* editbox = getEditbox();

        // mute to save doing unnecessary events work.
        bool wasMuted = editbox->isMuted();
        editbox->setMutedState(true);

        // Update text with new value.
        // (allow empty and '-' cases to equal 0 with no text change required)
        if (!(d_currentValue == 0 &&
              (editbox->getText().empty() || editbox->getText() == "-")))
        {
            editbox->setText(getTextFromValue());
        }
        // restore previous mute state.
        editbox->setMutedState(wasMuted);

        fireEvent(EventValueChanged, e, EventNamespace);
    }

    void Spinner::onStepChanged(WindowEventArgs& e)
    {
        fireEvent(EventStepChanged, e, EventNamespace);
    }

    void Spinner::onMaximumValueChanged(WindowEventArgs& e)
    {
        fireEvent(EventMaximumValueChanged, e, EventNamespace);

        if (d_currentValue > d_maxValue)
        {
            setCurrentValue(d_maxValue);
        }
    }

    void Spinner::onMinimumValueChanged(WindowEventArgs& e)
    {
        fireEvent(EventMinimumValueChanged, e, EventNamespace);

        if (d_currentValue < d_minValue)
        {
            setCurrentValue(d_minValue);
        }
    }

    void Spinner::onTextInputModeChanged(WindowEventArgs& e)
    {
        Editbox* editbox = getEditbox();
        // update edit box text to reflect new mode.
        // mute to save doing unnecessary events work.
        bool wasMuted = editbox->isMuted();
        editbox->setMutedState(true);
        // Update text with new value.
        editbox->setText(getTextFromValue());
        // restore previous mute state.
        editbox->setMutedState(wasMuted);

        fireEvent(EventTextInputModeChanged, e, EventNamespace);
    }

    bool Spinner::handleIncreaseButton(const EventArgs& e)
    {
        if (((const PointerEventArgs&)e).source == PS_Left)
        {
            setCurrentValue(d_currentValue + d_stepSize);
            return true;
        }

        return false;
    }

    bool Spinner::handleDecreaseButton(const EventArgs& e)
    {
        if (((const PointerEventArgs&)e).source == PS_Left)
        {
            setCurrentValue(d_currentValue - d_stepSize);
            return true;
        }

        return false;
    }

    bool Spinner::handleEditTextChange(const EventArgs&)
    {
        // set this windows text to match
        setText(getEditbox()->getText());
        // update value
        setCurrentValue(getValueFromText());
        return true;
    }

    PushButton* Spinner::getIncreaseButton() const
    {
        return static_cast<PushButton*>(getChild(IncreaseButtonName));
    }

    PushButton* Spinner::getDecreaseButton() const
    {
        return static_cast<PushButton*>(getChild(DecreaseButtonName));
    }

    Editbox* Spinner::getEditbox() const
    {
        return static_cast<Editbox*>(getChild(EditboxName));
    }

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

} // End of  CEGUI namespace section
<commit_msg>MOD: Fixing Spinner window text update on value change<commit_after>/***********************************************************************
	filename: 	CEGUISpinner.cpp
	created:	3/2/2005
	author:		Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/widgets/Spinner.h"
#include "CEGUI/widgets/PushButton.h"
#include "CEGUI/widgets/Editbox.h"
#include "CEGUI/Exceptions.h"
#include "CEGUI/WindowManager.h"
#include <stdio.h>
#include <sstream>
#include <iomanip>

// Start of CEGUI namespace section
namespace CEGUI
{
    const String Spinner::WidgetTypeName("CEGUI/Spinner");

    //////////////////////////////////////////////////////////////////////////
    // event strings
    const String Spinner::EventNamespace("Spinner");
    const String Spinner::EventValueChanged("ValueChanged");
    const String Spinner::EventStepChanged("StepChanged");
    const String Spinner::EventMaximumValueChanged("MaximumValueChanged");
    const String Spinner::EventMinimumValueChanged("MinimumValueChanged");
    const String Spinner::EventTextInputModeChanged("TextInputModeChanged");
    // Validator strings
    const String Spinner::FloatValidator("-?\\d*\\.?\\d*");
    const String Spinner::IntegerValidator("-?\\d*");
    const String Spinner::HexValidator("[0-9a-fA-F]*");
    const String Spinner::OctalValidator("[0-7]*");
    // component widget name strings
    const String Spinner::EditboxName( "__auto_editbox__" );
    const String Spinner::IncreaseButtonName( "__auto_incbtn__" );
    const String Spinner::DecreaseButtonName( "__auto_decbtn__" );
    //////////////////////////////////////////////////////////////////////////

    Spinner::Spinner(const String& type, const String& name) :
        Window(type, name),
        d_stepSize(1.0f),
        d_currentValue(1.0f),
        d_maxValue(32767.0f),
        d_minValue(-32768.0f),
        d_inputMode((TextInputMode)-1)
    {
        addSpinnerProperties();
    }

    Spinner::~Spinner(void)
    {
        // Nothing to do here.
    }

    void Spinner::initialiseComponents(void)
    {
        // get all the component widgets
        PushButton* increaseButton = getIncreaseButton();
        PushButton* decreaseButton = getDecreaseButton();
        Editbox* editbox = getEditbox();

        // setup component controls
        increaseButton->setPointerAutoRepeatEnabled(true);
        decreaseButton->setPointerAutoRepeatEnabled(true);

        // perform event subscriptions.
        increaseButton->subscribeEvent(Window::EventPointerPressHold, Event::Subscriber(&Spinner::handleIncreaseButton, this));
        decreaseButton->subscribeEvent(Window::EventPointerPressHold, Event::Subscriber(&Spinner::handleDecreaseButton, this));
        editbox->subscribeEvent(Window::EventTextChanged, Event::Subscriber(&Spinner::handleEditTextChange, this));

        // final initialisation
        setTextInputMode(Integer);
        setCurrentValue(0.0f);
        performChildWindowLayout();
    }

    double Spinner::getCurrentValue(void) const
    {
        return d_currentValue;
    }

    double Spinner::getStepSize(void) const
    {
        return d_stepSize;
    }

    double Spinner::getMaximumValue(void) const
    {
        return d_maxValue;
    }

    double Spinner::getMinimumValue(void) const
    {
        return d_minValue;
    }

    Spinner::TextInputMode Spinner::getTextInputMode(void) const
    {
        return d_inputMode;
    }

    void Spinner::setCurrentValue(double value)
    {
        if (value != d_currentValue)
        {
            // limit input value to within valid range for spinner
            value = ceguimax(ceguimin(value, d_maxValue), d_minValue);

            d_currentValue = value;

            WindowEventArgs args(this);
            onValueChanged(args);
        }
    }

    void Spinner::setStepSize(double step)
    {
        if (step != d_stepSize)
        {
            d_stepSize = step;

            WindowEventArgs args(this);
            onStepChanged(args);
        }
    }

    void Spinner::setMaximumValue(double maxValue)
    {
        if (maxValue != d_maxValue)
        {
            d_maxValue = maxValue;

            WindowEventArgs args(this);
            onMaximumValueChanged(args);
        }
    }

    void Spinner::setMinimumValue(double minVaue)
    {
        if (minVaue != d_minValue)
        {
            d_minValue = minVaue;

            WindowEventArgs args(this);
            onMinimumValueChanged(args);
        }
    }

    void Spinner::setTextInputMode(TextInputMode mode)
    {
        if (mode != d_inputMode)
        {
            switch (mode)
            {
            case FloatingPoint:
                getEditbox()->setValidationString(FloatValidator);
                break;
            case Integer:
                getEditbox()->setValidationString(IntegerValidator);
                break;
            case Hexadecimal:
                getEditbox()->setValidationString(HexValidator);
                break;
            case Octal:
                getEditbox()->setValidationString(OctalValidator);
                break;
            default:
                CEGUI_THROW(InvalidRequestException(
                    "An unknown TextInputMode was specified."));
            }

            d_inputMode = mode;

            WindowEventArgs args(this);
            onTextInputModeChanged(args);
        }
    }

    void Spinner::addSpinnerProperties(void)
    {
        const String& propertyOrigin = WidgetTypeName;

        CEGUI_DEFINE_PROPERTY(Spinner, double,
            "CurrentValue", "Property to get/set the current value of the spinner.  Value is a float.",
            &Spinner::setCurrentValue, &Spinner::getCurrentValue, 0.0f
        );

        CEGUI_DEFINE_PROPERTY(Spinner, double,
            "StepSize", "Property to get/set the step size of the spinner.  Value is a float.",
            &Spinner::setStepSize, &Spinner::getStepSize, 1.0f
        );

        CEGUI_DEFINE_PROPERTY(Spinner, double,
            "MinimumValue", "Property to get/set the minimum value setting of the spinner.  Value is a float.",
            &Spinner::setMinimumValue, &Spinner::getMinimumValue, -32768.000000f
        );

        CEGUI_DEFINE_PROPERTY(Spinner, double,
            "MaximumValue", "Property to get/set the maximum value setting of the spinner.  Value is a float.",
            &Spinner::setMaximumValue, &Spinner::getMaximumValue, 32767.000000f
        );

        CEGUI_DEFINE_PROPERTY(Spinner, Spinner::TextInputMode,
            "TextInputMode", "Property to get/set the TextInputMode setting for the spinner.  Value is \"FloatingPoint\", \"Integer\", \"Hexadecimal\", or \"Octal\".",
            &Spinner::setTextInputMode, &Spinner::getTextInputMode, Spinner::Integer
        );
    }

    double Spinner::getValueFromText(void) const
    {
        String tmpTxt(getEditbox()->getText());

        // handle empty and lone '-' or '.' cases
        if (tmpTxt.empty() || (tmpTxt == "-") || (tmpTxt == "."))
        {
            return 0.0f;
        }

        int res, tmp;
        uint utmp;
        double val;

        switch (d_inputMode)
        {
        case FloatingPoint:
            res = sscanf(tmpTxt.c_str(), "%lf", &val);
            break;
        case Integer:
            res = sscanf(tmpTxt.c_str(), "%d", &tmp);
            val = static_cast<double>(tmp);
            break;
        case Hexadecimal:
            res = sscanf(tmpTxt.c_str(), "%x", &utmp);
            val = static_cast<double>(utmp);
            break;
        case Octal:
            res = sscanf(tmpTxt.c_str(), "%o", &utmp);
            val = static_cast<double>(utmp);
            break;
        default:
            CEGUI_THROW(InvalidRequestException(
                "An unknown TextInputMode was encountered."));
        }

        if (res)
        {
            return val;
        }

        CEGUI_THROW(InvalidRequestException(
            "The string '" + getEditbox()->getText() +
            "' can not be converted to numerical representation."));
    }

    String Spinner::getTextFromValue(void) const
    {
        std::stringstream tmp;

        switch (d_inputMode)
        {
        case FloatingPoint:
            return CEGUI::PropertyHelper<float>::toString( static_cast<float>(d_currentValue) );
            break;
        case Integer:
            tmp << static_cast<int>(d_currentValue);
            break;
        case Hexadecimal:
            tmp << std::hex << std::uppercase << static_cast<int>(d_currentValue);
            break;
        case Octal:
            tmp << std::oct << static_cast<int>(d_currentValue);
            break;
        default:
            CEGUI_THROW(InvalidRequestException(
                "An unknown TextInputMode was encountered."));
        }

        return String(tmp.str().c_str());
    }

    void Spinner::onFontChanged(WindowEventArgs& e)
    {
        // Propagate to children
        getEditbox()->setFont(getFont());
        // Call base class handler
        Window::onFontChanged(e);
    }

    void Spinner::onTextChanged(WindowEventArgs& e)
    {
        Editbox* editbox = getEditbox();

        // update only if needed
        if (editbox->getText() != getText())
        {
            // done before doing base class processing so event subscribers see
            // 'updated' version.
            editbox->setText(getText());
            ++e.handled;

            Window::onTextChanged(e);
        }
    }

    void Spinner::onActivated(ActivationEventArgs& e)
    {
        if (!isActive())
        {
            Window::onActivated(e);

            Editbox* editbox = getEditbox();

            if (!editbox->isActive())
            {
                editbox->activate();
            }
        }
    }

    void Spinner::onValueChanged(WindowEventArgs& e)
    {
        Editbox* editbox = getEditbox();

        // mute to save doing unnecessary events work.
        bool wasMuted = editbox->isMuted();
        editbox->setMutedState(true);

        // Update editbox and spinner text with new value.
        // (allow empty and '-' cases to equal 0 with no text change required)
        if (!(d_currentValue == 0 &&
              (editbox->getText().empty() || editbox->getText() == "-")))
        {
            const CEGUI::String& valueString = getTextFromValue();
            editbox->setText(valueString);
            setText(valueString);
        }
        // restore previous mute state.
        editbox->setMutedState(wasMuted);

        fireEvent(EventValueChanged, e, EventNamespace);
    }

    void Spinner::onStepChanged(WindowEventArgs& e)
    {
        fireEvent(EventStepChanged, e, EventNamespace);
    }

    void Spinner::onMaximumValueChanged(WindowEventArgs& e)
    {
        fireEvent(EventMaximumValueChanged, e, EventNamespace);

        if (d_currentValue > d_maxValue)
        {
            setCurrentValue(d_maxValue);
        }
    }

    void Spinner::onMinimumValueChanged(WindowEventArgs& e)
    {
        fireEvent(EventMinimumValueChanged, e, EventNamespace);

        if (d_currentValue < d_minValue)
        {
            setCurrentValue(d_minValue);
        }
    }

    void Spinner::onTextInputModeChanged(WindowEventArgs& e)
    {
        Editbox* editbox = getEditbox();
        // update edit box text to reflect new mode.
        // mute to save doing unnecessary events work.
        bool wasMuted = editbox->isMuted();
        editbox->setMutedState(true);
        // Update text with new value.
        editbox->setText(getTextFromValue());
        // restore previous mute state.
        editbox->setMutedState(wasMuted);

        fireEvent(EventTextInputModeChanged, e, EventNamespace);
    }

    bool Spinner::handleIncreaseButton(const EventArgs& e)
    {
        if (((const PointerEventArgs&)e).source == PS_Left)
        {
            setCurrentValue(d_currentValue + d_stepSize);
            return true;
        }

        return false;
    }

    bool Spinner::handleDecreaseButton(const EventArgs& e)
    {
        if (((const PointerEventArgs&)e).source == PS_Left)
        {
            setCurrentValue(d_currentValue - d_stepSize);
            return true;
        }

        return false;
    }

    bool Spinner::handleEditTextChange(const EventArgs&)
    {
        // set this windows text to match
        setText(getEditbox()->getText());
        // update value
        setCurrentValue(getValueFromText());
        return true;
    }

    PushButton* Spinner::getIncreaseButton() const
    {
        return static_cast<PushButton*>(getChild(IncreaseButtonName));
    }

    PushButton* Spinner::getDecreaseButton() const
    {
        return static_cast<PushButton*>(getChild(DecreaseButtonName));
    }

    Editbox* Spinner::getEditbox() const
    {
        return static_cast<Editbox*>(getChild(EditboxName));
    }

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

} // End of  CEGUI namespace section
<|endoftext|>


<commit_before>/** @file

  openssl_utils.cc - Interaction with openssl constructs

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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 <cstring>
#include <cerrno>
#include <cmath>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <openssl/rand.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ts/ts.h>

#include "ssl_utils.h"
#include "Config.h"
#include "session_process.h"
#include "common.h"

static int
ssl_new_session(TSSslSessionID &sid)
{
  // Encode ID
  std::string encoded_id;
  int ret = encode_id(sid.bytes, sid.len, encoded_id);
  if (ret < 0) {
    TSError("Encoded id failed.");
    return 0;
  }
  std::string redis_channel = ssl_param.cluster_name + "." + encoded_id;

  int session_ret_len = SSL_SESSION_MAX_DER;
  char session_data[SSL_SESSION_MAX_DER];
  const auto buffer_length = TSSslSessionGetBuffer(&sid, session_data, &session_ret_len);
  if (buffer_length == 0) {
    TSError("Failed to find a session buffer.");
    return 0;
  } else if (buffer_length > session_ret_len) {
    TSError("Session data is too large. Its size is: %d but our max buffer size is: %d.", buffer_length, SSL_SESSION_MAX_DER);
    return 0;
  }

  std::string encrypted_data;
  ret = encrypt_session(session_data, session_ret_len, (unsigned char *)get_key_ptr(), get_key_length(), encrypted_data);
  if (ret < 0) {
    TSError("Encrypt_session failed.");
    return 0;
  }

  ssl_param.pub->publish(redis_channel, encrypted_data);

  TSDebug(PLUGIN, "Create new session id: %s encoded: %s channel: %s", encoded_id.c_str(), encrypted_data.c_str(),
          redis_channel.c_str());

  return 0;
}

static int
ssl_access_session(TSSslSessionID &sid)
{
  return 0;
}

static int
ssl_del_session(TSSslSessionID &sid)
{
  std::string encoded_id;

  int ret = encode_id(sid.bytes, sid.len, encoded_id);
  if (!ret) {
    TSDebug(PLUGIN, "Session is deleted. id: %s", encoded_id.c_str());
  }

  return 0;
}

int
SSL_session_callback(TSCont contp, TSEvent event, void *edata)
{
  TSDebug(PLUGIN, "SSL_session_callback event: %d", event);
  TSSslSessionID *sessionid = reinterpret_cast<TSSslSessionID *>(edata);

  switch (event) {
  case TS_EVENT_SSL_SESSION_NEW:
    ssl_new_session(*sessionid);
    break;
  case TS_EVENT_SSL_SESSION_REMOVE:
    ssl_del_session(*sessionid);
    break;
  case TS_EVENT_SSL_SESSION_GET:
    ssl_access_session(*sessionid);
    break;
  default:
    break;
  }
  return 0;
}
<commit_msg>TLS Session Reuse: Downgrade noisy log to debug (#7344)<commit_after>/** @file

  openssl_utils.cc - Interaction with openssl constructs

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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 <cstring>
#include <cerrno>
#include <cmath>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <openssl/rand.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ts/ts.h>

#include "ssl_utils.h"
#include "Config.h"
#include "session_process.h"
#include "common.h"

static int
ssl_new_session(TSSslSessionID &sid)
{
  // Encode ID
  std::string encoded_id;
  int ret = encode_id(sid.bytes, sid.len, encoded_id);
  if (ret < 0) {
    TSError("Encoded id failed.");
    return 0;
  }
  std::string redis_channel = ssl_param.cluster_name + "." + encoded_id;

  int session_ret_len = SSL_SESSION_MAX_DER;
  char session_data[SSL_SESSION_MAX_DER];
  const auto buffer_length = TSSslSessionGetBuffer(&sid, session_data, &session_ret_len);
  if (buffer_length == 0) {
    TSDebug(PLUGIN, "Failed to find a session buffer.");
    return 0;
  } else if (buffer_length > session_ret_len) {
    TSError("Session data is too large. Its size is: %d but our max buffer size is: %d.", buffer_length, SSL_SESSION_MAX_DER);
    return 0;
  }

  std::string encrypted_data;
  ret = encrypt_session(session_data, session_ret_len, (unsigned char *)get_key_ptr(), get_key_length(), encrypted_data);
  if (ret < 0) {
    TSError("Encrypt_session failed.");
    return 0;
  }

  ssl_param.pub->publish(redis_channel, encrypted_data);

  TSDebug(PLUGIN, "Create new session id: %s encoded: %s channel: %s", encoded_id.c_str(), encrypted_data.c_str(),
          redis_channel.c_str());

  return 0;
}

static int
ssl_access_session(TSSslSessionID &sid)
{
  return 0;
}

static int
ssl_del_session(TSSslSessionID &sid)
{
  std::string encoded_id;

  int ret = encode_id(sid.bytes, sid.len, encoded_id);
  if (!ret) {
    TSDebug(PLUGIN, "Session is deleted. id: %s", encoded_id.c_str());
  }

  return 0;
}

int
SSL_session_callback(TSCont contp, TSEvent event, void *edata)
{
  TSDebug(PLUGIN, "SSL_session_callback event: %d", event);
  TSSslSessionID *sessionid = reinterpret_cast<TSSslSessionID *>(edata);

  switch (event) {
  case TS_EVENT_SSL_SESSION_NEW:
    ssl_new_session(*sessionid);
    break;
  case TS_EVENT_SSL_SESSION_REMOVE:
    ssl_del_session(*sessionid);
    break;
  case TS_EVENT_SSL_SESSION_GET:
    ssl_access_session(*sessionid);
    break;
  default:
    break;
  }
  return 0;
}
<|endoftext|>


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

The MIT License

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

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

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

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

Author            : Moritz Dannhauer
Last modification : March 16 2014
ToDo: Padding is always enabled because of exit() in cleaver lib
*/

///TODO: fix include path to remove Externals/ part
#include <Externals/cleaver/lib/FloatField.h>
#include <Externals/cleaver/lib/Cleaver.h>
#include <Externals/cleaver/lib/InverseField.h>
#include <Externals/cleaver/lib/PaddedVolume.h>
#include <Externals/cleaver/lib/Volume.h>
#include <Core/Algorithms/Base/AlgorithmPreconditions.h>
#include <Core/Algorithms/Field/InterfaceWithCleaverAlgorithm.h>
#include <Core/Algorithms/Base/AlgorithmVariableNames.h>
#include <Core/GeometryPrimitives/Vector.h>
#include <Core/Datatypes/Legacy/Field/Field.h>
#include <Core/Datatypes/Legacy/Field/VField.h>
#include <Core/Datatypes/Legacy/Field/VMesh.h>
#include <Core/Datatypes/Legacy/Field/FieldInformation.h>
#include <iostream>
#include <Core/GeometryPrimitives/Point.h>
#include <Core/Utils/StringUtil.h>
#include <boost/scoped_ptr.hpp>
#include <Core/Logging/Log.h>

using namespace SCIRun::Core::Algorithms;
using namespace SCIRun::Core::Algorithms::Fields;
using namespace SCIRun::Core::Geometry;
using namespace SCIRun;
using namespace SCIRun::Core;
using namespace SCIRun::Core::Logging;

AlgorithmParameterName InterfaceWithCleaverAlgorithm::Verbose("VerboseCheckBox");
AlgorithmParameterName InterfaceWithCleaverAlgorithm::Padding("PaddingCheckBox");
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingOption("VolumeScalingOption");
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingX("VolumeScalingSpinBox_X");
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingY("VolumeScalingSpinBox_Y");
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingZ("VolumeScalingSpinBox_Z");

InterfaceWithCleaverAlgorithm::InterfaceWithCleaverAlgorithm()
{
  addParameter(Verbose,true);
  addParameter(Padding,true);
  add_option(VolumeScalingOption, "Relative size", "Absolute size|Relative size|None");
  addParameter(VolumeScalingX,1.0);
  addParameter(VolumeScalingY,1.0);
  addParameter(VolumeScalingZ,1.0);
}

boost::shared_ptr<Cleaver::ScalarField> InterfaceWithCleaverAlgorithm::makeCleaverFieldFromLatVol(FieldHandle field)
{
  //TODO: this function assumes input is completely valid, may want to move various checks from run() function here.

  VMesh*  vmesh   = field->vmesh();
  VField* vfield = field->vfield();
  VMesh::dimension_type dims;
  vmesh->get_dimensions( dims );
  float* ptr = static_cast<float*>(vfield->fdata_pointer());
  auto cleaverField = boost::make_shared<Cleaver::FloatField>(dims[0], dims[1], dims[2], ptr);

  //0 = constant, 1 = linear
  if (0 == vfield->basis_order())
    cleaverField->setCenter(Cleaver::FloatField::CellCentered);
  else if (1 == vfield->basis_order())
    cleaverField->setCenter(Cleaver::FloatField::NodeCentered);
  //else: TODO? handle other bases, probably by throwing exception.

  //TODO: Cleaver FloatField needs more setup (constructor is not sufficient)
  // 1.
  // setBounds(BoundingBox). Convert vmesh->get_bounding_box() to Cleaver BoundingBox.
  // 2.
  // setScale(vec3). Need to figure out which vmesh function to call, and convert to Cleaver::vec3.
  // 3. unit test heavily.

  return cleaverField;
}

FieldHandle InterfaceWithCleaverAlgorithm::run(const std::vector<FieldHandle>& input) const
{
  FieldHandle output;

  std::vector<FieldHandle> inputs;
  std::copy_if(input.begin(), input.end(), std::back_inserter(inputs), [](FieldHandle f) { return f; });

  if (inputs.empty())
  {
    THROW_ALGORITHM_INPUT_ERROR(" No input fields given ");
    return FieldHandle();
  }
  if (inputs.size()<2)
  {
    THROW_ALGORITHM_INPUT_ERROR(" At least 2 indicator functions stored as float values are needed to run cleaver! " );
    return FieldHandle();
  }

  std::vector<boost::shared_ptr<Cleaver::ScalarField>> fields;
  VMesh::dimension_type dims; int x=0,y=0,z=0;
  for (size_t p=1; p<inputs.size(); p++)
  {
    FieldHandle input = inputs[p];
    VMesh*  imesh1   = input->vmesh();

    if( !imesh1->is_structuredmesh() )
    {
      THROW_ALGORITHM_INPUT_ERROR("needs to be structured mesh!");
    }
    else
    {
      VField* vfield1 = input->vfield();
      if (!vfield1->is_scalar())
      {
        THROW_ALGORITHM_INPUT_ERROR("values at the node needs to be scalar!");
        return FieldHandle();
      }

      imesh1->get_dimensions( dims );
      if (p==1)
      {
        x=dims[0]; y=dims[1]; z=dims[2];
        if (x<1 || y<1 || z<1)
        {
          THROW_ALGORITHM_INPUT_ERROR(" Size of input fields should be non-zero !");
        }
      }
      else
      {
        if ( dims[0]!=x || dims[1]!=y || dims[2]!=z)
        {
          THROW_ALGORITHM_INPUT_ERROR(" Size of input fields is inconsistent !");
        }
      }

      if (dims.size()!=3)
      {
        THROW_ALGORITHM_INPUT_ERROR("need a three dimensional indicator function");
        return FieldHandle();
      }

      if (vfield1->is_float())
      {
        float* ptr = static_cast<float*>(vfield1->fdata_pointer());
        if (ptr)
        {
          fields.push_back(makeCleaverFieldFromLatVol(input));
        }
        else
        {
          THROW_ALGORITHM_INPUT_ERROR(" float field is NULL pointer");
          return FieldHandle();
        }
      }

    }

  }

  boost::shared_ptr<Cleaver::Volume> volume(new Cleaver::Volume(toVectorOfRawPointers(fields)));

  const double xScale = get(VolumeScalingX).toDouble();
  const double yScale = get(VolumeScalingY).toDouble();
  const double zScale = get(VolumeScalingZ).toDouble();

  if (xScale > 0 && yScale > 0 && zScale > 0)
  {
    const std::string scaling = get_option(VolumeScalingOption);
    if ("Absolute size" == scaling)
    {
      volume->setSize(xScale, yScale,zScale);
    }
    else if ("Relative size" == scaling)
    {
      double newX = xScale*volume->size().x;
      double newY = yScale*volume->size().y;
      double newZ = zScale*volume->size().z;
      std::cout << "Cleaver setting volume size to " << newX << "," << newY << "," << newZ << std::endl;
      volume->setSize(newX, newY, newZ);
    }
    else // None
      volume->setSize(dims[0],dims[1],dims[2]);
  }
  else
  {
    THROW_ALGORITHM_INPUT_ERROR(" Invalid Scaling. Use Input sizes.");
  }

  /// Padding is now optional!
  boost::shared_ptr<Cleaver::AbstractVolume> paddedVolume(volume);

  const bool verbose = get(Verbose).toBool();
  const bool pad = get(Padding).toBool();
  if (pad)
    paddedVolume.reset(new Cleaver::PaddedVolume(volume.get()));
  boost::scoped_ptr<Cleaver::TetMesh> mesh(Cleaver::createMeshFromVolume(paddedVolume.get(), verbose));

  FieldInformation fi("TetVolMesh",0,"double");   ///create output field

  output = CreateField(fi);
  auto omesh = output->vmesh();
  auto ofield = output->vfield();

  auto nr_of_tets  = mesh->tets.size();
  auto nr_of_verts = mesh->verts.size();

  omesh->node_reserve(nr_of_verts);
  omesh->elem_reserve(nr_of_tets);

  for (auto i=0; i<nr_of_verts; i++)
  {
    omesh->add_point(Point(mesh->verts[i]->pos().x,mesh->verts[i]->pos().y,mesh->verts[i]->pos().z));
  }

  VMesh::Node::array_type vdata;
  vdata.resize(4);
  std::vector<double> values(nr_of_tets);

  for (auto i=0; i<nr_of_tets; i++)
  {
    vdata[0]=mesh->tets[i]->verts[0]->tm_v_index;
    vdata[1]=mesh->tets[i]->verts[1]->tm_v_index;
    vdata[2]=mesh->tets[i]->verts[2]->tm_v_index;
    vdata[3]=mesh->tets[i]->verts[3]->tm_v_index;
    omesh->add_elem(vdata);
    auto mat_label = mesh->tets[i]->mat_label+1;
    values[i]=mat_label;
  }
  ofield->resize_values();
  ofield->set_values(values);
  mesh->computeAngles();
  std::ostringstream ostr1;
  ostr1 << "Number of tetrahedral elements:" << ofield->vmesh()->num_elems() <<  std::endl;
  ostr1 << "Number of tetrahedral nodes:" << ofield->vmesh()->num_nodes() << std::endl;
  ostr1 << "Number of tetrahedral nodes:" << ofield->vmesh()->num_nodes() << std::endl;
  ostr1 << "Worst Angle (min):" <<  mesh->min_angle << std::endl;
  ostr1 << "Worst Angle (max):" <<  mesh->max_angle << std::endl;
  ostr1 << "Volume:" << volume->size().toString() << std::endl;

  remark(ostr1.str());

  return output;
}

AlgorithmOutput InterfaceWithCleaverAlgorithm::run_generic(const AlgorithmInput& input) const
{
  auto inputfields = input.getList<Field>(Variables::InputFields);

  FieldHandle output_fld = run(inputfields);
  if ( !output_fld )
    THROW_ALGORITHM_PROCESSING_ERROR("Null returned on legacy run call.");

  AlgorithmOutput output;
  output[Variables::OutputField] = output_fld;
  return output;
}
<commit_msg>small update<commit_after>/*
For more information, please see: http://software.sci.utah.edu

The MIT License

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

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

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

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

Author            : Moritz Dannhauer
Last modification : March 16 2014
ToDo: Padding is always enabled because of exit() in cleaver lib
*/

///TODO: fix include path to remove Externals/ part

#include <Externals/cleaver/lib/FloatField.h>
#include <Externals/cleaver/lib/vec3.h>
#include <Externals/cleaver/lib/BoundingBox.h>
#include <Externals/cleaver/lib/Cleaver.h>
#include <Externals/cleaver/lib/InverseField.h>
#include <Externals/cleaver/lib/PaddedVolume.h>
#include <Externals/cleaver/lib/Volume.h>
#include <Core/Algorithms/Base/AlgorithmPreconditions.h>
#include <Core/Algorithms/Field/InterfaceWithCleaverAlgorithm.h>
#include <Core/Algorithms/Base/AlgorithmVariableNames.h>
#include <Core/GeometryPrimitives/Vector.h>
#include <Core/Datatypes/Legacy/Field/Field.h>
#include <Core/Datatypes/Legacy/Field/VField.h>
#include <Core/Datatypes/Legacy/Field/VMesh.h>
#include <Core/Datatypes/Legacy/Field/FieldInformation.h>
#include <iostream>
#include <Core/GeometryPrimitives/Point.h>
#include <Core/Utils/StringUtil.h>
#include <boost/scoped_ptr.hpp>
#include <Core/Logging/Log.h>
#include <Core/Math/MiscMath.h>

using namespace SCIRun::Core::Algorithms;
using namespace SCIRun::Core::Algorithms::Fields;
using namespace SCIRun::Core::Geometry;
using namespace SCIRun;
using namespace SCIRun::Core;
using namespace SCIRun::Core::Logging;

AlgorithmParameterName InterfaceWithCleaverAlgorithm::Verbose("VerboseCheckBox");
AlgorithmParameterName InterfaceWithCleaverAlgorithm::Padding("PaddingCheckBox");
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingOption("VolumeScalingOption");
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingX("VolumeScalingSpinBox_X");
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingY("VolumeScalingSpinBox_Y");
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingZ("VolumeScalingSpinBox_Z");

InterfaceWithCleaverAlgorithm::InterfaceWithCleaverAlgorithm()
{
  addParameter(Verbose,true);
  addParameter(Padding,true);
  add_option(VolumeScalingOption, "Relative size", "Absolute size|Relative size|None");
  addParameter(VolumeScalingX,1.0);
  addParameter(VolumeScalingY,1.0);
  addParameter(VolumeScalingZ,1.0);
}

boost::shared_ptr<Cleaver::ScalarField> InterfaceWithCleaverAlgorithm::makeCleaverFieldFromLatVol(FieldHandle field )
{
  //TODO: this function assumes input is completely valid, may want to move various checks from run() function here.
  VMesh*  vmesh   = field->vmesh();
  VField* vfield = field->vfield();
  VMesh::dimension_type dims;
  vmesh->get_dimensions( dims );

  float* ptr = static_cast<float*>(vfield->fdata_pointer());

  auto cleaverField = boost::make_shared<Cleaver::FloatField>(dims[0], dims[1], dims[2], ptr);

  cleaverField->setCenter(Cleaver::FloatField::CellCentered);

  BBox bbox=vmesh->get_bounding_box();
  Point bmin, bmax;
  if (bbox.valid())
  {
   bmin = bbox.min();
   bmax = bbox.max();
  }
  Cleaver::BoundingBox  bb = Cleaver::BoundingBox(Cleaver::vec3::zero, Cleaver::vec3(dims[0],dims[1],dims[2]));
  cleaverField->setBounds(bb);
  const Transform &transform = vmesh->get_transform();

  int x_spacing=fabs(transform.get_mat_val(0,0)), y_spacing=fabs(transform.get_mat_val(1,1)), z_spacing=fabs(transform.get_mat_val(2,2));
  if (IsNan(x_spacing)) x_spacing=1;
  if (IsNan(y_spacing)) y_spacing=1;
  if (IsNan(z_spacing)) z_spacing=1;

  cleaverField->setScale(Cleaver::vec3(x_spacing,y_spacing,z_spacing));

  //TODO: Cleaver FloatField needs more setup (constructor is not sufficient)
  // 1.
  // setBounds(BoundingBox). Convert vmesh->get_bounding_box() to Cleaver BoundingBox.
  // 2.
  // setScale(vec3). Need to figure out which vmesh function to call, and convert to Cleaver::vec3.
  // 3. unit test heavily.

  return cleaverField;
}

FieldHandle InterfaceWithCleaverAlgorithm::run(const std::vector<FieldHandle>& input) const
{
  FieldHandle output;
  std::vector<FieldHandle> inputs;
  std::copy_if(input.begin(), input.end(), std::back_inserter(inputs), [](FieldHandle f) { return f; });

  if (inputs.empty())
  {
    THROW_ALGORITHM_INPUT_ERROR(" No input fields given ");
    return FieldHandle();
  }
  if (inputs.size()<2)
  {
    THROW_ALGORITHM_INPUT_ERROR(" At least 2 indicator functions stored as float values are needed to run cleaver! " );
    return FieldHandle();
  }

  std::vector<boost::shared_ptr<Cleaver::ScalarField>> fields;

  VMesh::dimension_type dims; int x=0,y=0,z=0;
  for (size_t p=0; p<inputs.size(); p++)
  {
    FieldHandle input = inputs[p];
    VMesh*  imesh1   = input->vmesh();

    if( !imesh1->is_structuredmesh() )
    {
      THROW_ALGORITHM_INPUT_ERROR("needs to be structured mesh!");
    }
    else
    {
      VField* vfield1 = input->vfield();
      if (!vfield1->is_scalar())
      {
        THROW_ALGORITHM_INPUT_ERROR("values at the node needs to be scalar!");
        return FieldHandle();
      }

      imesh1->get_dimensions( dims );
      if (p==0)
      {
        x=dims[0]; y=dims[1]; z=dims[2];
        if (x<1 || y<1 || z<1)
        {
          THROW_ALGORITHM_INPUT_ERROR(" Size of input fields should be non-zero !");
        }
      }
      else
      {
        if ( dims[0]!=x || dims[1]!=y || dims[2]!=z)
        {
          THROW_ALGORITHM_INPUT_ERROR(" Size of input fields is inconsistent !");
        }
      }

      if (dims.size()!=3)
      {
        THROW_ALGORITHM_INPUT_ERROR("need a three dimensional indicator function");
        return FieldHandle();
      }

      //0 = constant, 1 = linear
       if (0 != vfield1->basis_order())
       {
        THROW_ALGORITHM_INPUT_ERROR("Input data need to be defined on elements. You can use the module MapFieldDataFromNodeToElem to do that.");
       }

      if (vfield1->is_float())
      {
        float* ptr = static_cast<float*>(vfield1->fdata_pointer());
	if (ptr)
        {
          fields.push_back(makeCleaverFieldFromLatVol(input));
        }
        else
        {
          THROW_ALGORITHM_INPUT_ERROR(" float field is NULL pointer");
          return FieldHandle();
        }
      } else
      {
       THROW_ALGORITHM_INPUT_ERROR(" Input field needs to be a structured mesh (LatVOL) with float values defnied on the elements. ");
      }

    }

  }

  boost::shared_ptr<Cleaver::Volume> volume(new Cleaver::Volume(toVectorOfRawPointers(fields)));
/*
  Cleaver::BoundingBox m_bounds=fields[0]->bounds();
  std::cout << "bsize: " << m_bounds.size.x << " " << m_bounds.size.y << " " <<  m_bounds.size.z << std::endl;
  std::cout << "borin: " << m_bounds.origin.x << " " << m_bounds.origin.y << " " << m_bounds.origin.z << std::endl;
  */
  const double xScale = get(VolumeScalingX).toDouble();
  const double yScale = get(VolumeScalingY).toDouble();
  const double zScale = get(VolumeScalingZ).toDouble();

  if (xScale > 0 && yScale > 0 && zScale > 0)
  {
    const std::string scaling = get_option(VolumeScalingOption);
    if ("Absolute size" == scaling)
    {
      volume->setSize(xScale, yScale,zScale);
    }
    else if ("Relative size" == scaling)
    {
      double newX = xScale*volume->size().x;
      double newY = yScale*volume->size().y;
      double newZ = zScale*volume->size().z;
      volume->setSize(newX, newY, newZ);
    }
    else // None
    {
      volume->setSize(dims[0],dims[1],dims[2]);
    }
  }
  else
  {
    THROW_ALGORITHM_INPUT_ERROR(" Invalid Scaling. Use Input sizes.");
  }

  /// Padding is now optional!
  boost::shared_ptr<Cleaver::AbstractVolume> paddedVolume(volume);
  const bool verbose = get(Verbose).toBool();
  const bool pad = get(Padding).toBool();
  if (pad)
    paddedVolume.reset(new Cleaver::PaddedVolume(volume.get()));

  std::cout << "Creating Mesh with Volume Size " << paddedVolume->size().toString() << std::endl;

  boost::scoped_ptr<Cleaver::TetMesh> mesh(Cleaver::createMeshFromVolume(paddedVolume.get(), verbose));

  FieldInformation fi("TetVolMesh",0,"double");   ///create output field

  output = CreateField(fi);
  auto omesh = output->vmesh();
  auto ofield = output->vfield();

  auto nr_of_tets  = mesh->tets.size();
  auto nr_of_verts = mesh->verts.size();

  omesh->node_reserve(nr_of_verts);
  omesh->elem_reserve(nr_of_tets);

  for (auto i=0; i<nr_of_verts; i++)
  {
    omesh->add_point(Point(mesh->verts[i]->pos().x,mesh->verts[i]->pos().y,mesh->verts[i]->pos().z));
  }

  VMesh::Node::array_type vdata;
  vdata.resize(4);
  std::vector<double> values(nr_of_tets);

  for (auto i=0; i<nr_of_tets; i++)
  {
    vdata[0]=mesh->tets[i]->verts[0]->tm_v_index;
    vdata[1]=mesh->tets[i]->verts[1]->tm_v_index;
    vdata[2]=mesh->tets[i]->verts[2]->tm_v_index;
    vdata[3]=mesh->tets[i]->verts[3]->tm_v_index;
    omesh->add_elem(vdata);
    auto mat_label = mesh->tets[i]->mat_label;
    values[i]=mat_label;
  }
  ofield->resize_values();
  ofield->set_values(values);
  mesh->computeAngles();
  std::ostringstream ostr1;
  ostr1 << "Number of tetrahedral elements:" << nr_of_tets <<  std::endl;
  ostr1 << "Number of tetrahedral nodes:" << nr_of_verts << std::endl;
  ostr1 << "Worst Angle (min):" <<  mesh->min_angle << std::endl;
  ostr1 << "Worst Angle (max):" <<  mesh->max_angle << std::endl;
  ostr1 << "Volume:" << volume->size().toString() << std::endl;

  remark(ostr1.str());

  return output;
}

AlgorithmOutput InterfaceWithCleaverAlgorithm::run_generic(const AlgorithmInput& input) const
{
  auto inputfields = input.getList<Field>(Variables::InputFields);

  FieldHandle output_fld = run(inputfields);
  if ( !output_fld )
    THROW_ALGORITHM_PROCESSING_ERROR("Null returned on legacy run call.");

  AlgorithmOutput output;
  output[Variables::OutputField] = output_fld;
  return output;
}
<|endoftext|>


<commit_before>/*
 *      Author: Vladimir Ivan
 *
 * Copyright (c) 2017, University Of Edinburgh
 * 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  nor the names of its contributors may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <exotica/TaskSpaceVector.h>

namespace exotica
{

    TaskVectorEntry::TaskVectorEntry(int inId_, RotationType type_) :
        inId(inId_), type(type_)
    {

    }

    TaskVectorEntry::TaskVectorEntry() :
        inId(0), type(RotationType::RPY)
    {

    }

    TaskSpaceVector::TaskSpaceVector()
    {

    }

    TaskSpaceVector& TaskSpaceVector::operator=(std::initializer_list<double> other)
    {
        if(other.size()!=data.rows()) throw_pretty("Wrong initializer size: " << other.size() << " expecting " << data.rows());
        int i = 0;
        for(double val : other)
        {
            data(i) = val;
            i++;
        }
        return *this;
    }

    void TaskSpaceVector::setZero(int N)
    {

        data = Eigen::VectorXd::Zero(N);
        for(const TaskVectorEntry& id : map)
        {
            int len = getRotationTypeLength(id.type);
            data.segment(id.inId,len) = setRotation(KDL::Rotation(), id.type);
        }
    }

    Eigen::VectorXd TaskSpaceVector::operator-(const TaskSpaceVector& other)
    {
        if(data.rows() != other.data.rows()) throw_pretty("Task space vector sizes do not match!");
        int entrySize = 0;
        for(const TaskVectorEntry& id : map) entrySize += getRotationTypeLength(id.type);
        Eigen::VectorXd ret(data.rows()+map.size()*3-map.size()*entrySize);
        int iIn=0;
        int iOut=0;
        for(const TaskVectorEntry& id : map)
        {
            if(iIn<id.inId) ret.segment(iOut, id.inId-iIn) = data.segment(iIn, id.inId-iIn) - other.data.segment(iIn, id.inId-iIn);
            iOut += id.inId-iIn;
            iIn += id.inId-iIn;
            int len = getRotationTypeLength(id.type);

            KDL::Rotation M1 = getRotation(data.segment(id.inId, len), id.type);
            KDL::Rotation M2 = getRotation(other.data.segment(id.inId, len), id.type);
            KDL::Rotation M = M2.Inverse()*M1;
            KDL::Vector rotvec = M1*(M.GetRot());
            ret(iOut) = rotvec[0];
            ret(iOut+1) = rotvec[1];
            ret(iOut+2) = rotvec[2];
            iOut+=3;
            iIn+=len;
        }
        if(iIn<data.rows()) ret.segment(iOut, data.rows()-iIn) = data.segment(iIn, data.rows()-iIn) - other.data.segment(iIn, data.rows()-iIn);
        return ret;
    }
}
<commit_msg>Fixes multiple ratiotion task inside a task map indexing<commit_after>/*
 *      Author: Vladimir Ivan
 *
 * Copyright (c) 2017, University Of Edinburgh
 * 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  nor the names of its contributors may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <exotica/TaskSpaceVector.h>

namespace exotica
{

    TaskVectorEntry::TaskVectorEntry(int inId_, RotationType type_) :
        inId(inId_), type(type_)
    {

    }

    TaskVectorEntry::TaskVectorEntry() :
        inId(0), type(RotationType::RPY)
    {

    }

    TaskSpaceVector::TaskSpaceVector()
    {

    }

    TaskSpaceVector& TaskSpaceVector::operator=(std::initializer_list<double> other)
    {
        if(other.size()!=data.rows()) throw_pretty("Wrong initializer size: " << other.size() << " expecting " << data.rows());
        int i = 0;
        for(double val : other)
        {
            data(i) = val;
            i++;
        }
        return *this;
    }

    void TaskSpaceVector::setZero(int N)
    {

        data = Eigen::VectorXd::Zero(N);
        for(const TaskVectorEntry& id : map)
        {
            int len = getRotationTypeLength(id.type);
            data.segment(id.inId,len) = setRotation(KDL::Rotation(), id.type);
        }
    }

    Eigen::VectorXd TaskSpaceVector::operator-(const TaskSpaceVector& other)
    {
        if(data.rows() != other.data.rows()) throw_pretty("Task space vector sizes do not match!");
        int entrySize = 0;
        for(const TaskVectorEntry& id : map) entrySize += getRotationTypeLength(id.type);
        Eigen::VectorXd ret(data.rows()+map.size()*3-entrySize);
        int iIn=0;
        int iOut=0;
        for(const TaskVectorEntry& id : map)
        {
            if(iIn<id.inId) ret.segment(iOut, id.inId-iIn) = data.segment(iIn, id.inId-iIn) - other.data.segment(iIn, id.inId-iIn);
            iOut += id.inId-iIn;
            iIn += id.inId-iIn;
            int len = getRotationTypeLength(id.type);

            KDL::Rotation M1 = getRotation(data.segment(id.inId, len), id.type);
            KDL::Rotation M2 = getRotation(other.data.segment(id.inId, len), id.type);
            KDL::Rotation M = M2.Inverse()*M1;
            KDL::Vector rotvec = M1*(M.GetRot());
            ret(iOut) = rotvec[0];
            ret(iOut+1) = rotvec[1];
            ret(iOut+2) = rotvec[2];
            iOut+=3;
            iIn+=len;
        }
        if(iIn<data.rows()) ret.segment(iOut, data.rows()-iIn) = data.segment(iIn, data.rows()-iIn) - other.data.segment(iIn, data.rows()-iIn);
        return ret;
    }
}
<|endoftext|>


<commit_before>#include <Element.h>
#include <FWPlatform.h>
#include <HeadingText.h>
#include <TextLabel.h>
#include <LinearLayout.h>
#include <FWApplication.h>

#include <cassert>

using namespace std;

int Element::nextInternalId = 1;

Element::~Element() {
  if (platform) {
    platform->unregisterElement(this);
  }
}

void
Element::initialize(FWPlatform * _platform) {
  assert(_platform);
  if (_platform) {
    platform = _platform;
    platform->registerElement(this);
    create();
    for (auto & c : pendingCommands) {
      sendCommand(c);
    }
    pendingCommands.clear();
  }
  assert(isInitialized());
}

void
Element::initializeChildren() {
  assert(isInitialized());
  if (isInitialized()) {
    for (auto & c : getChildren()) {
      c->initialize(platform);
      c->initializeChildren();
    }
  }
}

void
Element::setError(bool t) {
  if ((t && !has_error) || (!t && has_error)) {
    has_error = t;
    cerr << "setting error to " << has_error << endl;
    Command c(Command::SET_ERROR, getInternalId());
    c.setValue(t ? 1 : 0);
    if (t) c.setTextValue("Arvo ei kelpaa!");
    sendCommand(c);
  }
}

void
Element::setEnabled(bool _is_enabled) {
  is_enabled = _is_enabled;
  Command c(Command::SET_ENABLED, getInternalId());
  c.setValue(is_enabled ? 1 : 0);
  sendCommand(c);
}

void
Element::show() {
  is_visible = true;
  Command c(Command::SET_VISIBILITY, getInternalId());
  c.setValue(1);
  sendCommand(c);
}

void
Element::hide() {
  is_visible = false;
  Command c(Command::SET_VISIBILITY, getInternalId());
  c.setValue(0);
  sendCommand(c);
}

void
Element::style(const std::string & key, const std::string & value) {
  Command c(Command::SET_STYLE, getInternalId());
  c.setTextValue(key);
  c.setTextValue2(value);
  sendCommand(c);
}

void
Element::sendCommand(const Command & command) {
  if (platform) {
    platform->sendCommand2(command);
  } else {
    pendingCommands.push_back(command);
  }
}

Element &
Element::addHeading(const std::string & text) {
  return addChild(make_shared<HeadingText>(text));
}

Element &
Element::addText(const std::string & text) {
  return addChild(make_shared<TextLabel>(text));
}

Element &
Element::addHorizontalLayout(int _id) {
  return addChild(make_shared<LinearLayout>(FW_HORIZONTAL, _id));
}

Element &
Element::addVerticalLayout(int _id) {
  return addChild(make_shared<LinearLayout>(FW_VERTICAL, _id));
}

void
Element::onEvent(Event & ev) {
  if (!ev.isHandled()) {
    if (ev.isBroadcast()) {
      for (auto & c : getChildren()){
	ev.dispatch(*c);
      }
    } else if (parent) {
      ev.dispatch(*parent);
    }
  }
}

void
Element::showMessageDialog(const std::string & title, const std::string & text) {
  Command c(Command::SHOW_MESSAGE_DIALOG, getParentInternalId(), getInternalId());
  c.setTextValue(title);
  c.setTextValue2(text);
  sendCommand(c);
}

std::string
Element::showInputDialog(const std::string & title, const std::string & text) {
  Command c(Command::SHOW_INPUT_DIALOG, getParentInternalId(), getInternalId());
  c.setTextValue(title);
  c.setTextValue2(text);
  sendCommand(c);
  return platform->getModalResultText();
}

void
Element::showToast(const std::string & message, int duration) {
  Command c(Command::CREATE_TOAST, getParentInternalId(), getInternalId());
  c.setTextValue(message);
  c.setValue(duration);
  sendCommand(c);
}

FWApplication &
Element::getApplication() {
  auto p = getPlatform().getFirstChild();
  return dynamic_cast<FWApplication&>(*p);
}

const FWApplication &
Element::getApplication() const {
  auto p = getPlatform().getFirstChild();
  return dynamic_cast<const FWApplication&>(*p);
}

void
Element::removeChild(Element * child) {
  for (auto it = children.begin(); it != children.end(); it++) {
    if (it->get() == child) {
      sendCommand(Command(Command::DELETE_ELEMENT, getInternalId(), child->getInternalId()));
      children.erase(it);
      return;
    }
  }
}
<commit_msg>fix crash<commit_after>#include <Element.h>
#include <FWPlatform.h>
#include <HeadingText.h>
#include <TextLabel.h>
#include <LinearLayout.h>
#include <FWApplication.h>

#include <cassert>

using namespace std;

int Element::nextInternalId = 1;

Element::~Element() {
  // the platform itself cannot be unregistered at this point
  if (platform && this != platform) {
    platform->unregisterElement(this);
  }
}

void
Element::initialize(FWPlatform * _platform) {
  assert(_platform);
  if (_platform) {
    platform = _platform;
    platform->registerElement(this);
    create();
    for (auto & c : pendingCommands) {
      sendCommand(c);
    }
    pendingCommands.clear();
  }
  assert(isInitialized());
}

void
Element::initializeChildren() {
  assert(isInitialized());
  if (isInitialized()) {
    for (auto & c : getChildren()) {
      c->initialize(platform);
      c->initializeChildren();
    }
  }
}

void
Element::setError(bool t) {
  if ((t && !has_error) || (!t && has_error)) {
    has_error = t;
    cerr << "setting error to " << has_error << endl;
    Command c(Command::SET_ERROR, getInternalId());
    c.setValue(t ? 1 : 0);
    if (t) c.setTextValue("Arvo ei kelpaa!");
    sendCommand(c);
  }
}

void
Element::setEnabled(bool _is_enabled) {
  is_enabled = _is_enabled;
  Command c(Command::SET_ENABLED, getInternalId());
  c.setValue(is_enabled ? 1 : 0);
  sendCommand(c);
}

void
Element::show() {
  is_visible = true;
  Command c(Command::SET_VISIBILITY, getInternalId());
  c.setValue(1);
  sendCommand(c);
}

void
Element::hide() {
  is_visible = false;
  Command c(Command::SET_VISIBILITY, getInternalId());
  c.setValue(0);
  sendCommand(c);
}

void
Element::style(const std::string & key, const std::string & value) {
  Command c(Command::SET_STYLE, getInternalId());
  c.setTextValue(key);
  c.setTextValue2(value);
  sendCommand(c);
}

void
Element::sendCommand(const Command & command) {
  if (platform) {
    platform->sendCommand2(command);
  } else {
    pendingCommands.push_back(command);
  }
}

Element &
Element::addHeading(const std::string & text) {
  return addChild(make_shared<HeadingText>(text));
}

Element &
Element::addText(const std::string & text) {
  return addChild(make_shared<TextLabel>(text));
}

Element &
Element::addHorizontalLayout(int _id) {
  return addChild(make_shared<LinearLayout>(FW_HORIZONTAL, _id));
}

Element &
Element::addVerticalLayout(int _id) {
  return addChild(make_shared<LinearLayout>(FW_VERTICAL, _id));
}

void
Element::onEvent(Event & ev) {
  if (!ev.isHandled()) {
    if (ev.isBroadcast()) {
      for (auto & c : getChildren()){
	ev.dispatch(*c);
      }
    } else if (parent) {
      ev.dispatch(*parent);
    }
  }
}

void
Element::showMessageDialog(const std::string & title, const std::string & text) {
  Command c(Command::SHOW_MESSAGE_DIALOG, getParentInternalId(), getInternalId());
  c.setTextValue(title);
  c.setTextValue2(text);
  sendCommand(c);
}

std::string
Element::showInputDialog(const std::string & title, const std::string & text) {
  Command c(Command::SHOW_INPUT_DIALOG, getParentInternalId(), getInternalId());
  c.setTextValue(title);
  c.setTextValue2(text);
  sendCommand(c);
  return platform->getModalResultText();
}

void
Element::showToast(const std::string & message, int duration) {
  Command c(Command::CREATE_TOAST, getParentInternalId(), getInternalId());
  c.setTextValue(message);
  c.setValue(duration);
  sendCommand(c);
}

FWApplication &
Element::getApplication() {
  auto p = getPlatform().getFirstChild();
  return dynamic_cast<FWApplication&>(*p);
}

const FWApplication &
Element::getApplication() const {
  auto p = getPlatform().getFirstChild();
  return dynamic_cast<const FWApplication&>(*p);
}

void
Element::removeChild(Element * child) {
  for (auto it = children.begin(); it != children.end(); it++) {
    if (it->get() == child) {
      sendCommand(Command(Command::DELETE_ELEMENT, getInternalId(), child->getInternalId()));
      children.erase(it);
      return;
    }
  }
}
<|endoftext|>