<commit_before>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "doctype.h"
#include "visitor.h"

#include <vespa/document/update/documentupdate.h>
#include <vespa/document/fieldvalue/document.h>
#include <vespa/document/datatype/documenttype.h>
#include <ostream>

namespace document::select {

namespace {
    bool documentTypeEqualsName(const DocumentType& type,
                                vespalib::stringref name)
    {
        if (type.getName() == name) return true;
        // TODO Vespa 8: Remove this for look on Vespa 8
        for (std::vector<const DocumentType *>::const_iterator it
                = type.getInheritedTypes().begin();
             it != type.getInheritedTypes().end(); ++it)
        {
            if (documentTypeEqualsName(**it, name)) return true;
        }
        return false;
    }
}

DocType::DocType(vespalib::stringref doctype)
    : Node("DocType"),
      _doctype(doctype)
{
}

ResultList
DocType::contains(const Context &context) const
{
    if (context._doc != NULL) {
        const Document &doc = *context._doc;
        return
            ResultList(Result::get(
                documentTypeEqualsName(doc.getType(),
                                       _doctype)));
    }
    if (context._docId != NULL) {
        return ResultList(Result::get((context._docId->getDocType() == _doctype)));
    }
    const DocumentUpdate &upd(*context._docUpdate);
    return ResultList(Result::get(
                documentTypeEqualsName(upd.getType(), _doctype)));
}

ResultList
DocType::trace(const Context& context, std::ostream& out) const
{
    ResultList result = contains(context);
    if (context._doc != NULL) {
        const Document &doc = *context._doc;
        out << "DocType - Doc is type " << doc.getType()
            << ", wanted " << _doctype << ", returning "
            << result << ".\n";
    } else if (context._docId != NULL) {
        out << "DocType - Doc is type (document id -- unknown type)"
            << ", wanted " << _doctype << ", returning "
            << result << ".\n";
    } else {
        const DocumentUpdate &update(*context._docUpdate);
        out << "DocType - Doc is type " << update.getType()
            << ", wanted " << _doctype << ", returning "
            << result << ".\n";
    }
    return result;
}

void
DocType::visit(Visitor &v) const
{
    v.visitDocumentType(*this);
}

void
DocType::print(std::ostream& out, bool verbose,
                const std::string& indent) const
{
    (void) verbose; (void) indent;
    if (_parentheses) out << '(';
    out << _doctype;
    if (_parentheses) out << ')';
}

}
<commit_msg>Fix typo<commit_after>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "doctype.h"
#include "visitor.h"

#include <vespa/document/update/documentupdate.h>
#include <vespa/document/fieldvalue/document.h>
#include <vespa/document/datatype/documenttype.h>
#include <ostream>

namespace document::select {

namespace {
    bool documentTypeEqualsName(const DocumentType& type,
                                vespalib::stringref name)
    {
        if (type.getName() == name) return true;
        // TODO Vespa 8: Remove this for loop on Vespa 8
        for (std::vector<const DocumentType *>::const_iterator it
                = type.getInheritedTypes().begin();
             it != type.getInheritedTypes().end(); ++it)
        {
            if (documentTypeEqualsName(**it, name)) return true;
        }
        return false;
    }
}

DocType::DocType(vespalib::stringref doctype)
    : Node("DocType"),
      _doctype(doctype)
{
}

ResultList
DocType::contains(const Context &context) const
{
    if (context._doc != NULL) {
        const Document &doc = *context._doc;
        return
            ResultList(Result::get(
                documentTypeEqualsName(doc.getType(),
                                       _doctype)));
    }
    if (context._docId != NULL) {
        return ResultList(Result::get((context._docId->getDocType() == _doctype)));
    }
    const DocumentUpdate &upd(*context._docUpdate);
    return ResultList(Result::get(
                documentTypeEqualsName(upd.getType(), _doctype)));
}

ResultList
DocType::trace(const Context& context, std::ostream& out) const
{
    ResultList result = contains(context);
    if (context._doc != NULL) {
        const Document &doc = *context._doc;
        out << "DocType - Doc is type " << doc.getType()
            << ", wanted " << _doctype << ", returning "
            << result << ".\n";
    } else if (context._docId != NULL) {
        out << "DocType - Doc is type (document id -- unknown type)"
            << ", wanted " << _doctype << ", returning "
            << result << ".\n";
    } else {
        const DocumentUpdate &update(*context._docUpdate);
        out << "DocType - Doc is type " << update.getType()
            << ", wanted " << _doctype << ", returning "
            << result << ".\n";
    }
    return result;
}

void
DocType::visit(Visitor &v) const
{
    v.visitDocumentType(*this);
}

void
DocType::print(std::ostream& out, bool verbose,
                const std::string& indent) const
{
    (void) verbose; (void) indent;
    if (_parentheses) out << '(';
    out << _doctype;
    if (_parentheses) out << ')';
}

}
<|endoftext|>


<commit_before>#include <utility>

#include "drawtypes/label.hpp"
#include "utils/factory.hpp"
#include "utils/string.hpp"

POLYBAR_NS

namespace drawtypes {
  string label::get() const {
    return m_tokenized;
  }

  label::operator bool() {
    return !m_tokenized.empty();
  }

  label_t label::clone() {
    vector<token> tokens;
    if (!m_tokens.empty()) {
      std::back_insert_iterator<decltype(tokens)> back_it(tokens);
      std::copy(m_tokens.begin(), m_tokens.end(), back_it);
    }
    return factory_util::shared<label>(m_text, m_foreground, m_background, m_underline, m_overline, m_font, m_padding,
        m_margin, m_maxlen, m_ellipsis, move(tokens));
  }

  void label::clear() {
    m_tokenized.clear();
  }

  void label::reset_tokens() {
    m_tokenized = m_text;
  }

  void label::reset_tokens(const string& tokenized) {
    m_tokenized = tokenized;
  }

  bool label::has_token(const string& token) const {
    return m_tokenized.find(token) != string::npos;
  }

  void label::replace_token(const string& token, string replacement) {
    if (!has_token(token)) {
      return;
    }

    for (auto&& tok : m_tokens) {
      string repl{replacement};
      if (token == tok.token) {
        if (tok.max != 0_z && string_util::char_len(repl) > tok.max) {
          repl = string_util::utf8_truncate(std::move(repl), tok.max) + tok.suffix;
        } else if (tok.min != 0_z && repl.length() < tok.min) {
          repl.insert(0_z, tok.min - repl.length(), ' ');
        }

        /*
         * Only replace first occurence, so that the proper token objects can be used
         */
        m_tokenized = string_util::replace(m_tokenized, token, move(repl));
      }
    }
  }

  void label::replace_defined_values(const label_t& label) {
    if (!label->m_foreground.empty()) {
      m_foreground = label->m_foreground;
    }
    if (!label->m_background.empty()) {
      m_background = label->m_background;
    }
    if (!label->m_underline.empty()) {
      m_underline = label->m_underline;
    }
    if (!label->m_overline.empty()) {
      m_overline = label->m_overline;
    }
    if (label->m_font != 0) {
      m_font = label->m_font;
    }
    if (label->m_padding.left != 0U) {
      m_padding.left = label->m_padding.left;
    }
    if (label->m_padding.right != 0U) {
      m_padding.right = label->m_padding.right;
    }
    if (label->m_margin.left != 0U) {
      m_margin.left = label->m_margin.left;
    }
    if (label->m_margin.right != 0U) {
      m_margin.right = label->m_margin.right;
    }
    if (label->m_maxlen != 0_z) {
      m_maxlen = label->m_maxlen;
      m_ellipsis = label->m_ellipsis;
    }
  }

  void label::copy_undefined(const label_t& label) {
    if (m_foreground.empty() && !label->m_foreground.empty()) {
      m_foreground = label->m_foreground;
    }
    if (m_background.empty() && !label->m_background.empty()) {
      m_background = label->m_background;
    }
    if (m_underline.empty() && !label->m_underline.empty()) {
      m_underline = label->m_underline;
    }
    if (m_overline.empty() && !label->m_overline.empty()) {
      m_overline = label->m_overline;
    }
    if (m_font == 0 && label->m_font != 0) {
      m_font = label->m_font;
    }
    if (m_padding.left == 0U && label->m_padding.left != 0U) {
      m_padding.left = label->m_padding.left;
    }
    if (m_padding.right == 0U && label->m_padding.right != 0U) {
      m_padding.right = label->m_padding.right;
    }
    if (m_margin.left == 0U && label->m_margin.left != 0U) {
      m_margin.left = label->m_margin.left;
    }
    if (m_margin.right == 0U && label->m_margin.right != 0U) {
      m_margin.right = label->m_margin.right;
    }
    if (m_maxlen == 0_z && label->m_maxlen != 0_z) {
      m_maxlen = label->m_maxlen;
      m_ellipsis = label->m_ellipsis;
    }
  }

  /**
   * Create a label by loading values from the configuration
   */
  label_t load_label(const config& conf, const string& section, string name, bool required, string def) {
    vector<token> tokens;
    size_t start, end, pos;

    name = string_util::ltrim(string_util::rtrim(move(name), '>'), '<');

    string text;

    struct side_values padding {
    }, margin{};

    if (required) {
      text = conf.get(section, name);
    } else {
      text = conf.get(section, name, move(def));
    }

    size_t len{text.size()};

    if (len > 2 && text[0] == '"' && text[len - 1] == '"') {
      text = text.substr(1, len - 2);
    }

    const auto get_left_right = [&](string key) {
      auto value = conf.get(section, key, 0U);
      auto left = conf.get(section, key + "-left", value);
      auto right = conf.get(section, key + "-right", value);
      return side_values{static_cast<unsigned short int>(left), static_cast<unsigned short int>(right)};
    };

    padding = get_left_right(name + "-padding");
    margin = get_left_right(name + "-margin");

    string line{text};

    while ((start = line.find('%')) != string::npos && (end = line.find('%', start + 1)) != string::npos) {
      auto token_str = line.substr(start, end - start + 1);

      // ignore false positives
      //   lemonbar tags %{...}
      //   trailing percentage signs %token%%
      if (token_str.find_first_of("abcdefghijklmnopqrstuvwxyz") != 1) {
        line.erase(0, end);
        continue;
      }

      line.erase(start, end - start + 1);
      tokens.emplace_back(token{token_str, 0_z, 0_z});
      auto& token = tokens.back();

      // find min delimiter
      if ((pos = token_str.find(':')) == string::npos) {
        continue;
      }

      // strip min/max specifiers from the label string token
      token.token = token_str.substr(0, pos) + '%';
      text = string_util::replace(text, token_str, token.token);

      try {
        token.min = std::stoul(&token_str[pos + 1], nullptr, 10);
      } catch (const std::invalid_argument& err) {
        continue;
      }

      // find max delimiter
      if ((pos = token_str.find(':', pos + 1)) == string::npos) {
        continue;
      }

      try {
        token.max = std::stoul(&token_str[pos + 1], nullptr, 10);
      } catch (const std::invalid_argument& err) {
        continue;
      }

      // ignore max lengths less than min
      if (token.max < token.min) {
        token.max = 0_z;
      }

      // find suffix delimiter
      if ((pos = token_str.find(':', pos + 1)) != string::npos) {
        token.suffix = token_str.substr(pos + 1, token_str.size() - pos - 2);
      }
    }

    size_t maxlen = conf.get(section, name + "-maxlen", 0_z);
    bool ellipsis = conf.get(section, name + "-ellipsis", true);

    if(ellipsis && maxlen > 0 && maxlen < 3) {
      logger::make().err(sstream() << "Label " << section << "." << name
          << " has maxlen " << maxlen
          << ", which is smaller than length of ellipsis (3), disabling ellipsis...");

      ellipsis = false;
    }

    // clang-format off
    return factory_util::shared<label>(text,
        conf.get(section, name + "-foreground", ""s),
        conf.get(section, name + "-background", ""s),
        conf.get(section, name + "-underline", ""s),
        conf.get(section, name + "-overline", ""s),
        conf.get(section, name + "-font", 0),
        padding,
        margin,
        maxlen,
        ellipsis,
        move(tokens));
    // clang-format on
  }

  /**
   * Create a label by loading optional values from the configuration
   */
  label_t load_optional_label(const config& conf, string section, string name, string def) {
    return load_label(conf, move(section), move(name), false, move(def));
  }

  /**
   * Create an icon by loading values from the configuration
   */
  icon_t load_icon(const config& conf, string section, string name, bool required, string def) {
    return load_label(conf, move(section), move(name), required, move(def));
  }

  /**
   * Create an icon by loading optional values from the configuration
   */
  icon_t load_optional_icon(const config& conf, string section, string name, string def) {
    return load_icon(conf, move(section), move(name), false, move(def));
  }
}

POLYBAR_NS_END
<commit_msg>refactor(label): Throw exception with small maxlen<commit_after>#include <utility>

#include "drawtypes/label.hpp"
#include "utils/factory.hpp"
#include "utils/string.hpp"

POLYBAR_NS

namespace drawtypes {
  string label::get() const {
    return m_tokenized;
  }

  label::operator bool() {
    return !m_tokenized.empty();
  }

  label_t label::clone() {
    vector<token> tokens;
    if (!m_tokens.empty()) {
      std::back_insert_iterator<decltype(tokens)> back_it(tokens);
      std::copy(m_tokens.begin(), m_tokens.end(), back_it);
    }
    return factory_util::shared<label>(m_text, m_foreground, m_background, m_underline, m_overline, m_font, m_padding,
        m_margin, m_maxlen, m_ellipsis, move(tokens));
  }

  void label::clear() {
    m_tokenized.clear();
  }

  void label::reset_tokens() {
    m_tokenized = m_text;
  }

  void label::reset_tokens(const string& tokenized) {
    m_tokenized = tokenized;
  }

  bool label::has_token(const string& token) const {
    return m_tokenized.find(token) != string::npos;
  }

  void label::replace_token(const string& token, string replacement) {
    if (!has_token(token)) {
      return;
    }

    for (auto&& tok : m_tokens) {
      string repl{replacement};
      if (token == tok.token) {
        if (tok.max != 0_z && string_util::char_len(repl) > tok.max) {
          repl = string_util::utf8_truncate(std::move(repl), tok.max) + tok.suffix;
        } else if (tok.min != 0_z && repl.length() < tok.min) {
          repl.insert(0_z, tok.min - repl.length(), ' ');
        }

        /*
         * Only replace first occurence, so that the proper token objects can be used
         */
        m_tokenized = string_util::replace(m_tokenized, token, move(repl));
      }
    }
  }

  void label::replace_defined_values(const label_t& label) {
    if (!label->m_foreground.empty()) {
      m_foreground = label->m_foreground;
    }
    if (!label->m_background.empty()) {
      m_background = label->m_background;
    }
    if (!label->m_underline.empty()) {
      m_underline = label->m_underline;
    }
    if (!label->m_overline.empty()) {
      m_overline = label->m_overline;
    }
    if (label->m_font != 0) {
      m_font = label->m_font;
    }
    if (label->m_padding.left != 0U) {
      m_padding.left = label->m_padding.left;
    }
    if (label->m_padding.right != 0U) {
      m_padding.right = label->m_padding.right;
    }
    if (label->m_margin.left != 0U) {
      m_margin.left = label->m_margin.left;
    }
    if (label->m_margin.right != 0U) {
      m_margin.right = label->m_margin.right;
    }
    if (label->m_maxlen != 0_z) {
      m_maxlen = label->m_maxlen;
      m_ellipsis = label->m_ellipsis;
    }
  }

  void label::copy_undefined(const label_t& label) {
    if (m_foreground.empty() && !label->m_foreground.empty()) {
      m_foreground = label->m_foreground;
    }
    if (m_background.empty() && !label->m_background.empty()) {
      m_background = label->m_background;
    }
    if (m_underline.empty() && !label->m_underline.empty()) {
      m_underline = label->m_underline;
    }
    if (m_overline.empty() && !label->m_overline.empty()) {
      m_overline = label->m_overline;
    }
    if (m_font == 0 && label->m_font != 0) {
      m_font = label->m_font;
    }
    if (m_padding.left == 0U && label->m_padding.left != 0U) {
      m_padding.left = label->m_padding.left;
    }
    if (m_padding.right == 0U && label->m_padding.right != 0U) {
      m_padding.right = label->m_padding.right;
    }
    if (m_margin.left == 0U && label->m_margin.left != 0U) {
      m_margin.left = label->m_margin.left;
    }
    if (m_margin.right == 0U && label->m_margin.right != 0U) {
      m_margin.right = label->m_margin.right;
    }
    if (m_maxlen == 0_z && label->m_maxlen != 0_z) {
      m_maxlen = label->m_maxlen;
      m_ellipsis = label->m_ellipsis;
    }
  }

  /**
   * Create a label by loading values from the configuration
   */
  label_t load_label(const config& conf, const string& section, string name, bool required, string def) {
    vector<token> tokens;
    size_t start, end, pos;

    name = string_util::ltrim(string_util::rtrim(move(name), '>'), '<');

    string text;

    struct side_values padding {
    }, margin{};

    if (required) {
      text = conf.get(section, name);
    } else {
      text = conf.get(section, name, move(def));
    }

    size_t len{text.size()};

    if (len > 2 && text[0] == '"' && text[len - 1] == '"') {
      text = text.substr(1, len - 2);
    }

    const auto get_left_right = [&](string key) {
      auto value = conf.get(section, key, 0U);
      auto left = conf.get(section, key + "-left", value);
      auto right = conf.get(section, key + "-right", value);
      return side_values{static_cast<unsigned short int>(left), static_cast<unsigned short int>(right)};
    };

    padding = get_left_right(name + "-padding");
    margin = get_left_right(name + "-margin");

    string line{text};

    while ((start = line.find('%')) != string::npos && (end = line.find('%', start + 1)) != string::npos) {
      auto token_str = line.substr(start, end - start + 1);

      // ignore false positives
      //   lemonbar tags %{...}
      //   trailing percentage signs %token%%
      if (token_str.find_first_of("abcdefghijklmnopqrstuvwxyz") != 1) {
        line.erase(0, end);
        continue;
      }

      line.erase(start, end - start + 1);
      tokens.emplace_back(token{token_str, 0_z, 0_z});
      auto& token = tokens.back();

      // find min delimiter
      if ((pos = token_str.find(':')) == string::npos) {
        continue;
      }

      // strip min/max specifiers from the label string token
      token.token = token_str.substr(0, pos) + '%';
      text = string_util::replace(text, token_str, token.token);

      try {
        token.min = std::stoul(&token_str[pos + 1], nullptr, 10);
      } catch (const std::invalid_argument& err) {
        continue;
      }

      // find max delimiter
      if ((pos = token_str.find(':', pos + 1)) == string::npos) {
        continue;
      }

      try {
        token.max = std::stoul(&token_str[pos + 1], nullptr, 10);
      } catch (const std::invalid_argument& err) {
        continue;
      }

      // ignore max lengths less than min
      if (token.max < token.min) {
        token.max = 0_z;
      }

      // find suffix delimiter
      if ((pos = token_str.find(':', pos + 1)) != string::npos) {
        token.suffix = token_str.substr(pos + 1, token_str.size() - pos - 2);
      }
    }

    size_t maxlen = conf.get(section, name + "-maxlen", 0_z);
    bool ellipsis = conf.get(section, name + "-ellipsis", true);

    if(ellipsis && maxlen > 0 && maxlen < 3) {
      throw application_error(sstream()
          << "Label " << section << "." << name
          << " has maxlen " << maxlen
          << ", which is smaller than length of ellipsis (3)");
    }

    // clang-format off
    return factory_util::shared<label>(text,
        conf.get(section, name + "-foreground", ""s),
        conf.get(section, name + "-background", ""s),
        conf.get(section, name + "-underline", ""s),
        conf.get(section, name + "-overline", ""s),
        conf.get(section, name + "-font", 0),
        padding,
        margin,
        maxlen,
        ellipsis,
        move(tokens));
    // clang-format on
  }

  /**
   * Create a label by loading optional values from the configuration
   */
  label_t load_optional_label(const config& conf, string section, string name, string def) {
    return load_label(conf, move(section), move(name), false, move(def));
  }

  /**
   * Create an icon by loading values from the configuration
   */
  icon_t load_icon(const config& conf, string section, string name, bool required, string def) {
    return load_label(conf, move(section), move(name), required, move(def));
  }

  /**
   * Create an icon by loading optional values from the configuration
   */
  icon_t load_optional_icon(const config& conf, string section, string name, string def) {
    return load_icon(conf, move(section), move(name), false, move(def));
  }
}

POLYBAR_NS_END
<|endoftext|>


<commit_before>#ifdef DE

#include"global.h"
#include"grid3D.h"
#include<stdio.h>
#include<stdlib.h>
#include"math.h"
#include <iostream>

#ifdef PARALLEL_OMP
#include"parallel_omp.h"
#endif

#ifdef MPI_CHOLLA
#include"mpi_routines.h"
#endif

int Grid3D::Select_Internal_Energy_From_DE( Real E, Real U_total, Real U_advected ){

  Real eta = DE_LIMIT;

  if( U_total / E > eta ) return 0;
  else return 1;
}

void Grid3D::Sync_Energies_3D_CPU(){
  #ifndef PARALLEL_OMP
  Sync_Energies_3D_CPU_function( 0, H.nz_real );
  #ifdef TEMPERATURE_FLOOR
  Apply_Temperature_Floor_CPU_function( 0, H.nz_real );
  #endif
  #else
  #pragma omp parallel num_threads( N_OMP_THREADS )
  {
    int omp_id, n_omp_procs;
    int g_start, g_end;

    omp_id = omp_get_thread_num();
    n_omp_procs = omp_get_num_threads();
    Get_OMP_Grid_Indxs( H.nz_real, n_omp_procs, omp_id, &g_start, &g_end  );

    Sync_Energies_3D_CPU_function( g_start, g_end );
    #ifdef TEMPERATURE_FLOOR
    #pragma omp barrier
    Apply_Temperature_Floor_CPU_function( g_start, g_end );
    #endif
  }
  #endif

}

void Grid3D::Sync_Energies_3D_CPU_function( int g_start, int g_end ){

  int nx_grid, ny_grid, nz_grid, nGHST_grid;
  nGHST_grid = H.n_ghost;
  nx_grid = H.nx;
  ny_grid = H.ny;
  nz_grid = H.nz;

  int nx, ny, nz;
  nx = H.nx_real;
  ny = H.ny_real;
  nz = H.nz_real;

  int nGHST = nGHST_grid ;
  Real d, d_inv, vx, vy, vz, E, Ek, ge_total, ge_advected, Emax;
  int k, j, i, id;
  int k_g, j_g, i_g;

  Real eta = DE_LIMIT;

  int imo, ipo, jmo, jpo, kmo, kpo;
  for ( k_g=g_start; k_g<g_end; k_g++ ){
    for ( j_g=0; j_g<ny; j_g++ ){
      for ( i_g=0; i_g<nx; i_g++ ){

        i = i_g + nGHST;
        j = j_g + nGHST;
        k = k_g + nGHST;

        id  = (i) + (j)*nx_grid + (k)*ny_grid*nx_grid;
        imo = (i-1) + (j)*nx_grid + (k)*ny_grid*nx_grid;
        ipo = (i+1) + (j)*nx_grid + (k)*ny_grid*nx_grid;
        jmo = (i) + (j-1)*nx_grid + (k)*ny_grid*nx_grid;
        jpo = (i) + (j+1)*nx_grid + (k)*ny_grid*nx_grid;
        kmo = (i) + (j)*nx_grid + (k-1)*ny_grid*nx_grid;
        kpo = (i) + (j)*nx_grid + (k+1)*ny_grid*nx_grid;

        d = C.density[id];
        d_inv = 1/d;
        vx = C.momentum_x[id] * d_inv;
        vy = C.momentum_y[id] * d_inv;
        vz = C.momentum_z[id] * d_inv;
        E = C.Energy[id];

        // if (E < 0.0 || E != E) continue; // BUG: This leads to negative Energy
        Ek = 0.5*d*(vx*vx + vy*vy + vz*vz);
        ge_total = E - Ek;
        ge_advected = C.GasEnergy[id];

        // //Dont Change Internal energies based on first condition,
        // //This condition is used only to compute pressure and Intenal energy for cooling step
        #ifdef LIMIT_DE_EKINETIC
        if (ge_total > 0.0 && E > 0.0 && ge_total/E > eta && Ek/H.Ekin_avrg > 0.4 ){
        #else
        if (ge_total > 0.0 && E > 0.0 && ge_total/E > eta ) {
        #endif
          C.GasEnergy[id] = ge_total;
          ge_advected = ge_total;
        }
        //
        // //Syncronize advected internal energy with total internal energy when using total internal energy for dynamical purposes
        // // if (ge_total > 0.0 && E > 0.0 && ge_total/E > eta ) C.GasEnergy[id] = ge_total;
        //
        //Syncronize advected internal energy with total internal energy when using total internal energy based on local maxEnergy condition
        //find the max nearby total energy
        Emax = E;
        Emax = std::max(C.Energy[imo], E);
        Emax = std::max(Emax, C.Energy[ipo]);
        Emax = std::max(Emax, C.Energy[jmo]);
        Emax = std::max(Emax, C.Energy[jpo]);
        Emax = std::max(Emax, C.Energy[kmo]);
        Emax = std::max(Emax, C.Energy[kpo]);
        if (ge_total/Emax > 0.1 && ge_total > 0.0 && Emax > 0.0) {
          C.GasEnergy[id] = ge_total;
        }

        //Dont Change total energy
        // sync the total energy with the internal energy
        else {
          if (ge_advected > 0.0) C.Energy[id] += ge_advected - ge_total;
          else C.GasEnergy[id] = ge_total;
        }
      }
    }
  }
}

#ifdef TEMPERATURE_FLOOR
void Grid3D::Apply_Temperature_Floor_CPU_function( int g_start, int g_end ){

  Real temp_floor = H.temperature_floor;

  #ifdef COOLING_GRACKLE
  if ( Cosmo.current_a > Cool.scale_factor_UVB_on ) temp_floor = 1e3;
  #endif

  Real U_floor = temp_floor / (gama - 1) / MP * KB * 1e-10;

  #ifdef COSMOLOGY
  U_floor /=  Cosmo.v_0_gas * Cosmo.v_0_gas / Cosmo.current_a / Cosmo.current_a;
  #endif

  int nx_grid, ny_grid, nz_grid, nGHST_grid;
  nGHST_grid = H.n_ghost;
  nx_grid = H.nx;
  ny_grid = H.ny;
  nz_grid = H.nz;

  int nx, ny, nz;
  nx = H.nx_real;
  ny = H.ny_real;
  nz = H.nz_real;

  Real U_floor_local, mu;

  int nGHST = nGHST_grid ;
  Real d, vx, vy, vz, Ekin, E, U, GE;
  int k, j, i, id;
  for ( k=g_start; k<g_end; k++ ){
    for ( j=0; j<ny; j++ ){
      for ( i=0; i<nx; i++ ){
        id  = (i+nGHST) + (j+nGHST)*nx_grid + (k+nGHST)*ny_grid*nx_grid;

        d = C.density[id];
        vx = C.momentum_x[id] / d;
        vy = C.momentum_y[id] / d;
        vz = C.momentum_z[id] / d;
        Ekin = 0.5 * d * (vx*vx + vy*vy + vz*vz);
        E = C.Energy[id];

        #ifdef COOLING_GRACKLE
        mu = Cool.Get_Mean_Molecular_Weight( id );
        U_floor_local = U_floor / mu ;
        #else
        U_floor_local = U_floor;
        #endif

        U = ( E - Ekin ) / d;
        if ( U < U_floor_local ) C.Energy[id] = Ekin + d*U_floor;

        #ifdef DE
        GE = C.GasEnergy[id];
        U = GE / d;
        if ( U < U_floor_local ) C.GasEnergy[id] = d*U_floor;
        #endif
      }
    }
  }
}
#endif //TEMPERATURE_FLOOR

Real Grid3D::Get_Average_Kinetic_Energy_function( int g_start, int g_end ){

  int nx_grid, ny_grid, nz_grid, nGHST;
  nGHST = H.n_ghost;
  nx_grid = H.nx;
  ny_grid = H.ny;
  nz_grid = H.nz;

  int nx, ny, nz;
  nx = H.nx_real;
  ny = H.ny_real;
  nz = H.nz_real;

  Real Ek_sum = 0;
  Real d, d_inv, vx, vy, vz, E, Ek;

  int k, j, i, id;
  for ( k=g_start; k<g_end; k++ ){
    for ( j=0; j<ny; j++ ){
      for ( i=0; i<nx; i++ ){

        id  = (i+nGHST) + (j+nGHST)*nx_grid + (k+nGHST)*ny_grid*nx_grid;

        d = C.density[id];
        d_inv = 1/d;
        vx = C.momentum_x[id] * d_inv;
        vy = C.momentum_y[id] * d_inv;
        vz = C.momentum_z[id] * d_inv;
        E = C.Energy[id];
        Ek = 0.5*d*(vx*vx + vy*vy + vz*vz);
        Ek_sum += Ek;
      }
    }
  }
  return Ek_sum;
}

void Grid3D::Get_Average_Kinetic_Energy(){
  Real Ek_sum;

  #ifndef PARALLEL_OMP
  Ek_sum = Get_Average_Kinetic_Energy_function(  0, H.nz_real );
  #else
  Ek_sum = 0;
  Real Ek_sum_all[N_OMP_THREADS];
  #pragma omp parallel num_threads( N_OMP_THREADS )
  {
    int omp_id, n_omp_procs;
    int g_start, g_end;

    omp_id = omp_get_thread_num();
    n_omp_procs = omp_get_num_threads();
    Get_OMP_Grid_Indxs( H.nz_real, n_omp_procs, omp_id,  &g_start, &g_end  );
    Ek_sum_all[omp_id] = Get_Average_Kinetic_Energy_function(  g_start, g_end );

  }
  for ( int i=0; i<N_OMP_THREADS; i++ ){
    Ek_sum += Ek_sum_all[i];
  }
  #endif

  #ifdef MPI_CHOLLA
  Ek_sum /=  ( H.nx_real * H.ny_real * H.nz_real);
  H.Ekin_avrg = ReduceRealAvg(Ek_sum);
  #else
  H.Ekin_avrg = Ek_sum / ( H.nx_real * H.ny_real * H.nz_real);
  #endif

}

#endif<commit_msg>fixed error on temperature floor<commit_after>#ifdef DE

#include"global.h"
#include"grid3D.h"
#include<stdio.h>
#include<stdlib.h>
#include"math.h"
#include <iostream>

#ifdef PARALLEL_OMP
#include"parallel_omp.h"
#endif

#ifdef MPI_CHOLLA
#include"mpi_routines.h"
#endif

int Grid3D::Select_Internal_Energy_From_DE( Real E, Real U_total, Real U_advected ){

  Real eta = DE_LIMIT;

  if( U_total / E > eta ) return 0;
  else return 1;
}

void Grid3D::Sync_Energies_3D_CPU(){
  #ifndef PARALLEL_OMP
  Sync_Energies_3D_CPU_function( 0, H.nz_real );
  #ifdef TEMPERATURE_FLOOR
  Apply_Temperature_Floor_CPU_function( 0, H.nz_real );
  #endif
  #else
  #pragma omp parallel num_threads( N_OMP_THREADS )
  {
    int omp_id, n_omp_procs;
    int g_start, g_end;

    omp_id = omp_get_thread_num();
    n_omp_procs = omp_get_num_threads();
    Get_OMP_Grid_Indxs( H.nz_real, n_omp_procs, omp_id, &g_start, &g_end  );

    Sync_Energies_3D_CPU_function( g_start, g_end );
    #ifdef TEMPERATURE_FLOOR
    #pragma omp barrier
    Apply_Temperature_Floor_CPU_function( g_start, g_end );
    #endif
  }
  #endif

}

void Grid3D::Sync_Energies_3D_CPU_function( int g_start, int g_end ){

  int nx_grid, ny_grid, nz_grid, nGHST_grid;
  nGHST_grid = H.n_ghost;
  nx_grid = H.nx;
  ny_grid = H.ny;
  nz_grid = H.nz;

  int nx, ny, nz;
  nx = H.nx_real;
  ny = H.ny_real;
  nz = H.nz_real;

  int nGHST = nGHST_grid ;
  Real d, d_inv, vx, vy, vz, E, Ek, ge_total, ge_advected, Emax;
  int k, j, i, id;
  int k_g, j_g, i_g;

  Real eta = DE_LIMIT;

  int imo, ipo, jmo, jpo, kmo, kpo;
  for ( k_g=g_start; k_g<g_end; k_g++ ){
    for ( j_g=0; j_g<ny; j_g++ ){
      for ( i_g=0; i_g<nx; i_g++ ){

        i = i_g + nGHST;
        j = j_g + nGHST;
        k = k_g + nGHST;

        id  = (i) + (j)*nx_grid + (k)*ny_grid*nx_grid;
        imo = (i-1) + (j)*nx_grid + (k)*ny_grid*nx_grid;
        ipo = (i+1) + (j)*nx_grid + (k)*ny_grid*nx_grid;
        jmo = (i) + (j-1)*nx_grid + (k)*ny_grid*nx_grid;
        jpo = (i) + (j+1)*nx_grid + (k)*ny_grid*nx_grid;
        kmo = (i) + (j)*nx_grid + (k-1)*ny_grid*nx_grid;
        kpo = (i) + (j)*nx_grid + (k+1)*ny_grid*nx_grid;

        d = C.density[id];
        d_inv = 1/d;
        vx = C.momentum_x[id] * d_inv;
        vy = C.momentum_y[id] * d_inv;
        vz = C.momentum_z[id] * d_inv;
        E = C.Energy[id];

        // if (E < 0.0 || E != E) continue; // BUG: This leads to negative Energy
        Ek = 0.5*d*(vx*vx + vy*vy + vz*vz);
        ge_total = E - Ek;
        ge_advected = C.GasEnergy[id];

        // //Dont Change Internal energies based on first condition,
        // //This condition is used only to compute pressure and Intenal energy for cooling step
        #ifdef LIMIT_DE_EKINETIC
        if (ge_total > 0.0 && E > 0.0 && ge_total/E > eta && Ek/H.Ekin_avrg > 0.4 ){
        #else
        if (ge_total > 0.0 && E > 0.0 && ge_total/E > eta ) {
        #endif
          C.GasEnergy[id] = ge_total;
          ge_advected = ge_total;
        }
        //
        // //Syncronize advected internal energy with total internal energy when using total internal energy for dynamical purposes
        // // if (ge_total > 0.0 && E > 0.0 && ge_total/E > eta ) C.GasEnergy[id] = ge_total;
        //
        //Syncronize advected internal energy with total internal energy when using total internal energy based on local maxEnergy condition
        //find the max nearby total energy
        Emax = E;
        Emax = std::max(C.Energy[imo], E);
        Emax = std::max(Emax, C.Energy[ipo]);
        Emax = std::max(Emax, C.Energy[jmo]);
        Emax = std::max(Emax, C.Energy[jpo]);
        Emax = std::max(Emax, C.Energy[kmo]);
        Emax = std::max(Emax, C.Energy[kpo]);
        if (ge_total/Emax > 0.1 && ge_total > 0.0 && Emax > 0.0) {
          C.GasEnergy[id] = ge_total;
        }

        //Dont Change total energy
        // sync the total energy with the internal energy
        else {
          if (ge_advected > 0.0) C.Energy[id] += ge_advected - ge_total;
          else C.GasEnergy[id] = ge_total;
        }
      }
    }
  }
}

#ifdef TEMPERATURE_FLOOR
void Grid3D::Apply_Temperature_Floor_CPU_function( int g_start, int g_end ){

  Real temp_floor = H.temperature_floor;

  #ifdef COOLING_GRACKLE
  if ( Cosmo.current_a > Cool.scale_factor_UVB_on ) temp_floor = 3e2;
  #endif

  Real U_floor = temp_floor / (gama - 1) / MP * KB * 1e-10;

  #ifdef COSMOLOGY
  U_floor /=  Cosmo.v_0_gas * Cosmo.v_0_gas / Cosmo.current_a / Cosmo.current_a;
  #endif

  int nx_grid, ny_grid, nz_grid, nGHST_grid;
  nGHST_grid = H.n_ghost;
  nx_grid = H.nx;
  ny_grid = H.ny;
  nz_grid = H.nz;

  int nx, ny, nz;
  nx = H.nx_real;
  ny = H.ny_real;
  nz = H.nz_real;

  Real U_floor_local, mu;

  int nGHST = nGHST_grid ;
  Real d, vx, vy, vz, Ekin, E, U, GE;
  int k, j, i, id;
  for ( k=g_start; k<g_end; k++ ){
    for ( j=0; j<ny; j++ ){
      for ( i=0; i<nx; i++ ){
        id  = (i+nGHST) + (j+nGHST)*nx_grid + (k+nGHST)*ny_grid*nx_grid;

        d = C.density[id];
        vx = C.momentum_x[id] / d;
        vy = C.momentum_y[id] / d;
        vz = C.momentum_z[id] / d;
        Ekin = 0.5 * d * (vx*vx + vy*vy + vz*vz);
        E = C.Energy[id];

        #ifdef COOLING_GRACKLE
        mu = Cool.Get_Mean_Molecular_Weight( id );
        U_floor_local = U_floor / mu ;
        #else
        U_floor_local = U_floor;
        #endif

        U = ( E - Ekin ) / d;
        if ( U < U_floor_local ) C.Energy[id] = Ekin + d*U_floor_local;

        #ifdef DE
        GE = C.GasEnergy[id];
        U = GE / d;
        if ( U < U_floor_local ) C.GasEnergy[id] = d*U_floor_local;
        #endif
      }
    }
  }
}
#endif //TEMPERATURE_FLOOR

Real Grid3D::Get_Average_Kinetic_Energy_function( int g_start, int g_end ){

  int nx_grid, ny_grid, nz_grid, nGHST;
  nGHST = H.n_ghost;
  nx_grid = H.nx;
  ny_grid = H.ny;
  nz_grid = H.nz;

  int nx, ny, nz;
  nx = H.nx_real;
  ny = H.ny_real;
  nz = H.nz_real;

  Real Ek_sum = 0;
  Real d, d_inv, vx, vy, vz, E, Ek;

  int k, j, i, id;
  for ( k=g_start; k<g_end; k++ ){
    for ( j=0; j<ny; j++ ){
      for ( i=0; i<nx; i++ ){

        id  = (i+nGHST) + (j+nGHST)*nx_grid + (k+nGHST)*ny_grid*nx_grid;

        d = C.density[id];
        d_inv = 1/d;
        vx = C.momentum_x[id] * d_inv;
        vy = C.momentum_y[id] * d_inv;
        vz = C.momentum_z[id] * d_inv;
        E = C.Energy[id];
        Ek = 0.5*d*(vx*vx + vy*vy + vz*vz);
        Ek_sum += Ek;
      }
    }
  }
  return Ek_sum;
}

void Grid3D::Get_Average_Kinetic_Energy(){
  Real Ek_sum;

  #ifndef PARALLEL_OMP
  Ek_sum = Get_Average_Kinetic_Energy_function(  0, H.nz_real );
  #else
  Ek_sum = 0;
  Real Ek_sum_all[N_OMP_THREADS];
  #pragma omp parallel num_threads( N_OMP_THREADS )
  {
    int omp_id, n_omp_procs;
    int g_start, g_end;

    omp_id = omp_get_thread_num();
    n_omp_procs = omp_get_num_threads();
    Get_OMP_Grid_Indxs( H.nz_real, n_omp_procs, omp_id,  &g_start, &g_end  );
    Ek_sum_all[omp_id] = Get_Average_Kinetic_Energy_function(  g_start, g_end );

  }
  for ( int i=0; i<N_OMP_THREADS; i++ ){
    Ek_sum += Ek_sum_all[i];
  }
  #endif

  #ifdef MPI_CHOLLA
  Ek_sum /=  ( H.nx_real * H.ny_real * H.nz_real);
  H.Ekin_avrg = ReduceRealAvg(Ek_sum);
  #else
  H.Ekin_avrg = Ek_sum / ( H.nx_real * H.ny_real * H.nz_real);
  #endif

}

#endif<|endoftext|>


<commit_before>#include "propertyEditorView.h"
#include "mainWindow.h"

PropertyEditorView::PropertyEditorView(QWidget *parent) :
	QWidget(parent)
{
	mModel = NULL;
	mPropertyEditor = new QtTreePropertyBrowser(this);
	mPropertyEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}

/*
	QAbstractItemView's slots
*/
void PropertyEditorView::setModel(PropertyEditorModel *model)
{
	mModel = model;
	connect(mModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
		this, SLOT(dataChanged(QModelIndex,QModelIndex)));
	connect(mModel, SIGNAL(modelReset()), this, SLOT(reset()));
}

void PropertyEditorView::scrollTo(const QModelIndex &, QAbstractItemView::ScrollHint)
{
	// do nothing
}

void PropertyEditorView::reset()
{
	setRootIndex(QModelIndex());
}

void PropertyEditorView::update(const QModelIndex &)
{
	QWidget::update();
}

void PropertyEditorView::setRootIndex(const QModelIndex &index)
{
	mPropertyEditor->clear();
	mPropertiesRows.clear();
	QtVariantPropertyManager *variantManager = new QtVariantPropertyManager();
	QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory();

	PushButtonPropertyManager *buttonManager = new PushButtonPropertyManager();
	PushButtonFactory *buttonFactory = new PushButtonFactory();

	mPropertyEditor->setFactoryForManager(buttonManager, buttonFactory);
	mPropertyEditor->setFactoryForManager(variantManager, variantFactory);

	for(int i = 0, rows = mModel->rowCount(index); i < rows; ++i){
		QModelIndex const &valueCell = mModel->index(i, 1);
		QString name = mModel->data(mModel->index(i, 0)).toString();
		QVariant const &value = mModel->data(valueCell);

		int type = QVariant::String;
		QString typeName = mModel->typeName(valueCell).toLower();
		QStringList values = mModel->enumValues(valueCell);
		bool isButton = false;
		if(typeName == "int"){
			type = QVariant::Int;
		} else if(typeName == "bool"){
			type = QVariant::Bool;
		} else if(typeName == "string") {
			type = QVariant::String;
		} else if(!values.isEmpty()){
			type = QtVariantPropertyManager::enumTypeId();
		} else {
			if(name == "shape") // hack
				isButton = true;
		}
//		qDebug() << name << ":" << typeName;

		QtProperty *item = NULL;
		if(isButton){
			item = buttonManager->addProperty(name);
		} else {
			QtVariantProperty *vItem = variantManager->addProperty(type, name);

			vItem->setValue(value);
			vItem->setToolTip(value.toString());
			if(!values.isEmpty()){
				vItem->setAttribute("enumNames", values);
				if(values.contains(value.toString())){
					vItem->setValue(values.indexOf(value.toString()));
				}
			}
			item = vItem;
		}
		mPropertiesRows[valueCell] = item;
		mPropertyEditor->addProperty(item);
	}

	connect(buttonManager, SIGNAL(buttonClicked(QtProperty*)),
		this, SLOT(buttonClicked(QtProperty*))); // <---==
	connect(variantManager, SIGNAL(valueChanged(QtProperty*, QVariant)),
		this, SLOT(editorValueChanged(QtProperty *, QVariant)));
	mPropertyEditor->setPropertiesWithoutValueMarked(true);
	mPropertyEditor->setRootIsDecorated(false);
}

void PropertyEditorView::dataChanged(const QModelIndex &, const QModelIndex &)
{
	for(int i = 0, rows = mModel->rowCount(QModelIndex()); i < rows; ++i){
		QModelIndex const &valueIndex = mModel->index(i, 1);
		QtVariantProperty *property = dynamic_cast<QtVariantProperty*>(mPropertiesRows[valueIndex]);
		QVariant const &value = valueIndex.data();
		if(property){
			property->setValue(value);
			property->setToolTip(value.toString());
		}
	}
}

void PropertyEditorView::buttonClicked(QtProperty *property)
{
	QModelIndex const &index = mPropertiesRows.key(property);

	QString propertyValue = index.data(Qt::DisplayRole).toString();
	QPersistentModelIndex const actualIndex = mModel->modelIndex(index.row());
	int role = mModel->roleByIndex(index.row());

	mMainWindow->openShapeEditor(actualIndex, role, propertyValue);
}

void PropertyEditorView::init(qReal::MainWindow *mainWindow, qReal::models::LogicalModelAssistApi *const logicalModelAssistApi)
{
	mMainWindow = mainWindow;
	mLogicalModelAssistApi = logicalModelAssistApi;
}

void PropertyEditorView::editorValueChanged(QtProperty *prop, QVariant value)
{
	QtVariantProperty *property = dynamic_cast<QtVariantProperty*>(prop);
	int propertyType = property->propertyType();
	QModelIndex const &index = mPropertiesRows.key(property);
	if(propertyType == QtVariantPropertyManager::enumTypeId()){
		QStringList const &values = mModel->enumValues(index);
		int intValue = value.toInt();
		if(intValue >= 0 && intValue < values.length()){
			value = values.at(intValue);
		}
	}
	mModel->setData(index, value, Qt::EditRole);
}
<commit_msg>PropertyEditor fix: crush on checkbox check fixed<commit_after>#include "propertyEditorView.h"
#include "mainWindow.h"

PropertyEditorView::PropertyEditorView(QWidget *parent) :
	QWidget(parent)
{
	mModel = NULL;
	mPropertyEditor = new QtTreePropertyBrowser(this);
	mPropertyEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}

/*
	QAbstractItemView's slots
*/
void PropertyEditorView::setModel(PropertyEditorModel *model)
{
	mModel = model;
	connect(mModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
		this, SLOT(dataChanged(QModelIndex,QModelIndex)));
	connect(mModel, SIGNAL(modelReset()), this, SLOT(reset()));
}

void PropertyEditorView::scrollTo(const QModelIndex &, QAbstractItemView::ScrollHint)
{
	// do nothing
}

void PropertyEditorView::reset()
{
	setRootIndex(QModelIndex());
}

void PropertyEditorView::update(const QModelIndex &)
{
	QWidget::update();
}

void PropertyEditorView::setRootIndex(const QModelIndex &index)
{
	mPropertyEditor->clear();
	mPropertiesRows.clear();
	QtVariantPropertyManager *variantManager = new QtVariantPropertyManager();
	QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory();

	PushButtonPropertyManager *buttonManager = new PushButtonPropertyManager();
	PushButtonFactory *buttonFactory = new PushButtonFactory();

	mPropertyEditor->setFactoryForManager(buttonManager, buttonFactory);
	mPropertyEditor->setFactoryForManager(variantManager, variantFactory);

	for(int i = 0, rows = mModel->rowCount(index); i < rows; ++i){
		QModelIndex const &valueCell = mModel->index(i, 1);
		QString name = mModel->data(mModel->index(i, 0)).toString();
		QVariant const &value = mModel->data(valueCell);

		int type = QVariant::String;
		QString typeName = mModel->typeName(valueCell).toLower();
		QStringList values = mModel->enumValues(valueCell);
		bool isButton = false;
		if(typeName == "int"){
			type = QVariant::Int;
		} else if(typeName == "bool"){
			type = QVariant::Bool;
		} else if(typeName == "string") {
			type = QVariant::String;
		} else if(!values.isEmpty()){
			type = QtVariantPropertyManager::enumTypeId();
		} else {
			if(name == "shape") // hack
				isButton = true;
		}
//		qDebug() << name << ":" << typeName;

		QtProperty *item = NULL;
		if(isButton){
			item = buttonManager->addProperty(name);
		} else {
			QtVariantProperty *vItem = variantManager->addProperty(type, name);

			vItem->setValue(value);
			vItem->setToolTip(value.toString());
			if(!values.isEmpty()){
				vItem->setAttribute("enumNames", values);
				if(values.contains(value.toString())){
					vItem->setValue(values.indexOf(value.toString()));
				}
			}
			item = vItem;
		}
		mPropertiesRows[valueCell] = item;
		mPropertyEditor->addProperty(item);
	}

	connect(buttonManager, SIGNAL(buttonClicked(QtProperty*)),
		this, SLOT(buttonClicked(QtProperty*))); // <---==
	connect(variantManager, SIGNAL(valueChanged(QtProperty*, QVariant)),
		this, SLOT(editorValueChanged(QtProperty *, QVariant)));
	mPropertyEditor->setPropertiesWithoutValueMarked(true);
	mPropertyEditor->setRootIsDecorated(false);
}

void PropertyEditorView::dataChanged(const QModelIndex &, const QModelIndex &)
{
	for(int i = 0, rows = mModel->rowCount(QModelIndex()); i < rows; ++i){
		QModelIndex const &valueIndex = mModel->index(i, 1);
		QtVariantProperty *property = dynamic_cast<QtVariantProperty*>(mPropertiesRows[valueIndex]);
		QVariant const &value = valueIndex.data();
		if(property){
			property->setValue(value);
			property->setToolTip(value.toString());
		}
	}
}

void PropertyEditorView::buttonClicked(QtProperty *property)
{
	QModelIndex const &index = mPropertiesRows.key(property);

	QString propertyValue = index.data(Qt::DisplayRole).toString();
	QPersistentModelIndex const actualIndex = mModel->modelIndex(index.row());
	int role = mModel->roleByIndex(index.row());

	mMainWindow->openShapeEditor(actualIndex, role, propertyValue);
}

void PropertyEditorView::init(qReal::MainWindow *mainWindow, qReal::models::LogicalModelAssistApi *const logicalModelAssistApi)
{
	mMainWindow = mainWindow;
	mLogicalModelAssistApi = logicalModelAssistApi;
}

void PropertyEditorView::editorValueChanged(QtProperty *prop, QVariant value)
{
	QtVariantProperty *property = dynamic_cast<QtVariantProperty*>(prop);
	int propertyType = property->propertyType();
	QModelIndex const &index = mPropertiesRows.key(property);
	if(propertyType == QtVariantPropertyManager::enumTypeId()){
		QStringList const &values = mModel->enumValues(index);
		int intValue = value.toInt();
		if(intValue >= 0 && intValue < values.length()){
			value = values.at(intValue);
		}
	}
	value = QVariant(value.toString());
	mModel->setData(index, value, Qt::EditRole);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: b2dpolypolygontools.hxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: kz $ $Date: 2005-11-02 13:53:57 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX
#define _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX

#ifndef _BGFX_POINT_B2DPOINT_HXX
#include <basegfx/point/b2dpoint.hxx>
#endif

#ifndef _BGFX_VECTOR_B2DVECTOR_HXX
#include <basegfx/vector/b2dvector.hxx>
#endif

#ifndef _BGFX_POLYGON_B2DPOLYGON_HXX
#include <basegfx/polygon/b2dpolygon.hxx>
#endif

#ifndef _BGFX_POLYGON_B3DPOLYPOLYGON_HXX
#include <basegfx/polygon/b3dpolypolygon.hxx>
#endif

#include <vector>

namespace rtl
{
    class OUString;
}

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

namespace basegfx
{
    // predefinitions
    class B2DPolyPolygon;
    class B2DRange;

    namespace tools
    {
        // B2DPolyPolygon tools

        // Check and evtl. correct orientations of all contained Polygons so that
        // the orientations of contained polygons will variate to express areas and
        // holes
        B2DPolyPolygon correctOrientations(const B2DPolyPolygon& rCandidate);

        // Remove all intersections, the self intersections and the in-between
        // polygon intersections. After this operation there are no more intersections
        // in the given PolyPolygon. Only closed polygons are handled. The non-closed
        // polygons or the ones with less than 3 points are preserved, but not
        // computed.
        // bForceOrientation: If true, the orientations of all contained polygons
        // is changed to ORIENTATION_POSITIVE before computing.
        B2DPolyPolygon removeIntersections(const B2DPolyPolygon& rCandidate);
        B2DPolyPolygon removeAllIntersections(const B2DPolyPolygon& rCandidate);
        B2DPolyPolygon removeNeutralPolygons(const B2DPolyPolygon& rCandidate, bool bUseOr);

        // Subdivide all contained curves. Use distanceBound value if given.
        B2DPolyPolygon adaptiveSubdivideByDistance(const B2DPolyPolygon& rCandidate, double fDistanceBound = 0.0);

        // Subdivide all contained curves. Use distanceBound value if given. Else, a convenient one
        // is created.
        B2DPolyPolygon adaptiveSubdivideByAngle(const B2DPolyPolygon& rCandidate, double fAngleBound = 0.0);

        // Subdivide all contained curves. Use nCount divisions if given. Else, a convenient one
        // is created.
        B2DPolyPolygon adaptiveSubdivideByCount(const B2DPolyPolygon& rCandidate, sal_uInt32 nCount = 0L);

        // isInside test for B2dPoint. On border is not inside as long as not true is given
        // in bWithBorder flag. It is assumed that the orientations of the given polygon are correct.
        bool isInside(const B2DPolyPolygon& rCandidate, const B2DPoint& rPoint, bool bWithBorder = false);

        // get size of PolyPolygon. Control vectors are included in that ranges.
        B2DRange getRange(const B2DPolyPolygon& rCandidate);

        // Apply Line Dashing. This cuts every contained PolyPolygon into line pieces
        // which are inserted as single polygons into the result.
        // If fFullDashDotLen is not given it will be calculated from the given
        // raDashDotArray.
        B2DPolyPolygon applyLineDashing(const B2DPolyPolygon& rCandidate, const ::std::vector<double>& raDashDotArray, double fFullDashDotLen = 0.0);

        // Merge contained Polygons to longer ones if the end point of one Polygon equals
        // the start point of the next one. Only direct successors are checked.
        // This method is mainly for joining line snippets which reach over an original
        // polygon edge after using applyLineDashing. This is necessary if the dashed line
        // parts shall be used for creating thick line geometry to be able to do correct
        // line joints.
        B2DPolyPolygon mergeDashedLines(const B2DPolyPolygon& rCandidate);

        // test if point is inside epsilon-range around the given PolyPolygon. Can be used
        // for HitTesting. The epsilon-range is defined to be the tube around the PolyPolygon
        // with distance fDistance and rounded edges (start and end point).
        bool isInEpsilonRange(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPosition, double fDistance);

        /** Read poly-polygon from SVG.

            This function imports a poly-polygon from an SVG-D
            statement. Currently, elliptical arc elements are not yet
            supported (and ignored during parsing).

            @param o_rPolyPoly
            The output poly-polygon

            @param rSvgDStatement
            A valid SVG-D statement

            @return true, if the string was successfully parsed
         */
        bool importFromSvgD( B2DPolyPolygon& o_rPolyPoly,
                             const ::rtl::OUString&     rSvgDStatement );

        // create 3d PolyPolygon from given 2d PolyPolygon. The given fZCoordinate is used to expand the
        // third coordinate.
        B3DPolyPolygon createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon& rCandidate, double fZCoordinate = 0.0);

        // create 2d PolyPolygon from given 3d PolyPolygon. All coordinates are transformed using the given
        // matrix and the resulting x,y is used to form the new polygon.
        B2DPolyPolygon createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon& rCandidate, const B3DHomMatrix& rMat);

        // for each contained edge in each contained polygon calculate the smallest distance. Return the index to the smallest
        // edge in rEdgeIndex and the index to the polygon in rPolygonIndex. The relative position on the edge is returned in rCut.
        // If nothing was found (e.g. empty input plygon), DBL_MAX is returned.
        double getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPoint, sal_uInt32& rPolygonIndex, sal_uInt32& rEdgeIndex, double& rCut);

        // distort PolyPolygon. rOriginal describes the original range, where the given points describe the distorted
        // corresponding points.
        B2DPolyPolygon distort(const B2DPolyPolygon& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight);

        // rotate PolyPolygon around given point with given angle.
        B2DPolyPolygon rotateAroundPoint(const B2DPolyPolygon& rCandidate, const B2DPoint& rCenter, double fAngle);

        // expand all segments (which are not yet) to curve segments. This is done with setting the control
        // vectors on the 1/3 resp. 2/3 distances on each segment.
        B2DPolyPolygon expandToCurve(const B2DPolyPolygon& rCandidate);

        // set continuity for the whole curve. If not a curve, nothing will change. Non-curve points are not changed, too.
        B2DPolyPolygon setContinuity(const B2DPolyPolygon& rCandidate, B2VectorContinuity eContinuity);

        /** Predicate whether a given poly-polygon is a rectangle.

            @param rPoly
            PolyPolygon to check

            @return true, if the poly-polygon describes a rectangle
            (contains exactly one polygon, polygon is closed, and the
            points are either cw or ccw enumerations of a rectangle's
            vertices). Note that intermediate points and duplicate
            points are ignored.
         */
        bool isRectangle( const B2DPolyPolygon& rPoly );

    } // end of namespace tools
} // end of namespace basegfx

#endif /* _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX */
<commit_msg>INTEGRATION: CWS presfixes09 (1.14.10); FILE MERGED 2006/03/15 16:09:48 thb 1.14.10.1: #i49357# Added SVG-D export method for basegfx poly-polygons<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: b2dpolypolygontools.hxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-13 15:06:35 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX
#define _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX

#ifndef _BGFX_POINT_B2DPOINT_HXX
#include <basegfx/point/b2dpoint.hxx>
#endif

#ifndef _BGFX_VECTOR_B2DVECTOR_HXX
#include <basegfx/vector/b2dvector.hxx>
#endif

#ifndef _BGFX_POLYGON_B2DPOLYGON_HXX
#include <basegfx/polygon/b2dpolygon.hxx>
#endif

#ifndef _BGFX_POLYGON_B3DPOLYPOLYGON_HXX
#include <basegfx/polygon/b3dpolypolygon.hxx>
#endif

#include <vector>

namespace rtl
{
    class OUString;
}

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

namespace basegfx
{
    // predefinitions
    class B2DPolyPolygon;
    class B2DRange;

    namespace tools
    {
        // B2DPolyPolygon tools

        // Check and evtl. correct orientations of all contained Polygons so that
        // the orientations of contained polygons will variate to express areas and
        // holes
        B2DPolyPolygon correctOrientations(const B2DPolyPolygon& rCandidate);

        // Remove all intersections, the self intersections and the in-between
        // polygon intersections. After this operation there are no more intersections
        // in the given PolyPolygon. Only closed polygons are handled. The non-closed
        // polygons or the ones with less than 3 points are preserved, but not
        // computed.
        // bForceOrientation: If true, the orientations of all contained polygons
        // is changed to ORIENTATION_POSITIVE before computing.
        B2DPolyPolygon removeIntersections(const B2DPolyPolygon& rCandidate);
        B2DPolyPolygon removeAllIntersections(const B2DPolyPolygon& rCandidate);
        B2DPolyPolygon removeNeutralPolygons(const B2DPolyPolygon& rCandidate, bool bUseOr);

        // Subdivide all contained curves. Use distanceBound value if given.
        B2DPolyPolygon adaptiveSubdivideByDistance(const B2DPolyPolygon& rCandidate, double fDistanceBound = 0.0);

        // Subdivide all contained curves. Use distanceBound value if given. Else, a convenient one
        // is created.
        B2DPolyPolygon adaptiveSubdivideByAngle(const B2DPolyPolygon& rCandidate, double fAngleBound = 0.0);

        // Subdivide all contained curves. Use nCount divisions if given. Else, a convenient one
        // is created.
        B2DPolyPolygon adaptiveSubdivideByCount(const B2DPolyPolygon& rCandidate, sal_uInt32 nCount = 0L);

        // isInside test for B2dPoint. On border is not inside as long as not true is given
        // in bWithBorder flag. It is assumed that the orientations of the given polygon are correct.
        bool isInside(const B2DPolyPolygon& rCandidate, const B2DPoint& rPoint, bool bWithBorder = false);

        // get size of PolyPolygon. Control vectors are included in that ranges.
        B2DRange getRange(const B2DPolyPolygon& rCandidate);

        // Apply Line Dashing. This cuts every contained PolyPolygon into line pieces
        // which are inserted as single polygons into the result.
        // If fFullDashDotLen is not given it will be calculated from the given
        // raDashDotArray.
        B2DPolyPolygon applyLineDashing(const B2DPolyPolygon& rCandidate, const ::std::vector<double>& raDashDotArray, double fFullDashDotLen = 0.0);

        // Merge contained Polygons to longer ones if the end point of one Polygon equals
        // the start point of the next one. Only direct successors are checked.
        // This method is mainly for joining line snippets which reach over an original
        // polygon edge after using applyLineDashing. This is necessary if the dashed line
        // parts shall be used for creating thick line geometry to be able to do correct
        // line joints.
        B2DPolyPolygon mergeDashedLines(const B2DPolyPolygon& rCandidate);

        // test if point is inside epsilon-range around the given PolyPolygon. Can be used
        // for HitTesting. The epsilon-range is defined to be the tube around the PolyPolygon
        // with distance fDistance and rounded edges (start and end point).
        bool isInEpsilonRange(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPosition, double fDistance);

        /** Read poly-polygon from SVG.

            This function imports a poly-polygon from an SVG-D
            statement. Currently, elliptical arc elements are not yet
            supported (and ignored during parsing).

            @param o_rPolyPoly
            The output poly-polygon

            @param rSvgDStatement
            A valid SVG-D statement

            @return true, if the string was successfully parsed
         */
        bool importFromSvgD( B2DPolyPolygon& o_rPolyPoly,
                             const ::rtl::OUString&     rSvgDStatement );

        // create 3d PolyPolygon from given 2d PolyPolygon. The given fZCoordinate is used to expand the
        // third coordinate.
        B3DPolyPolygon createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon& rCandidate, double fZCoordinate = 0.0);

        // create 2d PolyPolygon from given 3d PolyPolygon. All coordinates are transformed using the given
        // matrix and the resulting x,y is used to form the new polygon.
        B2DPolyPolygon createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon& rCandidate, const B3DHomMatrix& rMat);

        // for each contained edge in each contained polygon calculate the smallest distance. Return the index to the smallest
        // edge in rEdgeIndex and the index to the polygon in rPolygonIndex. The relative position on the edge is returned in rCut.
        // If nothing was found (e.g. empty input plygon), DBL_MAX is returned.
        double getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPoint, sal_uInt32& rPolygonIndex, sal_uInt32& rEdgeIndex, double& rCut);

        // distort PolyPolygon. rOriginal describes the original range, where the given points describe the distorted
        // corresponding points.
        B2DPolyPolygon distort(const B2DPolyPolygon& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight);

        // rotate PolyPolygon around given point with given angle.
        B2DPolyPolygon rotateAroundPoint(const B2DPolyPolygon& rCandidate, const B2DPoint& rCenter, double fAngle);

        // expand all segments (which are not yet) to curve segments. This is done with setting the control
        // vectors on the 1/3 resp. 2/3 distances on each segment.
        B2DPolyPolygon expandToCurve(const B2DPolyPolygon& rCandidate);

        // set continuity for the whole curve. If not a curve, nothing will change. Non-curve points are not changed, too.
        B2DPolyPolygon setContinuity(const B2DPolyPolygon& rCandidate, B2VectorContinuity eContinuity);

        /** Predicate whether a given poly-polygon is a rectangle.

            @param rPoly
            PolyPolygon to check

            @return true, if the poly-polygon describes a rectangle
            (contains exactly one polygon, polygon is closed, and the
            points are either cw or ccw enumerations of a rectangle's
            vertices). Note that intermediate points and duplicate
            points are ignored.
         */
        bool isRectangle( const B2DPolyPolygon& rPoly );

        /** Export poly-polygon to SVG.

            This function exports a poly-polygon into an SVG-D
            statement. Currently, output of relative point sequences
            is not yet supported (might cause slightly larger output)

            @param rPolyPoly
            The poly-polygon to export

            @param bUseRelativeCoordinates
            When true, all coordinate values are exported as relative
            to the current position. This tends to save some space,
            since fewer digits needs to be written.

            @param bDetectQuadraticBeziers
            When true, the export tries to detect cubic bezier
            segments in the input polygon, which can be represented by
            quadratic bezier segments. Note that the generated string
            causes versions prior to OOo2.0 to crash.

            @return the generated SVG-D statement (the XML d attribute
            value alone, without any "<path ...>" or "d="...")
         */
        ::rtl::OUString exportToSvgD( const B2DPolyPolygon& rPolyPoly,
                                      bool                  bUseRelativeCoordinates=true,
                                      bool                  bDetectQuadraticBeziers=true );

    } // end of namespace tools
} // end of namespace basegfx

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


<commit_before>#include <cppassert/details/DebugPrint.hpp>
#include <cppassert/details/StackTrace.hpp>
#include <stdexcept>
#include <memory>
#include <mutex>
#include <cstdlib>
#include <cstdint>
#include <climits>
#include <Windows.h>
#pragma warning(push)
#pragma warning(disable: 4091 )
#include <DbgHelp.h>
#pragma warning(pop)
#include <strsafe.h>

namespace cppassert
{
    namespace internal
    {

        /**
         * Displays error message related to last occured error
         *
         */
        void DisplayLastError(LPTSTR lpszFunction)
        {
            // Retrieve the system error message for the last-error code

            LPVOID lpMsgBuf;
            LPVOID lpDisplayBuf;
            DWORD dw = GetLastError();

            FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER |
                FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                dw,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR)&lpMsgBuf,
                0, NULL);

            // Display the error message and exit the process

            lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
                (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));

            StringCchPrintf((LPTSTR)lpDisplayBuf,
                LocalSize(lpDisplayBuf) / sizeof(TCHAR),
                TEXT("%s failed with error %d: %s"),
                lpszFunction, dw, lpMsgBuf);

            PrintMessageToStdErr((LPCSTR)lpDisplayBuf);

            LocalFree(lpMsgBuf);
            LocalFree(lpDisplayBuf);
        }

        /**
        * Provides windows implementation of stack trace collection.
        */
        class StackTraceImpl
        {
            StackTraceImpl(const StackTraceImpl &) = delete;
            StackTraceImpl &operator=(const StackTraceImpl &) = delete;
            struct BacktraceSymbol : public StackTrace::StackFrame
            {
                BacktraceSymbol() = default;

                BacktraceSymbol(const void *frameAddr, const char *name)
                {
                    address_ = frameAddr;
                    setSymbol(name);
                }

                void setAddress(const void *frameAddress)
                {
                    address_ = frameAddress;
                }

                void setSymbol(const char *name)
                {
                    if (name && name[0])
                    {
                        strcpy_s(symbolName_, MaxSymbolNameSize, name);
                        symbolName_[MaxSymbolNameSize - 1] = '\0';
                    }
                    else
                    {
                        symbolName_[0] = '\0';
                    }
                    symbol_ = symbolName_;
                }

                enum { MaxSymbolNameSize = MAX_SYM_NAME + 1 };
                char symbolName_[MaxSymbolNameSize];
            };
        public:
            StackTraceImpl()
            {
            }

            ~StackTraceImpl()
            {
            }

            void collect()
            {
                HANDLE              process;
                ULONG               frame;
                PSYMBOL_INFO        symbol;
                DWORD64             displacement;
                PVOID               frames[cFramesSize];
                enum {              MaxNameLen = MAX_SYM_NAME + 1 };
                enum {              BufferSize = sizeof(SYMBOL_INFO)
                                                + MaxNameLen * sizeof(TCHAR) };

                char buffer[BufferSize] = { '\0' };

                symbol = static_cast<PSYMBOL_INFO>(static_cast<void *>(buffer));

                std::memset(symbol, 0, BufferSize);
                std::memset(frames, 0, sizeof(frames));

                symbol->MaxNameLen = MaxNameLen-1;
                symbol->SizeOfStruct = sizeof(SYMBOL_INFO);

                process = GetCurrentProcess();
                displacement = 0;

                symInitialize(process);
                capturedFrames_ = CaptureStackBackTrace(cFramesToSkip
                                            , cFramesSize
                                            , frames
                                            , NULL);

                if (capturedFrames_ > cFramesSize)
                {
                    capturedFrames_ = cFramesSize;
                }

                for (frame = 0; frame<capturedFrames_; frame++)
                {
                    DWORD64 frameAddr = (DWORD64)(frames[frame]);
                    frames_[frame].setAddress(frames[frame]);
                    std::unique_lock<std::mutex> lock(mutex_);
                    if (SymFromAddr(process, frameAddr, &displacement, symbol)
                                    == TRUE)
                    {
                        frames_[frame].setSymbol(symbol->Name);
                    }
                    else
                    {
                        char msgBuffer[512];
                        sprintf_s(msgBuffer, sizeof(msgBuffer)
                                , "Error getting symbol from addr: 0x%016llX 0x%p address size %d bits\n"
                                , frameAddr
                                , frames[frame]
                                , sizeof(PVOID)*CHAR_BIT);
                        msgBuffer[sizeof(msgBuffer)-1] = '\0';
                        PrintMessageToStdErr(msgBuffer);
                        DisplayLastError("SymFromAddr");
                    }
                }
            }

            /**
             * Call to this function should
             */
            void symInitialize(HANDLE process)
            {
                std::unique_lock<std::mutex> lock(mutex_);
                static bool symbolsInitialized = false;
                if(symbolsInitialized==false)
                {
                    //should be only called once
                    if (SymInitialize(process, NULL, TRUE) != TRUE)
                    {
                        DisplayLastError("SymInitialize");
                        return;
                    }
                }
                symbolsInitialized = true;
            }

            /**
            * Returns number of captured frames
            * @return number of captured frames
            */
            std::size_t size() const
            {
                return capturedFrames_;
            }

            /**
             * Returns StackFrame at position \p pos. If pos
             * is outside range (0, size()) throws std::out_of_range exception.
             */
            const StackTrace::StackFrame &at(std::size_t pos) const
            {
                if (pos<capturedFrames_)
                {
                    return frames_[pos];
                }
                throw std::out_of_range("StackTrace::at(pos) out of range");
            }

        private:
            //all dbhelp library functions are not thread safe
            //thats why we need a mutext to protect calls to
            //them
            static std::mutex mutex_;
            enum
            {
                cFramesToSkip = 2
            };

            enum
            {
                cFramesSize = 1024
            };
            BacktraceSymbol frames_[cFramesSize];
            std::size_t capturedFrames_ = 0;
        };

        std::mutex StackTraceImpl::mutex_;

    } //internal
} //asrt

<commit_msg>Fixed issue with formatting<commit_after>#include <cppassert/details/DebugPrint.hpp>
#include <cppassert/details/StackTrace.hpp>
#include <stdexcept>
#include <memory>
#include <mutex>
#include <cstdlib>
#include <cstdint>
#include <climits>
#include <Windows.h>
#pragma warning(push)
#pragma warning(disable: 4091 )
#include <DbgHelp.h>
#pragma warning(pop)
#include <strsafe.h>

namespace cppassert
{
    namespace internal
    {

        /**
         * Displays error message related to last occured error
         *
         */
        void DisplayLastError(LPTSTR lpszFunction)
        {
            // Retrieve the system error message for the last-error code

            LPVOID lpMsgBuf;
            LPVOID lpDisplayBuf;
            DWORD dw = GetLastError();

            FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER |
                FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                dw,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR)&lpMsgBuf,
                0, NULL);

            // Display the error message and exit the process

            lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
                (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));

            StringCchPrintf((LPTSTR)lpDisplayBuf,
                LocalSize(lpDisplayBuf) / sizeof(TCHAR),
                TEXT("%s failed with error %d: %s"),
                lpszFunction, dw, lpMsgBuf);

            PrintMessageToStdErr((LPCSTR)lpDisplayBuf);

            LocalFree(lpMsgBuf);
            LocalFree(lpDisplayBuf);
        }

        /**
        * Provides windows implementation of stack trace collection.
        */
        class StackTraceImpl
        {
            StackTraceImpl(const StackTraceImpl &) = delete;
            StackTraceImpl &operator=(const StackTraceImpl &) = delete;
            struct BacktraceSymbol : public StackTrace::StackFrame
            {
                BacktraceSymbol() = default;

                BacktraceSymbol(const void *frameAddr, const char *name)
                {
                    address_ = frameAddr;
                    setSymbol(name);
                }

                void setAddress(const void *frameAddress)
                {
                    address_ = frameAddress;
                }

                void setSymbol(const char *name)
                {
                    if (name && name[0])
                    {
                        strcpy_s(symbolName_, MaxSymbolNameSize, name);
                        symbolName_[MaxSymbolNameSize - 1] = '\0';
                    }
                    else
                    {
                        symbolName_[0] = '\0';
                    }
                    symbol_ = symbolName_;
                }

                enum { MaxSymbolNameSize = MAX_SYM_NAME + 1 };
                char symbolName_[MaxSymbolNameSize];
            };
        public:
            StackTraceImpl()
            {
            }

            ~StackTraceImpl()
            {
            }

            void collect()
            {
                HANDLE              process;
                ULONG               frame;
                PSYMBOL_INFO        symbol;
                DWORD64             displacement;
                PVOID               frames[cFramesSize];
                enum {              MaxNameLen = MAX_SYM_NAME + 1 };
                enum {              BufferSize = sizeof(SYMBOL_INFO)
                                                + MaxNameLen * sizeof(TCHAR) };

                char buffer[BufferSize] = { '\0' };

                symbol = static_cast<PSYMBOL_INFO>(static_cast<void *>(buffer));

                std::memset(symbol, 0, BufferSize);
                std::memset(frames, 0, sizeof(frames));

                symbol->MaxNameLen = MaxNameLen-1;
                symbol->SizeOfStruct = sizeof(SYMBOL_INFO);

                process = GetCurrentProcess();
                displacement = 0;

                symInitialize(process);
                capturedFrames_ = CaptureStackBackTrace(cFramesToSkip
                                            , cFramesSize
                                            , frames
                                            , NULL);

                if (capturedFrames_ > cFramesSize)
                {
                    capturedFrames_ = cFramesSize;
                }

                for (frame = 0; frame<capturedFrames_; frame++)
                {
                    DWORD64 frameAddr = (DWORD64)(frames[frame]);
                    frames_[frame].setAddress(frames[frame]);
                    std::unique_lock<std::mutex> lock(mutex_);
                    if (SymFromAddr(process, frameAddr, &displacement, symbol)
                                    == TRUE)
                    {
                        frames_[frame].setSymbol(symbol->Name);
                    }
                    else
                    {
                        const std::uint64_t addressSize = sizeof(PVOID)*CHAR_BIT;
                        char msgBuffer[512];
                        sprintf_s(msgBuffer, sizeof(msgBuffer)
                                , "Error getting symbol from addr: 0x%016llX 0x%p address size %lu bits\n"
                                , frameAddr
                                , frames[frame]
                                , addressSize);
                        msgBuffer[sizeof(msgBuffer)-1] = '\0';
                        PrintMessageToStdErr(msgBuffer);
                        DisplayLastError("SymFromAddr");
                    }
                }
            }

            /**
             * Call to this function should
             */
            void symInitialize(HANDLE process)
            {
                std::unique_lock<std::mutex> lock(mutex_);
                static bool symbolsInitialized = false;
                if(symbolsInitialized==false)
                {
                    //should be only called once
                    if (SymInitialize(process, NULL, TRUE) != TRUE)
                    {
                        DisplayLastError("SymInitialize");
                        return;
                    }
                }
                symbolsInitialized = true;
            }

            /**
            * Returns number of captured frames
            * @return number of captured frames
            */
            std::size_t size() const
            {
                return capturedFrames_;
            }

            /**
             * Returns StackFrame at position \p pos. If pos
             * is outside range (0, size()) throws std::out_of_range exception.
             */
            const StackTrace::StackFrame &at(std::size_t pos) const
            {
                if (pos<capturedFrames_)
                {
                    return frames_[pos];
                }
                throw std::out_of_range("StackTrace::at(pos) out of range");
            }

        private:
            //all dbhelp library functions are not thread safe
            //thats why we need a mutext to protect calls to
            //them
            static std::mutex mutex_;
            enum
            {
                cFramesToSkip = 2
            };

            enum
            {
                cFramesSize = 1024
            };
            BacktraceSymbol frames_[cFramesSize];
            std::size_t capturedFrames_ = 0;
        };

        std::mutex StackTraceImpl::mutex_;

    } //internal
} //asrt

<|endoftext|>


<commit_before>#include "PacketController.h"
#include "WProgram.h"
#include <cstdint>
#undef min // Arduino libraries define max and min macros which mess with <vector>
#undef max
#include <vector>
#include "config.h"
#include "Packet.h"

// Constructor
PacketController::PacketController() {
    Serial.begin(BAUD_RATE);    // Setup the serial port
    Serial.setTimeout(0);       // Don't block the program if the serial buffer is empty
}

// Receiver. Reads from the serial buffer until there is nothing left or it has parsed a packet
// Returns true if a packet was found, else false
bool PacketController::receive() {
    int newByte;
    while (true) {
        newByte = Serial.read(); // Read a byte from the buffer
        switch (newByte) {
        case -1:
            // Serial buffer is empty, wait till next call to resume
            return false;
        case PACKET_START_BYTE:
            // Prepare to read a new packet into the receiveBuffer
            if (!_midReceive) {
                // We weren't in a packet, start a new one
                _receiveBufferHead = 0;
                _midReceive = true;
                _errorFlag = false;
                _receiveLength = PACKET_MAX_SIZE;
            }
            processByte(newByte);
            return false;
        default:
            if (!_errorFlag) {
                if (_midReceive) {
                    return processByte(newByte);
                } else {
                    // A packet wasn't started yet and this byte is in no man's land
                    transmitError(NO_MANS_LAND_CODE);
                    return false;
                }
            } else { return false; }
        }
    }
}

bool PacketController::processByte(uint8_t byte) {
    // Add the new byte to our buffer
    _receiveBuffer[_receiveBufferHead] = byte;
    if (_receiveBufferHead == 3) {
        // Time to read the length byte
        if (byte > PACKET_MAX_SIZE) {
            // Specified length is too long
            transmitError(PACKET_OOR_CODE);
        } else if (byte < PACKET_MIN_RESPONSE_SIZE) {
            transmitError(PACKET_SHORT_CODE);
        }
        else { _receiveLength = byte; }
    }
    if (_receiveBufferHead == _receiveLength - 1) {
        // We've reached the last byte
        decodePacket();
        _midReceive = false;
        return true;
    }
    _receiveBufferHead++;
    return false;
}

void PacketController::decodePacket() {
    _latestPacket->id = _receiveBuffer[1] + (_receiveBuffer[2] << 8);
    _latestPacket->dest = _receiveBuffer[4];
    _latestPacket->payload.assign(_receiveBuffer + 5, _receiveBuffer + _receiveBufferHead + 1);
}

// Returns the last processed packet
Packet* PacketController::getLatestPacket() {
    return _latestPacket;
}

// Transmitter. Given a response vector, transmit a response packet.
// The packet has the same ID as the last received packet.
void PacketController::transmit(std::vector<uint8_t> &responseData) {
    uint16_t id = _latestPacket->id;
    Serial.write(PACKET_START_BYTE);
    Serial.write(id);
    Serial.write(id>>8);
    Serial.write(4+responseData.size());
    for (uint8_t i = 0; i < responseData.size(); i++) {
        Serial.write(responseData[i]);
    }
    Serial.send_now();
}

// Private function to transmit errors in parsing packets
// Since a packet couldn't be read, the ID is fixed to PACKET_ERROR_ID
void PacketController::transmitError(uint8_t errorCode) {
    Serial.write(errorCode);
    _errorFlag = true;
    _midReceive = false;
}<commit_msg>Fix the 3057 bug, when the start byte appears in the payload<commit_after>#include "PacketController.h"
#include "WProgram.h"
#include <cstdint>
#undef min // Arduino libraries define max and min macros which mess with <vector>
#undef max
#include <vector>
#include "config.h"
#include "Packet.h"

// Constructor
PacketController::PacketController() {
    Serial.begin(BAUD_RATE);    // Setup the serial port
    Serial.setTimeout(0);       // Don't block the program if the serial buffer is empty
}

// Receiver. Reads from the serial buffer until there is nothing left or it has parsed a packet
// Returns true if a packet was found, else false
bool PacketController::receive() {
    int newByte;
    while (true) {
        newByte = Serial.read(); // Read a byte from the buffer
        switch (newByte) {
        case -1:
            // Serial buffer is empty, wait till next call to resume
            return false;
        case PACKET_START_BYTE:
            // Prepare to read a new packet into the receiveBuffer
            if (!_midReceive) {
                // We weren't in a packet, start a new one
                _receiveBufferHead = 0;
                _midReceive = true;
                _errorFlag = false;
                _receiveLength = PACKET_MAX_SIZE;
            }
            return processByte(newByte);
        default:
            if (!_errorFlag) {
                if (_midReceive) {
                    return processByte(newByte);
                } else {
                    // A packet wasn't started yet and this byte is in no man's land
                    transmitError(NO_MANS_LAND_CODE);
                    return false;
                }
            } else { return false; }
        }
    }
}

bool PacketController::processByte(uint8_t byte) {
    // Add the new byte to our buffer
    _receiveBuffer[_receiveBufferHead] = byte;
    if (_receiveBufferHead == 3) {
        // Time to read the length byte
        if (byte > PACKET_MAX_SIZE) {
            // Specified length is too long
            transmitError(PACKET_OOR_CODE);
        } else if (byte < PACKET_MIN_RESPONSE_SIZE) {
            transmitError(PACKET_SHORT_CODE);
        }
        else { _receiveLength = byte; }
    }
    if (_receiveBufferHead == _receiveLength - 1) {
        // We've reached the last byte
        decodePacket();
        _midReceive = false;
        return true;
    }
    _receiveBufferHead++;
    return false;
}

void PacketController::decodePacket() {
    _latestPacket->id = _receiveBuffer[1] + (_receiveBuffer[2] << 8);
    _latestPacket->dest = _receiveBuffer[4];
    _latestPacket->payload.assign(_receiveBuffer + 5, _receiveBuffer + _receiveBufferHead + 1);
}

// Returns the last processed packet
Packet* PacketController::getLatestPacket() {
    return _latestPacket;
}

// Transmitter. Given a response vector, transmit a response packet.
// The packet has the same ID as the last received packet.
void PacketController::transmit(std::vector<uint8_t> &responseData) {
    uint16_t id = _latestPacket->id;
    Serial.write(PACKET_START_BYTE);
    Serial.write(id);
    Serial.write(id>>8);
    Serial.write(4+responseData.size());
    for (uint8_t i = 0; i < responseData.size(); i++) {
        Serial.write(responseData[i]);
    }
    Serial.send_now();
}

// Private function to transmit errors in parsing packets
// Since a packet couldn't be read, the ID is fixed to PACKET_ERROR_ID
void PacketController::transmitError(uint8_t errorCode) {
    Serial.write(errorCode);
    _errorFlag = true;
    _midReceive = false;
}<|endoftext|>