<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/controls/menu/menu_item_view.h"

#include "app/resource_bundle.h"
#include "gfx/canvas_skia.h"
#include "gfx/favicon_size.h"
#include "grit/app_resources.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "views/controls/button/text_button.h"
#include "views/controls/menu/menu_config.h"
#include "views/controls/menu/submenu_view.h"

namespace views {

// Background color when the menu item is selected.
#if defined(OS_CHROMOS)
static const SkColor kSelectedBackgroundColor = SkColorSetRGB(0xDC, 0xE4, 0xFA);
#else
static const SkColor kSelectedBackgroundColor = SkColorSetRGB(246, 249, 253);
#endif

// Size of the radio button inciator.
static const int kSelectedIndicatorSize = 5;
static const int kIndicatorSize = 10;

// Used for the radio indicator. See theme_draw for details.
static const double kGradientStop = .5;
static const SkColor kGradient0 = SkColorSetRGB(255, 255, 255);
static const SkColor kGradient1 = SkColorSetRGB(255, 255, 255);
static const SkColor kGradient2 = SkColorSetRGB(0xD8, 0xD8, 0xD8);
static const SkColor kBaseStroke = SkColorSetRGB(0x8F, 0x8F, 0x8F);
static const SkColor kRadioButtonIndicatorGradient0 =
    SkColorSetRGB(0, 0, 0);
static const SkColor kRadioButtonIndicatorGradient1 =
    SkColorSetRGB(0x83, 0x83, 0x83);

static const SkColor kIndicatorStroke = SkColorSetRGB(0, 0, 0);

gfx::Size MenuItemView::GetPreferredSize() {
  const gfx::Font& font = MenuConfig::instance().font;
  // TODO(sky): this is a workaround until I figure out why font.height()
  // isn't returning the right thing. We really only want to include
  // kFavIconSize if we're showing icons.
  int content_height = std::max(kFavIconSize, font.height());
  return gfx::Size(
      font.GetStringWidth(title_) + label_start_ + item_right_margin_ +
          GetChildPreferredWidth(),
      content_height + GetBottomMargin() + GetTopMargin());
}

void MenuItemView::Paint(gfx::Canvas* canvas, bool for_drag) {
  const MenuConfig& config = MenuConfig::instance();
  bool render_selection =
      (!for_drag && IsSelected() &&
       parent_menu_item_->GetSubmenu()->GetShowSelection(this) &&
       GetChildViewCount() == 0);

  int icon_x = config.item_left_margin;
  int top_margin = GetTopMargin();
  int bottom_margin = GetBottomMargin();
  int icon_y = top_margin + (height() - config.item_top_margin -
                             bottom_margin - config.check_height) / 2;
  int icon_height = config.check_height;
  int available_height = height() - top_margin - bottom_margin;

  // Render the background. As MenuScrollViewContainer draws the background, we
  // only need the background when we want it to look different, as when we're
  // selected.
  if (render_selection)
    canvas->AsCanvasSkia()->drawColor(kSelectedBackgroundColor,
                                      SkXfermode::kSrc_Mode);

  // Render the check.
  if (type_ == CHECKBOX && GetDelegate()->IsItemChecked(GetCommand())) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    SkBitmap* check = rb.GetBitmapNamed(IDR_MENU_CHECK);
    // Don't use config.check_width here as it's padded to force more padding.
    gfx::Rect check_bounds(icon_x, icon_y, check->width(), icon_height);
    AdjustBoundsForRTLUI(&check_bounds);
    canvas->DrawBitmapInt(*check, check_bounds.x(), check_bounds.y());
  } else if (type_ == RADIO) {
    // This code comes from theme_draw.cc. See it for details.
    canvas->TranslateInt(
        icon_x,
        top_margin + (height() - top_margin - bottom_margin -
                      kIndicatorSize) / 2);

    SkPoint gradient_points[3];
    gradient_points[0].set(SkIntToScalar(0), SkIntToScalar(0));
    gradient_points[1].set(
        SkIntToScalar(0),
        SkIntToScalar(static_cast<int>(kIndicatorSize * kGradientStop)));
    gradient_points[2].set(SkIntToScalar(0), SkIntToScalar(kIndicatorSize));
    SkColor gradient_colors[3] = { kGradient0, kGradient1, kGradient2 };
    SkShader* shader = SkGradientShader::CreateLinear(
        gradient_points, gradient_colors, NULL, arraysize(gradient_points),
        SkShader::kClamp_TileMode, NULL);
    SkPaint paint;
    paint.setStyle(SkPaint::kFill_Style);
    paint.setAntiAlias(true);
    paint.setShader(shader);
    shader->unref();
    int radius = kIndicatorSize / 2;
    canvas->AsCanvasSkia()->drawCircle(radius, radius, radius, paint);

    paint.setStrokeWidth(SkIntToScalar(0));
    paint.setShader(NULL);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setColor(kBaseStroke);
    canvas->AsCanvasSkia()->drawCircle(radius, radius, radius, paint);

    if (GetDelegate()->IsItemChecked(GetCommand())) {
      SkPoint selected_gradient_points[2];
      selected_gradient_points[0].set(SkIntToScalar(0), SkIntToScalar(0));
      selected_gradient_points[1].set(
          SkIntToScalar(0),
          SkIntToScalar(kSelectedIndicatorSize));
      SkColor selected_gradient_colors[2] = { kRadioButtonIndicatorGradient0,
                                              kRadioButtonIndicatorGradient1 };
      shader = SkGradientShader::CreateLinear(
          selected_gradient_points, selected_gradient_colors, NULL,
          arraysize(selected_gradient_points), SkShader::kClamp_TileMode, NULL);
      paint.setShader(shader);
      shader->unref();
      paint.setStyle(SkPaint::kFill_Style);
      canvas->AsCanvasSkia()->drawCircle(radius, radius,
                                         kSelectedIndicatorSize / 2, paint);

      paint.setStrokeWidth(SkIntToScalar(0));
      paint.setShader(NULL);
      paint.setStyle(SkPaint::kStroke_Style);
      paint.setColor(kIndicatorStroke);
      canvas->AsCanvasSkia()->drawCircle(radius, radius,
                                         kSelectedIndicatorSize / 2, paint);
    }

    canvas->TranslateInt(
        -icon_x,
        -(top_margin + (height() - top_margin - bottom_margin -
                        kIndicatorSize) / 2));
  }

  // Render the foreground.
#if defined(OS_CHROMEOS)
  SkColor fg_color =
      IsEnabled() ? SK_ColorBLACK : SkColorSetRGB(0x80, 0x80, 0x80);
#else
  SkColor fg_color =
      IsEnabled() ? TextButton::kEnabledColor : TextButton::kDisabledColor;
#endif
  const gfx::Font& font = MenuConfig::instance().font;
  int accel_width = parent_menu_item_->GetSubmenu()->max_accelerator_width();
  int width = this->width() - item_right_margin_ - label_start_ - accel_width;
  gfx::Rect text_bounds(label_start_, top_margin +
                        (available_height - font.height()) / 2, width,
                        font.height());
  text_bounds.set_x(MirroredLeftPointForRect(text_bounds));
  canvas->DrawStringInt(GetTitle(), font, fg_color,
                        text_bounds.x(), text_bounds.y(), text_bounds.width(),
                        text_bounds.height(),
                        GetRootMenuItem()->GetDrawStringFlags());

  PaintAccelerator(canvas);

  // Render the icon.
  if (icon_.width() > 0) {
    gfx::Rect icon_bounds(config.item_left_margin,
                          top_margin + (height() - top_margin -
                          bottom_margin - icon_.height()) / 2,
                          icon_.width(),
                          icon_.height());
    icon_bounds.set_x(MirroredLeftPointForRect(icon_bounds));
    canvas->DrawBitmapInt(icon_, icon_bounds.x(), icon_bounds.y());
  }

  // Render the submenu indicator (arrow).
  if (HasSubmenu()) {
    gfx::Rect arrow_bounds(this->width() - item_right_margin_ +
                           config.label_to_arrow_padding,
                           top_margin + (available_height -
                                         config.arrow_width) / 2,
                           config.arrow_width, height());
    AdjustBoundsForRTLUI(&arrow_bounds);
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    canvas->DrawBitmapInt(*rb.GetBitmapNamed(IDR_MENU_ARROW),
                          arrow_bounds.x(), arrow_bounds.y());
  }
}

}  // namespace views
<commit_msg>Fix a typo that caused wrong menu highlight color being used for ChromeOS.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/controls/menu/menu_item_view.h"

#include "app/resource_bundle.h"
#include "gfx/canvas_skia.h"
#include "gfx/favicon_size.h"
#include "grit/app_resources.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "views/controls/button/text_button.h"
#include "views/controls/menu/menu_config.h"
#include "views/controls/menu/submenu_view.h"

namespace views {

// Background color when the menu item is selected.
#if defined(OS_CHROMEOS)
static const SkColor kSelectedBackgroundColor = SkColorSetRGB(0xDC, 0xE4, 0xFA);
#else
static const SkColor kSelectedBackgroundColor = SkColorSetRGB(246, 249, 253);
#endif

// Size of the radio button inciator.
static const int kSelectedIndicatorSize = 5;
static const int kIndicatorSize = 10;

// Used for the radio indicator. See theme_draw for details.
static const double kGradientStop = .5;
static const SkColor kGradient0 = SkColorSetRGB(255, 255, 255);
static const SkColor kGradient1 = SkColorSetRGB(255, 255, 255);
static const SkColor kGradient2 = SkColorSetRGB(0xD8, 0xD8, 0xD8);
static const SkColor kBaseStroke = SkColorSetRGB(0x8F, 0x8F, 0x8F);
static const SkColor kRadioButtonIndicatorGradient0 =
    SkColorSetRGB(0, 0, 0);
static const SkColor kRadioButtonIndicatorGradient1 =
    SkColorSetRGB(0x83, 0x83, 0x83);

static const SkColor kIndicatorStroke = SkColorSetRGB(0, 0, 0);

gfx::Size MenuItemView::GetPreferredSize() {
  const gfx::Font& font = MenuConfig::instance().font;
  // TODO(sky): this is a workaround until I figure out why font.height()
  // isn't returning the right thing. We really only want to include
  // kFavIconSize if we're showing icons.
  int content_height = std::max(kFavIconSize, font.height());
  return gfx::Size(
      font.GetStringWidth(title_) + label_start_ + item_right_margin_ +
          GetChildPreferredWidth(),
      content_height + GetBottomMargin() + GetTopMargin());
}

void MenuItemView::Paint(gfx::Canvas* canvas, bool for_drag) {
  const MenuConfig& config = MenuConfig::instance();
  bool render_selection =
      (!for_drag && IsSelected() &&
       parent_menu_item_->GetSubmenu()->GetShowSelection(this) &&
       GetChildViewCount() == 0);

  int icon_x = config.item_left_margin;
  int top_margin = GetTopMargin();
  int bottom_margin = GetBottomMargin();
  int icon_y = top_margin + (height() - config.item_top_margin -
                             bottom_margin - config.check_height) / 2;
  int icon_height = config.check_height;
  int available_height = height() - top_margin - bottom_margin;

  // Render the background. As MenuScrollViewContainer draws the background, we
  // only need the background when we want it to look different, as when we're
  // selected.
  if (render_selection)
    canvas->AsCanvasSkia()->drawColor(kSelectedBackgroundColor,
                                      SkXfermode::kSrc_Mode);

  // Render the check.
  if (type_ == CHECKBOX && GetDelegate()->IsItemChecked(GetCommand())) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    SkBitmap* check = rb.GetBitmapNamed(IDR_MENU_CHECK);
    // Don't use config.check_width here as it's padded to force more padding.
    gfx::Rect check_bounds(icon_x, icon_y, check->width(), icon_height);
    AdjustBoundsForRTLUI(&check_bounds);
    canvas->DrawBitmapInt(*check, check_bounds.x(), check_bounds.y());
  } else if (type_ == RADIO) {
    // This code comes from theme_draw.cc. See it for details.
    canvas->TranslateInt(
        icon_x,
        top_margin + (height() - top_margin - bottom_margin -
                      kIndicatorSize) / 2);

    SkPoint gradient_points[3];
    gradient_points[0].set(SkIntToScalar(0), SkIntToScalar(0));
    gradient_points[1].set(
        SkIntToScalar(0),
        SkIntToScalar(static_cast<int>(kIndicatorSize * kGradientStop)));
    gradient_points[2].set(SkIntToScalar(0), SkIntToScalar(kIndicatorSize));
    SkColor gradient_colors[3] = { kGradient0, kGradient1, kGradient2 };
    SkShader* shader = SkGradientShader::CreateLinear(
        gradient_points, gradient_colors, NULL, arraysize(gradient_points),
        SkShader::kClamp_TileMode, NULL);
    SkPaint paint;
    paint.setStyle(SkPaint::kFill_Style);
    paint.setAntiAlias(true);
    paint.setShader(shader);
    shader->unref();
    int radius = kIndicatorSize / 2;
    canvas->AsCanvasSkia()->drawCircle(radius, radius, radius, paint);

    paint.setStrokeWidth(SkIntToScalar(0));
    paint.setShader(NULL);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setColor(kBaseStroke);
    canvas->AsCanvasSkia()->drawCircle(radius, radius, radius, paint);

    if (GetDelegate()->IsItemChecked(GetCommand())) {
      SkPoint selected_gradient_points[2];
      selected_gradient_points[0].set(SkIntToScalar(0), SkIntToScalar(0));
      selected_gradient_points[1].set(
          SkIntToScalar(0),
          SkIntToScalar(kSelectedIndicatorSize));
      SkColor selected_gradient_colors[2] = { kRadioButtonIndicatorGradient0,
                                              kRadioButtonIndicatorGradient1 };
      shader = SkGradientShader::CreateLinear(
          selected_gradient_points, selected_gradient_colors, NULL,
          arraysize(selected_gradient_points), SkShader::kClamp_TileMode, NULL);
      paint.setShader(shader);
      shader->unref();
      paint.setStyle(SkPaint::kFill_Style);
      canvas->AsCanvasSkia()->drawCircle(radius, radius,
                                         kSelectedIndicatorSize / 2, paint);

      paint.setStrokeWidth(SkIntToScalar(0));
      paint.setShader(NULL);
      paint.setStyle(SkPaint::kStroke_Style);
      paint.setColor(kIndicatorStroke);
      canvas->AsCanvasSkia()->drawCircle(radius, radius,
                                         kSelectedIndicatorSize / 2, paint);
    }

    canvas->TranslateInt(
        -icon_x,
        -(top_margin + (height() - top_margin - bottom_margin -
                        kIndicatorSize) / 2));
  }

  // Render the foreground.
#if defined(OS_CHROMEOS)
  SkColor fg_color =
      IsEnabled() ? SK_ColorBLACK : SkColorSetRGB(0x80, 0x80, 0x80);
#else
  SkColor fg_color =
      IsEnabled() ? TextButton::kEnabledColor : TextButton::kDisabledColor;
#endif
  const gfx::Font& font = MenuConfig::instance().font;
  int accel_width = parent_menu_item_->GetSubmenu()->max_accelerator_width();
  int width = this->width() - item_right_margin_ - label_start_ - accel_width;
  gfx::Rect text_bounds(label_start_, top_margin +
                        (available_height - font.height()) / 2, width,
                        font.height());
  text_bounds.set_x(MirroredLeftPointForRect(text_bounds));
  canvas->DrawStringInt(GetTitle(), font, fg_color,
                        text_bounds.x(), text_bounds.y(), text_bounds.width(),
                        text_bounds.height(),
                        GetRootMenuItem()->GetDrawStringFlags());

  PaintAccelerator(canvas);

  // Render the icon.
  if (icon_.width() > 0) {
    gfx::Rect icon_bounds(config.item_left_margin,
                          top_margin + (height() - top_margin -
                          bottom_margin - icon_.height()) / 2,
                          icon_.width(),
                          icon_.height());
    icon_bounds.set_x(MirroredLeftPointForRect(icon_bounds));
    canvas->DrawBitmapInt(icon_, icon_bounds.x(), icon_bounds.y());
  }

  // Render the submenu indicator (arrow).
  if (HasSubmenu()) {
    gfx::Rect arrow_bounds(this->width() - item_right_margin_ +
                           config.label_to_arrow_padding,
                           top_margin + (available_height -
                                         config.arrow_width) / 2,
                           config.arrow_width, height());
    AdjustBoundsForRTLUI(&arrow_bounds);
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    canvas->DrawBitmapInt(*rb.GetBitmapNamed(IDR_MENU_ARROW),
                          arrow_bounds.x(), arrow_bounds.y());
  }
}

}  // namespace views
<|endoftext|>


<commit_before>/*
 * config.cpp - implementation of Config class
 * Copyright 2017 MIPT-MIPS
 */

/* Simulator modules */
#include "config.h"

/* Generic C++ */
#include <iostream>

/* boost - program option parsing */
#include <boost/program_options.hpp>

/* constructor and destructor */
Config::Config()
{

}

Config::~Config()
{

}

/* basic method */
int Config::handleArgs( int argc, char** argv)
{
    namespace po = boost::program_options;

    po::options_description description( "Allowed options");

    description.add_options()
        ( "binary,b",      po::value<std::string>( this->binary_filename.get_ptr())->required(),
          "input binary file")

        ( "numsteps,n",    po::value<int>( this->num_steps.get_ptr())->required(),
          "number of instructions to run")

        /* by default, the silent mode is on */
        ( "disassembly,d", po::bool_switch( this->disassembly_on.get_ptr())->default_value( false),
          "print disassembly")

        ( "help,h",
          "print this help message");

    po::positional_options_description posDescription;
    posDescription.add( "binary", 1).add( "numsteps", 2);
    po::variables_map vm;

    try
    {
        po::store(po::command_line_parser(argc, argv).
                                    options(description).
                                    positional(posDescription).
                                    run(),
                                    vm);

        /* parsing help */
        if ( vm.count( "help"))
        {
            std::cout << "Functional and performance simulators for MIPS-based CPU.";
            std::cout << std::endl << std::endl;
            std::cout << description << std::endl;
            std::exit( EXIT_SUCCESS);
        }

        /* calling notify AFTER parsing help, as otherwise
         * absent required args will cause errors
         */
        po::notify(vm);
    }
    catch ( const std::exception& e)
    {
        std::cout << argv[0] << ": " << e.what();
        std::cout << std::endl << std::endl;
        std::cout << description << std::endl;
        std::exit( EXIT_SUCCESS);
    }

    return 0;
}
<commit_msg>Use std::cerr for error output<commit_after>/*
 * config.cpp - implementation of Config class
 * Copyright 2017 MIPT-MIPS
 */

/* Simulator modules */
#include "config.h"

/* Generic C++ */
#include <iostream>

/* boost - program option parsing */
#include <boost/program_options.hpp>

/* constructor and destructor */
Config::Config()
{

}

Config::~Config()
{

}

/* basic method */
int Config::handleArgs( int argc, char** argv)
{
    namespace po = boost::program_options;

    po::options_description description( "Allowed options");

    description.add_options()
        ( "binary,b",      po::value<std::string>( this->binary_filename.get_ptr())->required(),
          "input binary file")

        ( "numsteps,n",    po::value<int>( this->num_steps.get_ptr())->required(),
          "number of instructions to run")

        /* by default, the silent mode is on */
        ( "disassembly,d", po::bool_switch( this->disassembly_on.get_ptr())->default_value( false),
          "print disassembly")

        ( "help,h",
          "print this help message");

    po::positional_options_description posDescription;
    posDescription.add( "binary", 1).add( "numsteps", 2);
    po::variables_map vm;

    try
    {
        po::store(po::command_line_parser(argc, argv).
                                    options(description).
                                    positional(posDescription).
                                    run(),
                                    vm);

        /* parsing help */
        if ( vm.count( "help"))
        {
            std::cout << "Functional and performance simulators for MIPS-based CPU.";
            std::cout << std::endl << std::endl;
            std::cout << description << std::endl;
            std::exit( EXIT_SUCCESS);
        }

        /* calling notify AFTER parsing help, as otherwise
         * absent required args will cause errors
         */
        po::notify(vm);
    }
    catch ( const std::exception& e)
    {
        std::cerr << argv[0] << ": " << e.what();
        std::cerr << std::endl << std::endl;
        std::cerr << description << std::endl;
        std::exit( EXIT_SUCCESS);
    }

    return 0;
}
<|endoftext|>


<commit_before>#ifndef MJOLNIR_CORE_TOPOLOGY_HPP
#define MJOLNIR_CORE_TOPOLOGY_HPP
#include <mjolnir/util/throw_exception.hpp>
#include <utility>
#include <algorithm>
#include <stdexcept>
#include <string>
#include <vector>

namespace mjolnir
{

// XXX Topology class manages the connections between beads.
//
// NOTE: connection kind "bond" is used to determine the molecules.
//       Other kind of connections also can be defined (and overlayed
//       if nessesary). In that case, you can traverse the graph by using
//       your connection kind also, but it will not be considered when
//       it detemines "molecule"s.
//
// Most of the time, "molecule" defined by this class is equivalent to "chain".
// But calling "molecule" as "chain" is misreading because there can be a
// circular molecule or tiny molecule that only has a few number of beads.
// For example, lipid membrane is composed of a large number of lipid molecules
// and people useally does not call each lipid as "chain".
//
// Generally, traversing graph takes time rather than finding value from
// contiguous container. So there are ExclusionList class that stores the
// information for NeighborLists (usually, nonlocal potentials are ignored if
// the two particles are connected by covarent bond). While the simulation,
// ExclusionLists would be called many time, but Topology would only be called
// to construct ExclusionList at the beginning ofjthe simulation.
//
// Since the members of this class are rarely called, in most cases, the speed
// of these methods does not affect to the overall efficiency.class Topology
class Topology
{
  public:

    using molecule_id_type     = std::size_t;
    using group_id_type        = std::string;
    using connection_kind_type = std::string;
    using edge_type = std::pair<std::size_t, connection_kind_type>;

    static constexpr molecule_id_type uninitialized() noexcept
    {
        return std::numeric_limits<molecule_id_type>::max();
    }

    struct node
    {
        std::size_t   molecule_id;
        std::string   name;
        group_id_type group;
        std::vector<edge_type> adjacents;
    };

  public:

    Topology()  = default;
    ~Topology() = default;
    Topology(const Topology&) = default;
    Topology(Topology&&)      = default;
    Topology& operator=(const Topology&) = default;
    Topology& operator=(Topology&&)      = default;

    explicit Topology(const std::size_t N)
        : num_molecules_(1), nodes_(N, node{
                uninitialized(), "uninitialized", "uninitialized", {}})
    {}

    void        clear()                {return nodes_.clear();}
    bool        empty() const noexcept {return nodes_.empty();}
    std::size_t size()  const noexcept {return nodes_.size();}

    std::string&       name_of(const std::size_t i)
    {return this->nodes_.at(i).name;}
    std::string const& name_of(const std::size_t i) const
    {return this->nodes_.at(i).name;}
    std::string&       name_of(const std::size_t i, const std::nothrow_t&) noexcept
    {return this->nodes_[i].name;}
    std::string const& name_of(const std::size_t i, const std::nothrow_t&) const noexcept
    {return this->nodes_[i].name;}

    molecule_id_type  molecule_of(const std::size_t i) const
    {return nodes_.at(i).molecule_id;}
    molecule_id_type& molecule_of(const std::size_t i)
    {return nodes_.at(i).molecule_id;}

    molecule_id_type  molecule_of(const std::size_t i, const std::nothrow_t&) const
    {return nodes_[i].molecule_id;}
    molecule_id_type& molecule_of(const std::size_t i, const std::nothrow_t&)
    {return nodes_[i].molecule_id;}

    std::string&       group_of(const std::size_t i)
    {return this->nodes_.at(i).group;}
    std::string const& group_of(const std::size_t i) const
    {return this->nodes_.at(i).group;}

    std::string&       group_of(const std::size_t i, const std::nothrow_t&) noexcept
    {return this->nodes_[i].group;}
    std::string const& group_of(const std::size_t i, const std::nothrow_t&) const noexcept
    {return this->nodes_[i].group;}

    void add_connection  (const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    void erase_connection(const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    bool has_connection  (const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    // has_connection returns true if i == j.

    std::vector<std::size_t>
    list_adjacent_within(const std::size_t node_idx, const std::size_t dist,
                         const connection_kind_type& kind) const;

    std::vector<connection_kind_type>
    list_connections_between(const std::size_t i, const std::size_t j) const;

    //! reset molecule_id of all the particles
    void construct_molecules();
    void resize(const std::size_t N) {nodes_.resize(N); return;}

    std::size_t number_of_molecules() const noexcept {return this->num_molecules_;}

  private:

    void list_adjacent_within(
        const std::size_t node_idx, const std::size_t dist,
        const connection_kind_type& kind, std::vector<std::size_t>& out) const
    {
        if(dist == 0)
        {
            if(std::find(out.cbegin(), out.cend(), node_idx) != out.cend())
            {
                out.push_back(node_idx);
            }
            return;
        }

        for(auto edge : this->nodes_.at(node_idx).adjacents)
        {
            if(edge.second != kind ||
               std::find(out.cbegin(), out.cend(), edge.first) != out.cend())
            {
                continue;
            }
            out.push_back(edge.first);
            this->list_adjacent_within(edge.first, dist-1, kind, out);
        }
        return;
    }

  private:
    std::size_t num_molecules_;
    std::vector<node>   nodes_;
    // each node corresponds to the particle having the same idx in a system.
};

inline void Topology::add_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::add_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }

    {
        const edge_type edge = std::make_pair(j, kind);

        auto& adjs = nodes_[i].adjacents;
        if(std::find(adjs.cbegin(), adjs.cend(), edge) == adjs.cend())
        {
            adjs.push_back(edge);
        }
    }
    {
        const edge_type edge = std::make_pair(i, kind);

        auto& adjs = nodes_[j].adjacents;
        if(std::find(adjs.cbegin(), adjs.cend(), edge) == adjs.cend())
        {
            adjs.push_back(edge);
        }
    }
    return ;
}

inline void Topology::erase_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::erase_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }

    {
        auto& adjs = nodes_[i].adjacents;
        const auto found = std::find(
                adjs.begin(), adjs.end(), std::make_pair(j, kind));
        if(found != adjs.end())
        {
            adjs.erase(found);
        }
    }
    {
        auto& adjs = nodes_[j].adjacents;
        const auto found = std::find(
                adjs.begin(), adjs.end(), std::make_pair(i, kind));
        if(found != adjs.end())
        {
            adjs.erase(found);
        }
    }
    return ;
}

inline bool Topology::has_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::has_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }
    if(i == j) {return true;} // XXX

    const auto& adjs = nodes_[i].adjacents;
    const auto found =
        std::find(adjs.cbegin(), adjs.cend(), std::make_pair(j, kind));
    return found != adjs.cend();
}

inline std::vector<std::size_t>
Topology::list_adjacent_within(
        const std::size_t node_idx, const std::size_t dist,
        const connection_kind_type& kind) const
{
    std::vector<std::size_t> retval = {node_idx};
    if(dist == 0) {return retval;}

    for(auto edge : this->nodes_.at(node_idx).adjacents)
    {
        if(edge.second != kind || std::find(
           retval.cbegin(), retval.cend(), edge.first) != retval.cend())
        {
            continue;
        }
        retval.push_back(edge.first);
        this->list_adjacent_within(edge.first, dist - 1, kind, retval);
    }
    std::sort(retval.begin(), retval.end());
    const auto new_end = std::unique(retval.begin(), retval.end());
    retval.erase(new_end, retval.end());
    return retval;
}

inline std::vector<typename Topology::connection_kind_type>
Topology::list_connections_between(const std::size_t i, const std::size_t j) const
{
    std::vector<connection_kind_type> connections;
    for(const auto& edge : this->nodes_.at(i).adjacents)
    {
        if(edge.first == j)
        {
            connections.push_back(edge.second);
        }
    }
    return connections;
}

inline void
Topology::construct_molecules()
{
    if(this->nodes_.empty()){return;}
    // reset molecule-ids
    for(auto& node : nodes_)
    {
        node.molecule_id = uninitialized();
    }

    molecule_id_type next_molecule_id = 0;
    for(auto& node : nodes_)
    {
        // look all the adjacents and update node by their molecule id
        for(const auto& edge : node.adjacents)
        {
            // ignore all the edges that are not bonds
            if(edge.second != "bond") {continue;}

            // if an adjacent that is connected by a "bond",
            // it should be in the same molecule.
            const auto& adj = this->nodes_.at(edge.first);
            if(adj.molecule_id != uninitialized())
            {
                node.molecule_id = adj.molecule_id;
                break;
            }
        }
        // if the molecule_id of this node is still not initialized, that means
        // this node belongs to a new molecule.
        if(node.molecule_id == uninitialized())
        {
            node.molecule_id = next_molecule_id++;
        }
    }
    this->num_molecules_ = next_molecule_id;
    return;
}

} // mjolnir
#endif// MJOLNIR_STRUCTURE_TOPOLOGY_H
<commit_msg>fix: correct adjacents even if a loop exists<commit_after>#ifndef MJOLNIR_CORE_TOPOLOGY_HPP
#define MJOLNIR_CORE_TOPOLOGY_HPP
#include <mjolnir/util/throw_exception.hpp>
#include <utility>
#include <algorithm>
#include <stdexcept>
#include <string>
#include <vector>

namespace mjolnir
{

// XXX Topology class manages the connections between beads.
//
// NOTE: connection kind "bond" is used to determine the molecules.
//       Other kind of connections also can be defined (and overlayed
//       if nessesary). In that case, you can traverse the graph by using
//       your connection kind also, but it will not be considered when
//       it detemines "molecule"s.
//
// Most of the time, "molecule" defined by this class is equivalent to "chain".
// But calling "molecule" as "chain" is misreading because there can be a
// circular molecule or tiny molecule that only has a few number of beads.
// For example, lipid membrane is composed of a large number of lipid molecules
// and people useally does not call each lipid as "chain".
//
// Generally, traversing graph takes time rather than finding value from
// contiguous container. So there are ExclusionList class that stores the
// information for NeighborLists (usually, nonlocal potentials are ignored if
// the two particles are connected by covarent bond). While the simulation,
// ExclusionLists would be called many time, but Topology would only be called
// to construct ExclusionList at the beginning ofjthe simulation.
//
// Since the members of this class are rarely called, in most cases, the speed
// of these methods does not affect to the overall efficiency.class Topology
class Topology
{
  public:

    using molecule_id_type     = std::size_t;
    using group_id_type        = std::string;
    using connection_kind_type = std::string;
    using edge_type = std::pair<std::size_t, connection_kind_type>;

    static constexpr molecule_id_type uninitialized() noexcept
    {
        return std::numeric_limits<molecule_id_type>::max();
    }

    struct node
    {
        std::size_t   molecule_id;
        std::string   name;
        group_id_type group;
        std::vector<edge_type> adjacents;
    };

  public:

    Topology()  = default;
    ~Topology() = default;
    Topology(const Topology&) = default;
    Topology(Topology&&)      = default;
    Topology& operator=(const Topology&) = default;
    Topology& operator=(Topology&&)      = default;

    explicit Topology(const std::size_t N)
        : num_molecules_(1), nodes_(N, node{
                uninitialized(), "uninitialized", "uninitialized", {}})
    {}

    void        clear()                {return nodes_.clear();}
    bool        empty() const noexcept {return nodes_.empty();}
    std::size_t size()  const noexcept {return nodes_.size();}

    std::string&       name_of(const std::size_t i)
    {return this->nodes_.at(i).name;}
    std::string const& name_of(const std::size_t i) const
    {return this->nodes_.at(i).name;}
    std::string&       name_of(const std::size_t i, const std::nothrow_t&) noexcept
    {return this->nodes_[i].name;}
    std::string const& name_of(const std::size_t i, const std::nothrow_t&) const noexcept
    {return this->nodes_[i].name;}

    molecule_id_type  molecule_of(const std::size_t i) const
    {return nodes_.at(i).molecule_id;}
    molecule_id_type& molecule_of(const std::size_t i)
    {return nodes_.at(i).molecule_id;}

    molecule_id_type  molecule_of(const std::size_t i, const std::nothrow_t&) const
    {return nodes_[i].molecule_id;}
    molecule_id_type& molecule_of(const std::size_t i, const std::nothrow_t&)
    {return nodes_[i].molecule_id;}

    std::string&       group_of(const std::size_t i)
    {return this->nodes_.at(i).group;}
    std::string const& group_of(const std::size_t i) const
    {return this->nodes_.at(i).group;}

    std::string&       group_of(const std::size_t i, const std::nothrow_t&) noexcept
    {return this->nodes_[i].group;}
    std::string const& group_of(const std::size_t i, const std::nothrow_t&) const noexcept
    {return this->nodes_[i].group;}

    void add_connection  (const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    void erase_connection(const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    bool has_connection  (const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    // has_connection returns true if i == j.

    std::vector<std::size_t>
    list_adjacent_within(const std::size_t node_idx, const std::size_t dist,
                         const connection_kind_type& kind) const;

    std::vector<connection_kind_type>
    list_connections_between(const std::size_t i, const std::size_t j) const;

    //! reset molecule_id of all the particles
    void construct_molecules();
    void resize(const std::size_t N) {nodes_.resize(N); return;}

    std::size_t number_of_molecules() const noexcept {return this->num_molecules_;}

  private:

    void list_adjacent_within(
        const std::size_t node_idx, const std::size_t dist,
        const connection_kind_type& kind, std::vector<std::size_t>& out) const
    {
        if(dist == 0)
        {
            out.push_back(node_idx);
            return;
        }

        for(auto edge : this->nodes_.at(node_idx).adjacents)
        {
            if(edge.second != kind)
            {
                continue;
            }
            out.push_back(edge.first);
            this->list_adjacent_within(edge.first, dist-1, kind, out);
        }
        return;
    }

  private:
    std::size_t num_molecules_;
    std::vector<node>   nodes_;
    // each node corresponds to the particle having the same idx in a system.
};

inline void Topology::add_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::add_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }

    {
        const edge_type edge = std::make_pair(j, kind);

        auto& adjs = nodes_[i].adjacents;
        if(std::find(adjs.cbegin(), adjs.cend(), edge) == adjs.cend())
        {
            adjs.push_back(edge);
        }
    }
    {
        const edge_type edge = std::make_pair(i, kind);

        auto& adjs = nodes_[j].adjacents;
        if(std::find(adjs.cbegin(), adjs.cend(), edge) == adjs.cend())
        {
            adjs.push_back(edge);
        }
    }
    return ;
}

inline void Topology::erase_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::erase_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }

    {
        auto& adjs = nodes_[i].adjacents;
        const auto found = std::find(
                adjs.begin(), adjs.end(), std::make_pair(j, kind));
        if(found != adjs.end())
        {
            adjs.erase(found);
        }
    }
    {
        auto& adjs = nodes_[j].adjacents;
        const auto found = std::find(
                adjs.begin(), adjs.end(), std::make_pair(i, kind));
        if(found != adjs.end())
        {
            adjs.erase(found);
        }
    }
    return ;
}

inline bool Topology::has_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::has_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }
    if(i == j) {return true;} // XXX

    const auto& adjs = nodes_[i].adjacents;
    const auto found =
        std::find(adjs.cbegin(), adjs.cend(), std::make_pair(j, kind));
    return found != adjs.cend();
}

inline std::vector<std::size_t>
Topology::list_adjacent_within(
        const std::size_t node_idx, const std::size_t dist,
        const connection_kind_type& kind) const
{
    std::vector<std::size_t> retval = {node_idx};
    if(dist == 0) {return retval;}

    for(auto edge : this->nodes_.at(node_idx).adjacents)
    {
        if(edge.second != kind)
        {
            continue;
        }
        retval.push_back(edge.first);
        this->list_adjacent_within(edge.first, dist - 1, kind, retval);
    }
    std::sort(retval.begin(), retval.end());
    const auto new_end = std::unique(retval.begin(), retval.end());
    retval.erase(new_end, retval.end());
    return retval;
}

inline std::vector<typename Topology::connection_kind_type>
Topology::list_connections_between(const std::size_t i, const std::size_t j) const
{
    std::vector<connection_kind_type> connections;
    for(const auto& edge : this->nodes_.at(i).adjacents)
    {
        if(edge.first == j)
        {
            connections.push_back(edge.second);
        }
    }
    return connections;
}

inline void
Topology::construct_molecules()
{
    if(this->nodes_.empty()){return;}
    // reset molecule-ids
    for(auto& node : nodes_)
    {
        node.molecule_id = uninitialized();
    }

    molecule_id_type next_molecule_id = 0;
    for(auto& node : nodes_)
    {
        // look all the adjacents and update node by their molecule id
        for(const auto& edge : node.adjacents)
        {
            // ignore all the edges that are not bonds
            if(edge.second != "bond") {continue;}

            // if an adjacent that is connected by a "bond",
            // it should be in the same molecule.
            const auto& adj = this->nodes_.at(edge.first);
            if(adj.molecule_id != uninitialized())
            {
                node.molecule_id = adj.molecule_id;
                break;
            }
        }
        // if the molecule_id of this node is still not initialized, that means
        // this node belongs to a new molecule.
        if(node.molecule_id == uninitialized())
        {
            node.molecule_id = next_molecule_id++;
        }
    }
    this->num_molecules_ = next_molecule_id;
    return;
}

} // mjolnir
#endif// MJOLNIR_STRUCTURE_TOPOLOGY_H
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkIconGlyphFilter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkIconGlyphFilter.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkFloatArray.h"
#include "vtkIdList.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPointLocator.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"

vtkStandardNewMacro(vtkIconGlyphFilter);

//-----------------------------------------------------------------------------
vtkIconGlyphFilter::vtkIconGlyphFilter()
{
  this->IconSize[0] = 1;
  this->IconSize[1] = 1;
  this->IconSheetSize[0] = 1;
  this->IconSheetSize[1] = 1;
  this->DisplaySize[0] = 25;
  this->DisplaySize[1] = 25;
  this->Gravity = VTK_ICON_GRAVITY_CENTER_CENTER;
  this->UseIconSize = true;
  this->PassScalars = false;
  this->IconScaling = VTK_ICON_SCALING_OFF;
  this->Offset[0] = this->Offset[0] = 0;

  this->SetInputArrayToProcess(0, 0, 0,
    vtkDataObject::FIELD_ASSOCIATION_POINTS, vtkDataSetAttributes::SCALARS);
}

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

//-----------------------------------------------------------------------------
void vtkIconGlyphFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Icon Size: " << this->IconSize[0] << " " << this->IconSize[1] << endl;
  os << indent << "Icon Sheet Size: " << this->IconSheetSize[0] << " " << this->IconSheetSize[1] << endl;
  os << indent << "Display Size: " << this->DisplaySize[0] << " " << this->DisplaySize[1] << endl;
  os << indent << "Gravity: " << this->Gravity << "\n";
  os << indent << "Use Icon Size: "
     << (this->UseIconSize ? " On" : " Off") << endl;
  os << indent << "Pass Scalars: "
     << (this->PassScalars ? " On" : " Off") << endl;
  os << indent << "Icon Scaling: " << this->IconScaling << endl;
}

//-----------------------------------------------------------------------------
int vtkIconGlyphFilter::RequestData(vtkInformation *vtkNotUsed(request),
                                  vtkInformationVector **inputVector,
                                  vtkInformationVector *outputVector)
{
  // Get the information object.
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // Get the data objects.
  vtkPointSet *input = vtkPointSet::SafeDownCast(
                                     inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPolyData *output = vtkPolyData::SafeDownCast(
                                    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  int numPoints = input->GetNumberOfPoints();

  if (numPoints <= 0)
    {
    // nothing to do...
    return 1;
    }

  vtkIntArray* scalars = vtkIntArray::SafeDownCast(
    this->GetInputArrayToProcess(0, inputVector));
  if (!scalars)
    {
    vtkErrorMacro("Input Scalars must be specified to index into the icon sheet.");
    return 0;
    }

  // Optional scaling may be going on
  vtkDataArray *scalingArray = NULL;
  if ( this->IconScaling == VTK_ICON_SCALING_USE_SCALING_ARRAY )
    {
    scalingArray = input->GetPointData()->GetArray("IconScale");
    }

  double point[3], textureCoord[2];
  point[2] = 0;
  double sheetXDim = this->IconSheetSize[0]/this->IconSize[0];
  double sheetYDim = this->IconSheetSize[1]/this->IconSize[1];
  int iconIndex = 0;
  int j, k;

  vtkPoints * outPoints = vtkPoints::New();
  outPoints->Allocate(4 * numPoints);

  vtkCellArray * outCells = vtkCellArray::New();
  outCells->Allocate(outCells->EstimateSize(numPoints, 4));

  vtkFloatArray *outTCoords = vtkFloatArray::New();
  outTCoords->SetNumberOfComponents(2);
  outTCoords->Allocate(8*numPoints);

  // Copy point data to cell data
  vtkPointData *inPD = input->GetPointData();
  vtkCellData  *outCD = output->GetCellData();

  double size[2];
  size[0] = this->DisplaySize[0];
  size[1] = this->DisplaySize[1];
  if(this->UseIconSize)
    {
    size[0] = this->IconSize[0];
    size[1] = this->IconSize[1];
    }

  vtkIdType ptId;
  double sf = 1.0;
  for(ptId = 0; ptId < numPoints; ++ptId)
    {
    iconIndex = scalars->GetValue(ptId);

    if(iconIndex >= 0)
      {
      this->IconConvertIndex(iconIndex, j, k);

      textureCoord[0] = j/sheetXDim;
      textureCoord[1] = k/sheetYDim;
      outTCoords->InsertTuple(ptId * 4, textureCoord);

      textureCoord[0] = (j + 1.0)/sheetXDim;
      textureCoord[1] = k/sheetYDim;
      outTCoords->InsertTuple(ptId * 4 + 1, textureCoord);

      textureCoord[0] = (j + 1.0)/sheetXDim;
      textureCoord[1] = (k + 1.0)/sheetYDim;
      outTCoords->InsertTuple(ptId * 4 + 2, textureCoord);

      textureCoord[0] = j/sheetXDim;
      textureCoord[1] = (k + 1.0)/sheetYDim;
      outTCoords->InsertTuple(ptId * 4 + 3, textureCoord);
      }

    input->GetPoint(ptId, point);
    point[0] += this->Offset[0];
    point[1] += this->Offset[1];

    if ( scalingArray )
      {
      sf = scalingArray->GetTuple1(ptId);
      }

    switch(this->Gravity)
      {
      case VTK_ICON_GRAVITY_CENTER_CENTER:
        break;
      case VTK_ICON_GRAVITY_TOP_RIGHT:
        point[0] = point[0] + 0.5 * sf * size[0];
        point[1] = point[1] + 0.5 * sf * size[1];
        break;
      case VTK_ICON_GRAVITY_TOP_CENTER:
        point[1] = point[1] + 0.5 * sf * size[1];
        break;
      case VTK_ICON_GRAVITY_TOP_LEFT:
        point[0] = point[0] - 0.5 * sf * size[0];
        point[1] = point[1] + 0.5 * sf * size[1];
        break;
      case VTK_ICON_GRAVITY_CENTER_RIGHT:
        point[0] = point[0] + 0.5 * sf * size[0];
        break;
      case VTK_ICON_GRAVITY_CENTER_LEFT:
        point[0] = point[0] - 0.5 * sf * size[0];
        break;
      case VTK_ICON_GRAVITY_BOTTOM_RIGHT:
        point[0] = point[0] + 0.5 * sf * size[0];
        point[1] = point[1] - 0.5 * sf * size[1];
        break;
      case VTK_ICON_GRAVITY_BOTTOM_CENTER:
        point[1] = point[1] - 0.5 * sf * size[1];
        break;
      case VTK_ICON_GRAVITY_BOTTOM_LEFT:
        point[0] = point[0] - 0.5 * sf * size[0];
        point[1] = point[1] - 0.5 * sf * size[1];
        break;
      }

    outPoints->InsertNextPoint(point[0] - 0.5 * sf * size[0], point[1] - 0.5 * sf * size[1], point[2]);
    outPoints->InsertNextPoint(point[0] + 0.5 * sf * size[0], point[1] - 0.5 * sf * size[1], point[2]);
    outPoints->InsertNextPoint(point[0] + 0.5 * sf * size[0], point[1] + 0.5 * sf * size[1], point[2]);
    outPoints->InsertNextPoint(point[0] - 0.5 * sf * size[0], point[1] + 0.5 * sf * size[1], point[2]);

    outCells->InsertNextCell(4);
    outCells->InsertCellPoint(ptId * 4);
    outCells->InsertCellPoint(ptId * 4 + 1);
    outCells->InsertCellPoint(ptId * 4 + 2);
    outCells->InsertCellPoint(ptId * 4 + 3);
    }

  output->SetPoints(outPoints);
  outPoints->Delete();

  outTCoords->SetName("TextureCoordinates");
  output->GetPointData()->SetTCoords(outTCoords);
  outTCoords->Delete();

  output->SetPolys(outCells);
  outCells->Delete();

  // Pass the input point data to the cell data because for every point we
  // generate a quad cell.
  if ( this->PassScalars )
    {
    outCD->CopyScalarsOn();
    }
  else
    {
    outCD->CopyScalarsOff();
    }
  outCD->PassData(inPD);

  return 1;
}

<commit_msg>BUG:Bad initialization of offset<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkIconGlyphFilter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkIconGlyphFilter.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkFloatArray.h"
#include "vtkIdList.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPointLocator.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"

vtkStandardNewMacro(vtkIconGlyphFilter);

//-----------------------------------------------------------------------------
vtkIconGlyphFilter::vtkIconGlyphFilter()
{
  this->IconSize[0] = 1;
  this->IconSize[1] = 1;
  this->IconSheetSize[0] = 1;
  this->IconSheetSize[1] = 1;
  this->DisplaySize[0] = 25;
  this->DisplaySize[1] = 25;
  this->Gravity = VTK_ICON_GRAVITY_CENTER_CENTER;
  this->UseIconSize = true;
  this->PassScalars = false;
  this->IconScaling = VTK_ICON_SCALING_OFF;
  this->Offset[0] = this->Offset[1] = 0;

  this->SetInputArrayToProcess(0, 0, 0,
    vtkDataObject::FIELD_ASSOCIATION_POINTS, vtkDataSetAttributes::SCALARS);
}

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

//-----------------------------------------------------------------------------
void vtkIconGlyphFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Icon Size: " << this->IconSize[0] << " " << this->IconSize[1] << endl;
  os << indent << "Icon Sheet Size: " << this->IconSheetSize[0] << " " << this->IconSheetSize[1] << endl;
  os << indent << "Display Size: " << this->DisplaySize[0] << " " << this->DisplaySize[1] << endl;
  os << indent << "Gravity: " << this->Gravity << "\n";
  os << indent << "Use Icon Size: "
     << (this->UseIconSize ? " On" : " Off") << endl;
  os << indent << "Pass Scalars: "
     << (this->PassScalars ? " On" : " Off") << endl;
  os << indent << "Icon Scaling: " << this->IconScaling << endl;
}

//-----------------------------------------------------------------------------
int vtkIconGlyphFilter::RequestData(vtkInformation *vtkNotUsed(request),
                                  vtkInformationVector **inputVector,
                                  vtkInformationVector *outputVector)
{
  // Get the information object.
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // Get the data objects.
  vtkPointSet *input = vtkPointSet::SafeDownCast(
                                     inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPolyData *output = vtkPolyData::SafeDownCast(
                                    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  int numPoints = input->GetNumberOfPoints();

  if (numPoints <= 0)
    {
    // nothing to do...
    return 1;
    }

  vtkIntArray* scalars = vtkIntArray::SafeDownCast(
    this->GetInputArrayToProcess(0, inputVector));
  if (!scalars)
    {
    vtkErrorMacro("Input Scalars must be specified to index into the icon sheet.");
    return 0;
    }

  // Optional scaling may be going on
  vtkDataArray *scalingArray = NULL;
  if ( this->IconScaling == VTK_ICON_SCALING_USE_SCALING_ARRAY )
    {
    scalingArray = input->GetPointData()->GetArray("IconScale");
    }

  double point[3], textureCoord[2];
  point[2] = 0;
  double sheetXDim = this->IconSheetSize[0]/this->IconSize[0];
  double sheetYDim = this->IconSheetSize[1]/this->IconSize[1];
  int iconIndex = 0;
  int j, k;

  vtkPoints * outPoints = vtkPoints::New();
  outPoints->Allocate(4 * numPoints);

  vtkCellArray * outCells = vtkCellArray::New();
  outCells->Allocate(outCells->EstimateSize(numPoints, 4));

  vtkFloatArray *outTCoords = vtkFloatArray::New();
  outTCoords->SetNumberOfComponents(2);
  outTCoords->Allocate(8*numPoints);

  // Copy point data to cell data
  vtkPointData *inPD = input->GetPointData();
  vtkCellData  *outCD = output->GetCellData();

  double size[2];
  size[0] = this->DisplaySize[0];
  size[1] = this->DisplaySize[1];
  if(this->UseIconSize)
    {
    size[0] = this->IconSize[0];
    size[1] = this->IconSize[1];
    }

  vtkIdType ptId;
  double sf = 1.0;
  for(ptId = 0; ptId < numPoints; ++ptId)
    {
    iconIndex = scalars->GetValue(ptId);

    if(iconIndex >= 0)
      {
      this->IconConvertIndex(iconIndex, j, k);

      textureCoord[0] = j/sheetXDim;
      textureCoord[1] = k/sheetYDim;
      outTCoords->InsertTuple(ptId * 4, textureCoord);

      textureCoord[0] = (j + 1.0)/sheetXDim;
      textureCoord[1] = k/sheetYDim;
      outTCoords->InsertTuple(ptId * 4 + 1, textureCoord);

      textureCoord[0] = (j + 1.0)/sheetXDim;
      textureCoord[1] = (k + 1.0)/sheetYDim;
      outTCoords->InsertTuple(ptId * 4 + 2, textureCoord);

      textureCoord[0] = j/sheetXDim;
      textureCoord[1] = (k + 1.0)/sheetYDim;
      outTCoords->InsertTuple(ptId * 4 + 3, textureCoord);
      }

    input->GetPoint(ptId, point);
    point[0] += this->Offset[0];
    point[1] += this->Offset[1];

    if ( scalingArray )
      {
      sf = scalingArray->GetTuple1(ptId);
      }

    switch(this->Gravity)
      {
      case VTK_ICON_GRAVITY_CENTER_CENTER:
        break;
      case VTK_ICON_GRAVITY_TOP_RIGHT:
        point[0] = point[0] + 0.5 * sf * size[0];
        point[1] = point[1] + 0.5 * sf * size[1];
        break;
      case VTK_ICON_GRAVITY_TOP_CENTER:
        point[1] = point[1] + 0.5 * sf * size[1];
        break;
      case VTK_ICON_GRAVITY_TOP_LEFT:
        point[0] = point[0] - 0.5 * sf * size[0];
        point[1] = point[1] + 0.5 * sf * size[1];
        break;
      case VTK_ICON_GRAVITY_CENTER_RIGHT:
        point[0] = point[0] + 0.5 * sf * size[0];
        break;
      case VTK_ICON_GRAVITY_CENTER_LEFT:
        point[0] = point[0] - 0.5 * sf * size[0];
        break;
      case VTK_ICON_GRAVITY_BOTTOM_RIGHT:
        point[0] = point[0] + 0.5 * sf * size[0];
        point[1] = point[1] - 0.5 * sf * size[1];
        break;
      case VTK_ICON_GRAVITY_BOTTOM_CENTER:
        point[1] = point[1] - 0.5 * sf * size[1];
        break;
      case VTK_ICON_GRAVITY_BOTTOM_LEFT:
        point[0] = point[0] - 0.5 * sf * size[0];
        point[1] = point[1] - 0.5 * sf * size[1];
        break;
      }

    outPoints->InsertNextPoint(point[0] - 0.5 * sf * size[0], point[1] - 0.5 * sf * size[1], point[2]);
    outPoints->InsertNextPoint(point[0] + 0.5 * sf * size[0], point[1] - 0.5 * sf * size[1], point[2]);
    outPoints->InsertNextPoint(point[0] + 0.5 * sf * size[0], point[1] + 0.5 * sf * size[1], point[2]);
    outPoints->InsertNextPoint(point[0] - 0.5 * sf * size[0], point[1] + 0.5 * sf * size[1], point[2]);

    outCells->InsertNextCell(4);
    outCells->InsertCellPoint(ptId * 4);
    outCells->InsertCellPoint(ptId * 4 + 1);
    outCells->InsertCellPoint(ptId * 4 + 2);
    outCells->InsertCellPoint(ptId * 4 + 3);
    }

  output->SetPoints(outPoints);
  outPoints->Delete();

  outTCoords->SetName("TextureCoordinates");
  output->GetPointData()->SetTCoords(outTCoords);
  outTCoords->Delete();

  output->SetPolys(outCells);
  outCells->Delete();

  // Pass the input point data to the cell data because for every point we
  // generate a quad cell.
  if ( this->PassScalars )
    {
    outCD->CopyScalarsOn();
    }
  else
    {
    outCD->CopyScalarsOff();
    }
  outCD->PassData(inPD);

  return 1;
}

<|endoftext|>


<commit_before>#ifdef HAVE_CXX11
#include <functional>
#define HAVE_CPP_FUNC_PTR
namespace funcptr = std;
#else
#ifdef HAVE_BOOST
#include <boost/function.hpp>
namespace funcptr = boost;
#define HAVE_CPP_FUNC_PTR
#endif
#endif

#include <fstream>
#include <cctype>

#ifndef WIN32
#include <cstdio>
#include <unistd.h>
#endif

#ifndef YAHTTP_MAX_REQUEST_SIZE
#define YAHTTP_MAX_REQUEST_SIZE 2097152
#endif

#ifndef YAHTTP_MAX_RESPONSE_SIZE
#define YAHTTP_MAX_RESPONSE_SIZE 2097152
#endif

#define YAHTTP_TYPE_REQUEST 1
#define YAHTTP_TYPE_RESPONSE 2

namespace YaHTTP {
  typedef std::map<std::string,std::string> strstr_map_t;
  typedef std::map<std::string,Cookie> strcookie_map_t;

  typedef enum {
    urlencoded,
    multipart
  } postformat_t;

  class HTTPBase {
  public:
#ifdef HAVE_CPP_FUNC_PTR
    class SendBodyRender {
    public:
      SendBodyRender() {};

      size_t operator()(const HTTPBase *doc, std::ostream& os) const {
        os << doc->body;
        return doc->body.length();
      };
    };
    class SendFileRender {
    public:
      SendFileRender(const std::string& path) {
        this->path = path;
      };

      size_t operator()(const HTTPBase *doc __attribute__((unused)), std::ostream& os) const {
        char buf[4096];
        size_t n,k;
#ifdef HAVE_CXX11
        std::ifstream ifs(path, std::ifstream::binary);
#else
        std::ifstream ifs(path.c_str(), std::ifstream::binary);
#endif
        n = 0;
        while(ifs && ifs.good()) {
          ifs.read(buf, sizeof buf);
          n += (k = ifs.gcount());
          if (k)
            os.write(buf, k);
        }

        return n;
      };

      std::string path;
    };
#endif
    HTTPBase() {
      kind = 0;
      status = 0;
#ifdef HAVE_CPP_FUNC_PTR
      renderer = SendBodyRender();
#endif
    };
protected:
    HTTPBase(const HTTPBase& rhs) {
      this->url = rhs.url; this->kind = rhs.kind;
      this->status = rhs.status; this->statusText = rhs.statusText;
      this->method = rhs.method; this->headers = rhs.headers;
      this->jar = rhs.jar; this->postvars = rhs.postvars;
      this->parameters = rhs.parameters; this->getvars = rhs.getvars;
      this->body = rhs.body;
#ifdef HAVE_CPP_FUNC_PTR
      this->renderer = rhs.renderer;
#endif
    };
    HTTPBase& operator=(const HTTPBase& rhs) {
      this->url = rhs.url; this->kind = rhs.kind;
      this->status = rhs.status; this->statusText = rhs.statusText;
      this->method = rhs.method; this->headers = rhs.headers;
      this->jar = rhs.jar; this->postvars = rhs.postvars;
      this->parameters = rhs.parameters; this->getvars = rhs.getvars;
      this->body = rhs.body;
#ifdef HAVE_CPP_FUNC_PTR
      this->renderer = rhs.renderer;
#endif
      return *this;
    };
public:
    URL url;
    int kind;
    int status;
    std::string statusText;
    std::string method;
    strstr_map_t headers;
    CookieJar jar;
    strstr_map_t postvars;
    strstr_map_t getvars;
// these two are for Router
    strstr_map_t parameters;
    std::string routeName;

    std::string body;

#ifdef HAVE_CPP_FUNC_PTR
    funcptr::function<size_t(const HTTPBase*,std::ostream&)> renderer;
#endif
    void write(std::ostream& os) const;

    strstr_map_t& GET() { return getvars; };
    strstr_map_t& POST() { return postvars; };
    strcookie_map_t& COOKIES() { return jar.cookies; };
  };

  class Response: public HTTPBase {
  public:
    Response() { this->kind = YAHTTP_TYPE_RESPONSE; };
    Response(const HTTPBase& rhs): HTTPBase(rhs) {
      this->kind = YAHTTP_TYPE_RESPONSE;
    };
    Response& operator=(const HTTPBase& rhs) {
      HTTPBase::operator=(rhs);
      this->kind = YAHTTP_TYPE_RESPONSE;
      return *this;
    }
    friend std::ostream& operator<<(std::ostream& os, const Response &resp);
    friend std::istream& operator>>(std::istream& is, Response &resp);
  };

  class Request: public HTTPBase {
  public:
    Request() { this->kind = YAHTTP_TYPE_REQUEST; };
    Request(const HTTPBase& rhs): HTTPBase(rhs) {
      this->kind = YAHTTP_TYPE_REQUEST;
    };
    Request& operator=(const HTTPBase& rhs) {
      HTTPBase::operator=(rhs);
      this->kind = YAHTTP_TYPE_REQUEST;
      return *this;
    }

    void setup(const std::string& method, const std::string& url) {
      this->url.parse(url);
      this->headers["host"] = this->url.host;
      this->method = method;
      std::transform(this->method.begin(), this->method.end(), this->method.begin(), ::toupper);
      this->headers["user-agent"] = "YaHTTP v1.0";
    }

    void preparePost(postformat_t format = urlencoded) {
      std::ostringstream postbuf;
      if (format == urlencoded) {
        for(strstr_map_t::const_iterator i = POST().begin(); i != POST().end(); i++) {
          postbuf << Utility::encodeURL(i->first) << "=" << Utility::encodeURL(i->second) << "&";
        }
        // remove last bit
        if (postbuf.str().length()>0)
          body = postbuf.str().substr(0, postbuf.str().length()-1);
        else
          body = "";
        headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
      } else if (format == multipart) {
        headers["content-type"] = "multipart/form-data; boundary=YaHTTP-12ca543";
        for(strstr_map_t::const_iterator i = POST().begin(); i != POST().end(); i++) {
          postbuf << "--YaHTTP-12ca543\r\nContent-Disposition: form-data; name=\"" << Utility::encodeURL(i->first) << "; charset=UTF-8\r\n\r\n"
            << Utility::encodeURL(i->second) << "\r\n";
        }
      }

      postbuf.str("");
      postbuf << body.length();
      // set method and change headers
      method = "POST";
      headers["content-length"] = postbuf.str();
    };

    friend std::ostream& operator<<(std::ostream& os, const Request &resp);
    friend std::istream& operator>>(std::istream& is, Request &resp);
  };

  template <class T>
  class AsyncLoader {
  public:
    T* target;
    int state;
    size_t pos;

    std::string buffer;
    bool chunked;
    int chunk_size;
    std::ostringstream bodybuf;
    size_t maxbody;
    size_t minbody;
    bool hasBody;

    void keyValuePair(const std::string &keyvalue, std::string &key, std::string &value);

    void initialize(T* target) {
      chunked = false; chunk_size = 0;
      bodybuf.str(""); maxbody = 0;
      pos = 0; state = 0; this->target = target;
      hasBody = false;
    };
    int feed(const std::string& somedata);
    bool ready() {  return state > 1 &&
                      (!hasBody ||
                         (bodybuf.str().size() <= maxbody &&
                          bodybuf.str().size() >= minbody)
                      );
                 };
    void finalize() {
      bodybuf.flush();
      if (ready()) {
        strstr_map_t::iterator pos = target->headers.find("content-type");
        if (pos != target->headers.end() && Utility::iequals(pos->second, "application/x-www-form-urlencoded", 32)) {
          target->postvars = Utility::parseUrlParameters(bodybuf.str());
        }
        target->body = bodybuf.str();
      }
      bodybuf.str("");
      this->target = NULL;
    };
  };

  class AsyncResponseLoader: public AsyncLoader<Response> {
  };

  class AsyncRequestLoader: public AsyncLoader<Request> {
  };

};
<commit_msg>Add str() method to request/response<commit_after>#ifdef HAVE_CXX11
#include <functional>
#define HAVE_CPP_FUNC_PTR
namespace funcptr = std;
#else
#ifdef HAVE_BOOST
#include <boost/function.hpp>
namespace funcptr = boost;
#define HAVE_CPP_FUNC_PTR
#endif
#endif

#include <fstream>
#include <cctype>

#ifndef WIN32
#include <cstdio>
#include <unistd.h>
#endif

#ifndef YAHTTP_MAX_REQUEST_SIZE
#define YAHTTP_MAX_REQUEST_SIZE 2097152
#endif

#ifndef YAHTTP_MAX_RESPONSE_SIZE
#define YAHTTP_MAX_RESPONSE_SIZE 2097152
#endif

#define YAHTTP_TYPE_REQUEST 1
#define YAHTTP_TYPE_RESPONSE 2

namespace YaHTTP {
  typedef std::map<std::string,std::string> strstr_map_t;
  typedef std::map<std::string,Cookie> strcookie_map_t;

  typedef enum {
    urlencoded,
    multipart
  } postformat_t;

  class HTTPBase {
  public:
#ifdef HAVE_CPP_FUNC_PTR
    class SendBodyRender {
    public:
      SendBodyRender() {};

      size_t operator()(const HTTPBase *doc, std::ostream& os) const {
        os << doc->body;
        return doc->body.length();
      };
    };
    class SendFileRender {
    public:
      SendFileRender(const std::string& path) {
        this->path = path;
      };

      size_t operator()(const HTTPBase *doc __attribute__((unused)), std::ostream& os) const {
        char buf[4096];
        size_t n,k;
#ifdef HAVE_CXX11
        std::ifstream ifs(path, std::ifstream::binary);
#else
        std::ifstream ifs(path.c_str(), std::ifstream::binary);
#endif
        n = 0;
        while(ifs && ifs.good()) {
          ifs.read(buf, sizeof buf);
          n += (k = ifs.gcount());
          if (k)
            os.write(buf, k);
        }

        return n;
      };

      std::string path;
    };
#endif
    HTTPBase() {
      kind = 0;
      status = 0;
#ifdef HAVE_CPP_FUNC_PTR
      renderer = SendBodyRender();
#endif
    };
protected:
    HTTPBase(const HTTPBase& rhs) {
      this->url = rhs.url; this->kind = rhs.kind;
      this->status = rhs.status; this->statusText = rhs.statusText;
      this->method = rhs.method; this->headers = rhs.headers;
      this->jar = rhs.jar; this->postvars = rhs.postvars;
      this->parameters = rhs.parameters; this->getvars = rhs.getvars;
      this->body = rhs.body;
#ifdef HAVE_CPP_FUNC_PTR
      this->renderer = rhs.renderer;
#endif
    };
    HTTPBase& operator=(const HTTPBase& rhs) {
      this->url = rhs.url; this->kind = rhs.kind;
      this->status = rhs.status; this->statusText = rhs.statusText;
      this->method = rhs.method; this->headers = rhs.headers;
      this->jar = rhs.jar; this->postvars = rhs.postvars;
      this->parameters = rhs.parameters; this->getvars = rhs.getvars;
      this->body = rhs.body;
#ifdef HAVE_CPP_FUNC_PTR
      this->renderer = rhs.renderer;
#endif
      return *this;
    };
public:
    URL url;
    int kind;
    int status;
    std::string statusText;
    std::string method;
    strstr_map_t headers;
    CookieJar jar;
    strstr_map_t postvars;
    strstr_map_t getvars;
// these two are for Router
    strstr_map_t parameters;
    std::string routeName;

    std::string body;

#ifdef HAVE_CPP_FUNC_PTR
    funcptr::function<size_t(const HTTPBase*,std::ostream&)> renderer;
#endif
    void write(std::ostream& os) const;

    strstr_map_t& GET() { return getvars; };
    strstr_map_t& POST() { return postvars; };
    strcookie_map_t& COOKIES() { return jar.cookies; };

    std::string str() const {
       std::ostringstream oss;
       write(oss);
       return oss.str();
    };
  };

  class Response: public HTTPBase {
  public:
    Response() { this->kind = YAHTTP_TYPE_RESPONSE; };
    Response(const HTTPBase& rhs): HTTPBase(rhs) {
      this->kind = YAHTTP_TYPE_RESPONSE;
    };
    Response& operator=(const HTTPBase& rhs) {
      HTTPBase::operator=(rhs);
      this->kind = YAHTTP_TYPE_RESPONSE;
      return *this;
    }
    friend std::ostream& operator<<(std::ostream& os, const Response &resp);
    friend std::istream& operator>>(std::istream& is, Response &resp);
  };

  class Request: public HTTPBase {
  public:
    Request() { this->kind = YAHTTP_TYPE_REQUEST; };
    Request(const HTTPBase& rhs): HTTPBase(rhs) {
      this->kind = YAHTTP_TYPE_REQUEST;
    };
    Request& operator=(const HTTPBase& rhs) {
      HTTPBase::operator=(rhs);
      this->kind = YAHTTP_TYPE_REQUEST;
      return *this;
    }

    void setup(const std::string& method, const std::string& url) {
      this->url.parse(url);
      this->headers["host"] = this->url.host;
      this->method = method;
      std::transform(this->method.begin(), this->method.end(), this->method.begin(), ::toupper);
      this->headers["user-agent"] = "YaHTTP v1.0";
    }

    void preparePost(postformat_t format = urlencoded) {
      std::ostringstream postbuf;
      if (format == urlencoded) {
        for(strstr_map_t::const_iterator i = POST().begin(); i != POST().end(); i++) {
          postbuf << Utility::encodeURL(i->first) << "=" << Utility::encodeURL(i->second) << "&";
        }
        // remove last bit
        if (postbuf.str().length()>0)
          body = postbuf.str().substr(0, postbuf.str().length()-1);
        else
          body = "";
        headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
      } else if (format == multipart) {
        headers["content-type"] = "multipart/form-data; boundary=YaHTTP-12ca543";
        for(strstr_map_t::const_iterator i = POST().begin(); i != POST().end(); i++) {
          postbuf << "--YaHTTP-12ca543\r\nContent-Disposition: form-data; name=\"" << Utility::encodeURL(i->first) << "; charset=UTF-8\r\n\r\n"
            << Utility::encodeURL(i->second) << "\r\n";
        }
      }

      postbuf.str("");
      postbuf << body.length();
      // set method and change headers
      method = "POST";
      headers["content-length"] = postbuf.str();
    };

    friend std::ostream& operator<<(std::ostream& os, const Request &resp);
    friend std::istream& operator>>(std::istream& is, Request &resp);
  };

  template <class T>
  class AsyncLoader {
  public:
    T* target;
    int state;
    size_t pos;

    std::string buffer;
    bool chunked;
    int chunk_size;
    std::ostringstream bodybuf;
    size_t maxbody;
    size_t minbody;
    bool hasBody;

    void keyValuePair(const std::string &keyvalue, std::string &key, std::string &value);

    void initialize(T* target) {
      chunked = false; chunk_size = 0;
      bodybuf.str(""); maxbody = 0;
      pos = 0; state = 0; this->target = target;
      hasBody = false;
    };
    int feed(const std::string& somedata);
    bool ready() {  return state > 1 &&
                      (!hasBody ||
                         (bodybuf.str().size() <= maxbody &&
                          bodybuf.str().size() >= minbody)
                      );
                 };
    void finalize() {
      bodybuf.flush();
      if (ready()) {
        strstr_map_t::iterator pos = target->headers.find("content-type");
        if (pos != target->headers.end() && Utility::iequals(pos->second, "application/x-www-form-urlencoded", 32)) {
          target->postvars = Utility::parseUrlParameters(bodybuf.str());
        }
        target->body = bodybuf.str();
      }
      bodybuf.str("");
      this->target = NULL;
    };
  };

  class AsyncResponseLoader: public AsyncLoader<Response> {
  };

  class AsyncRequestLoader: public AsyncLoader<Request> {
  };

};
<|endoftext|>


<commit_before>#include <spdlog/spdlog.h>

#include <algorithm>
#include <memory>
#include <string>
#include <regex>
#include <sstream>

#include "core/Peer.hpp"
#include "core/Engine.hpp"
#include "core/ProgramContext.hpp"
#include "network/NetworkManager.hpp"

namespace K3 {

Peer::Peer(shared_ptr<ContextFactory> fac, const YAML::Node& config,
           std::function<void()> callback, const JSONOptions& opts) {
  // Initialization
  address_ = serialization::yaml::meFromYAML(config);
  start_processing_ = false;
  finished_ = false;
  message_counter_ = 0;
  statistics_.resize(ProgramContext::__trigger_names_.size());
  json_opts_ = opts;

  // Log configuration
  logger_ = spdlog::get(address_.toString());
  if (!logger_) {
    logger_ = spdlog::stdout_logger_mt(address_.toString());
  }
  string json_path = json_opts_.output_folder_;
  if (json_path != "") {
    json_globals_log_ = make_shared<std::ofstream>(
        json_path + "/" + address_.toString() + "_Globals.dsv");
    json_messages_log_ = make_shared<std::ofstream>(
        json_path + "/" + address_.toString() + "_Messages.dsv");
  }

  // Create work to run in new thread
  auto work = [this, fac, config, callback]() {
    // Queue and batch are allocated on worker thread for locality
    queue_ = make_shared<Queue>();
    batch_.resize(1000);
    context_ = (*fac)();
    context_->__patch(config);
    context_->initDecls(unit_t{});

    // Signal that peer is initialized, wait for 'go' signal
    callback();
    while (!start_processing_) continue;
    try {
      while (true) {
        processBatch();
      }
    } catch (EndOfProgramException e) {
      finished_ = true;
#ifdef K3DEBUG
      logGlobals(true);
#endif
    }
    //catch (const std::exception& e) {
    //  logger_->error() << "Peer failed: " << e.what();
    //}
  };

  // Execute in new thread
  thread_ = make_shared<std::thread>(work);
}

void Peer::processRole() {
  if (!context_) {
    throw std::runtime_error("Peer processRole(): null context ptr");
  }
  context_->processRole(unit_t{});
}

void Peer::start() { start_processing_ = true; }

void Peer::join() {
  if (!thread_) {
    throw std::runtime_error("Peer join(): not running ");
  }
  thread_->join();
  return;
}

Queue& Peer::getQueue() { return *queue_; }

bool Peer::finished() { return finished_.load(); }

Address Peer::address() { return address_; }

shared_ptr<ProgramContext> Peer::getContext() { return context_; }

void Peer::processBatch() {
  size_t num = queue_->dequeueBulk(batch_);

  for (int i = 0; i < num; i++) {
    auto d = std::move(batch_[i]);
#ifdef K3DEBUG
    logMessage(*d);
    TriggerID tid = d->trigger_;
    std::chrono::high_resolution_clock::time_point start_time =
        std::chrono::high_resolution_clock::now();
#endif  // K3DEBUG

    (*d)();  // Call the dispatcher (process a message)

#ifdef K3DEBUG
    statistics_[tid].total_time +=
        std::chrono::high_resolution_clock::now() - start_time;
    statistics_[tid].total_count++;
    logGlobals(false);
#endif  // K3DEBUG
  }
}

void Peer::logMessage(const Dispatcher& d) {
#ifdef K3DEBUG
  string trig = ProgramContext::__triggerName(d.trigger_);
  if (logger_->level() <= spdlog::level::debug) {
    logger_->debug() << "Received:: @" << trig;
  }

  if (json_messages_log_ && !json_opts_.final_state_only_ &&
      std::regex_match(trig, std::regex(json_opts_.messages_regex_))) {
    *json_messages_log_ << message_counter_ << "|";
    *json_messages_log_ << K3::serialization::json::encode<Address>(
                               d.destination_) << "|";
    *json_messages_log_ << trig << "|";
    *json_messages_log_ << K3::serialization::json::encode<Address>(d.source_)
                        << "|";
    *json_messages_log_ << d.jsonify() << "|";
    *json_messages_log_ << currentTime() << std::endl;
  }
  message_counter_++;
#endif  // K3DEBUG
}

void Peer::logGlobals(bool final) {
#ifdef K3DEBUG
  if (logger_->level() <= spdlog::level::trace) {
    std::ostringstream oss;
    oss << "Environment: " << std::endl;
    bool first = true;
    for (const auto& it : context_->__prettify()) {
      if (!first) {
        oss << std::endl;
      } else {
        first = false;
      }
      oss << std::setw(10) << it.first << ": " << it.second;
    }
    logger_->trace() << oss.str();
  }

  if ((json_globals_log_ && !json_opts_.final_state_only_) ||
      (json_opts_.final_state_only_ && final)) {
    for (const auto& global : context_->__globalNames()) {
      if (std::regex_match(global.c_str(),
                           std::regex(json_opts_.globals_regex_.c_str()))) {
        *json_globals_log_ << message_counter_ << "|"
                           << K3::serialization::json::encode<Address>(address_)
                           << "|" << global << "|"
                           << context_->__jsonify(global) << std::endl;
      }
    }
  }
#endif  // K3DEBUG
}

void Peer::printStatistics() {
  // Associate each statistic with its trigger id, since sorting will reorder
  // the statistics_ vector
  for (int i = 0; i < statistics_.size(); i++) {
    statistics_[i].trig_id = ProgramContext::__triggerName(i);
  }

  double total = 0.0;
  std::cout << "===Trigger Statistics @" << addressAsString(address_)
            << "===" << std::endl;
  std::sort(statistics_.begin(), statistics_.end(),
            [](const TriggerStatistics& a, const TriggerStatistics& b) {
              return a.total_time > b.total_time;
            });

  int k = 10;
  int max = statistics_.size() < k ? statistics_.size() : k;
  for (int i = 0; i < max; i++) {
    auto count = statistics_[i].total_count;
    auto time =
        std::chrono::duration_cast<std::chrono::duration<float, std::ratio<1>>>(
            statistics_[i].total_time)
            .count();
    total += time;
    std::cout << std::setw(70) << statistics_[i].trig_id << ": " << std::setw(6)
              << count << " call(s), " << std::setw(15) << std::scientific
              << std::setprecision(15) << time << "s total time spent, "
              << std::setw(6) << std::scientific << std::setprecision(15)
              << time / count << "s average per call." << std::endl;
  }
  std::cout << "Total time in all triggers: " << total << std::endl;
}
}  // namespace K3
<commit_msg>runtime peer: remove small bit of logging work when not logging<commit_after>#include <spdlog/spdlog.h>

#include <algorithm>
#include <memory>
#include <string>
#include <regex>
#include <sstream>

#include "core/Peer.hpp"
#include "core/Engine.hpp"
#include "core/ProgramContext.hpp"
#include "network/NetworkManager.hpp"

namespace K3 {

Peer::Peer(shared_ptr<ContextFactory> fac, const YAML::Node& config,
           std::function<void()> callback, const JSONOptions& opts) {
  // Initialization
  address_ = serialization::yaml::meFromYAML(config);
  start_processing_ = false;
  finished_ = false;
  message_counter_ = 0;
  statistics_.resize(ProgramContext::__trigger_names_.size());
  json_opts_ = opts;

  // Log configuration
  logger_ = spdlog::get(address_.toString());
  if (!logger_) {
    logger_ = spdlog::stdout_logger_mt(address_.toString());
  }
  string json_path = json_opts_.output_folder_;
  if (json_path != "") {
    json_globals_log_ = make_shared<std::ofstream>(
        json_path + "/" + address_.toString() + "_Globals.dsv");
    json_messages_log_ = make_shared<std::ofstream>(
        json_path + "/" + address_.toString() + "_Messages.dsv");
  }

  // Create work to run in new thread
  auto work = [this, fac, config, callback]() {
    // Queue and batch are allocated on worker thread for locality
    queue_ = make_shared<Queue>();
    batch_.resize(1000);
    context_ = (*fac)();
    context_->__patch(config);
    context_->initDecls(unit_t{});

    // Signal that peer is initialized, wait for 'go' signal
    callback();
    while (!start_processing_) continue;
    try {
      while (true) {
        processBatch();
      }
    } catch (EndOfProgramException e) {
      finished_ = true;
#ifdef K3DEBUG
      logGlobals(true);
#endif
    }
    //catch (const std::exception& e) {
    //  logger_->error() << "Peer failed: " << e.what();
    //}
  };

  // Execute in new thread
  thread_ = make_shared<std::thread>(work);
}

void Peer::processRole() {
  if (!context_) {
    throw std::runtime_error("Peer processRole(): null context ptr");
  }
  context_->processRole(unit_t{});
}

void Peer::start() { start_processing_ = true; }

void Peer::join() {
  if (!thread_) {
    throw std::runtime_error("Peer join(): not running ");
  }
  thread_->join();
  return;
}

Queue& Peer::getQueue() { return *queue_; }

bool Peer::finished() { return finished_.load(); }

Address Peer::address() { return address_; }

shared_ptr<ProgramContext> Peer::getContext() { return context_; }

void Peer::processBatch() {
  size_t num = queue_->dequeueBulk(batch_);

  for (int i = 0; i < num; i++) {
    auto d = std::move(batch_[i]);
#ifdef K3DEBUG
    logMessage(*d);
    TriggerID tid = d->trigger_;
    std::chrono::high_resolution_clock::time_point start_time =
        std::chrono::high_resolution_clock::now();
#endif  // K3DEBUG

    (*d)();  // Call the dispatcher (process a message)

#ifdef K3DEBUG
    statistics_[tid].total_time +=
        std::chrono::high_resolution_clock::now() - start_time;
    statistics_[tid].total_count++;
    logGlobals(false);
#endif  // K3DEBUG
  }
}

void Peer::logMessage(const Dispatcher& d) {
#ifdef K3DEBUG
  if (logger_->level() <= spdlog::level::debug) {
    string trig = ProgramContext::__triggerName(d.trigger_);
    logger_->debug() << "Received:: @" << trig;
  }

  if (json_messages_log_ && !json_opts_.final_state_only_) {
    string trig = ProgramContext::__triggerName(d.trigger_);
    if (std::regex_match(trig, std::regex(json_opts_.messages_regex_))) {
      *json_messages_log_ << message_counter_ << "|";
      *json_messages_log_ << K3::serialization::json::encode<Address>(
                                d.destination_) << "|";
      *json_messages_log_ << trig << "|";
      *json_messages_log_ << K3::serialization::json::encode<Address>(d.source_)
                          << "|";
      *json_messages_log_ << d.jsonify() << "|";
      *json_messages_log_ << currentTime() << std::endl;
    }
  }
  message_counter_++;
#endif  // K3DEBUG
}

void Peer::logGlobals(bool final) {
#ifdef K3DEBUG
  if (logger_->level() <= spdlog::level::trace) {
    std::ostringstream oss;
    oss << "Environment: " << std::endl;
    bool first = true;
    for (const auto& it : context_->__prettify()) {
      if (!first) {
        oss << std::endl;
      } else {
        first = false;
      }
      oss << std::setw(10) << it.first << ": " << it.second;
    }
    logger_->trace() << oss.str();
  }

  if ((json_globals_log_ && !json_opts_.final_state_only_) ||
      (json_opts_.final_state_only_ && final)) {
    for (const auto& global : context_->__globalNames()) {
      if (std::regex_match(global.c_str(),
                           std::regex(json_opts_.globals_regex_.c_str()))) {
        *json_globals_log_ << message_counter_ << "|"
                           << K3::serialization::json::encode<Address>(address_)
                           << "|" << global << "|"
                           << context_->__jsonify(global) << std::endl;
      }
    }
  }
#endif  // K3DEBUG
}

void Peer::printStatistics() {
  // Associate each statistic with its trigger id, since sorting will reorder
  // the statistics_ vector
  for (int i = 0; i < statistics_.size(); i++) {
    statistics_[i].trig_id = ProgramContext::__triggerName(i);
  }

  double total = 0.0;
  std::cout << "===Trigger Statistics @" << addressAsString(address_)
            << "===" << std::endl;
  std::sort(statistics_.begin(), statistics_.end(),
            [](const TriggerStatistics& a, const TriggerStatistics& b) {
              return a.total_time > b.total_time;
            });

  int k = 10;
  int max = statistics_.size() < k ? statistics_.size() : k;
  for (int i = 0; i < max; i++) {
    auto count = statistics_[i].total_count;
    auto time =
        std::chrono::duration_cast<std::chrono::duration<float, std::ratio<1>>>(
            statistics_[i].total_time)
            .count();
    total += time;
    std::cout << std::setw(70) << statistics_[i].trig_id << ": " << std::setw(6)
              << count << " call(s), " << std::setw(15) << std::scientific
              << std::setprecision(15) << time << "s total time spent, "
              << std::setw(6) << std::scientific << std::setprecision(15)
              << time / count << "s average per call." << std::endl;
  }
  std::cout << "Total time in all triggers: " << total << std::endl;
}
}  // namespace K3
<|endoftext|>


<commit_before>#include "fdsb/nid.hpp"
#include "fdsb/harc.hpp"

using namespace fdsb;

Harc::Harc(const Nid &a, const Nid &b)
{
	m_tail[0] = a;
	m_tail[1] = b;
	m_head = null_nid;
	m_out_of_date = false;
}

const Nid &Harc::query()
{
	//Check if out_of_date.
	return m_head;
}

void Harc::add_dependant(Harc &h)
{
	m_dependants.push(&h);
}

void Harc::mark()
{
	m_out_of_date = true;
	//Mark all dependants.
}

void Harc::define(const Nid &n)
{
	m_head = n;
	m_out_of_date = false;
	//Mark all dependants.
}

Harc &Harc::operator=(const Nid &n)
{
	define(n);
	return *this;
}
<commit_msg>Corrected list push method name<commit_after>#include "fdsb/nid.hpp"
#include "fdsb/harc.hpp"

using namespace fdsb;

Harc::Harc(const Nid &a, const Nid &b)
{
	m_tail[0] = a;
	m_tail[1] = b;
	m_head = null_nid;
	m_out_of_date = false;
}

const Nid &Harc::query()
{
	//Check if out_of_date.
	return m_head;
}

void Harc::add_dependant(Harc &h)
{
	m_dependants.push_back(&h);
}

void Harc::mark()
{
	m_out_of_date = true;
	//Mark all dependants.
}

void Harc::define(const Nid &n)
{
	m_head = n;
	m_out_of_date = false;
	//Mark all dependants.
}

Harc &Harc::operator=(const Nid &n)
{
	define(n);
	return *this;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <functional>

typedef uint32_t uint32;
typedef int32_t int32;
typedef uint64_t uint64;
typedef int64_t int64;
typedef uint16_t uint16;
typedef int8_t int8;

// #define DT_INT8 int8_t
template<typename T>
class DT {
public:
    static const DT<T> get() {
        const DT<T> v;
        return v;
    }
};
#define DT_INT8 DT<int8_t>::get()

#define EIGEN_DEVICE_FUNC __attribute__((device))
#define EIGEN_STRONG_INLINE __inline__

#define TF_RETURN_IF_ERROR(x) x

class Status {
public:
    Status(int value) {
        this->value = value;
    }
    static Status OK() {
        return Status(0);
    }
    int value;
};
struct TensorShape {
    int64_t x;
};
class TensorReference {
public:
    void Unref() const;
};
namespace perftools {
    namespace gputools {
        class DeviceMemoryBase {
        public:
        };
    }
}
class Stream {
public:
    void ThenMemcpy(float *);
};
class EventMgr {
public:
    void ThenExecute(Stream &stream, std::function<void ()> fn);
};

class GpuDeviceInfo {
public:
    GpuDeviceInfo() {
        event_mgr = new EventMgr();
    }
    ~GpuDeviceInfo() {
        delete event_mgr;
    }
    EventMgr *event_mgr;
};
class AllocatorAttributes {
public:
    void set_on_host(bool v) {
        this->on_host = v;
    }
    void set_gpu_compatible(bool v) {
        this->gpu_compatible = v;
    }
    bool on_host = false;
    bool gpu_compatible;
};
class Tensor {
public:
    template<typename T>
    Tensor flat() {
        std::cout << "Tensor::flat()" << std::endl;
        Tensor ret;
        return ret;
    }
    bool IsInitialized() const;
    float *data() {
        std::cout << "Tensor::data()" << std::endl;
        return 0;
    }
};
class Device {
public:
    GpuDeviceInfo *tensorflow_gpu_device_info();
};
class OpDeviceContext {
public:
    Stream *stream();
};
class OpKernelContext {
public:
    Status allocate_temp(DT<int8_t> dt, TensorShape tensorShape, Tensor *tensor, AllocatorAttributes attrib) {
        std::cout << "OpKernelContext::allocate_temp()" << std::endl;
        return Status::OK();
    }
    OpDeviceContext *op_device_context() {
        return &opDeviceContext;
    }
    Device *device();
    OpDeviceContext opDeviceContext;
};
#define TF_DISALLOW_COPY_AND_ASSIGN(x)

#include "tf_files/cuda_device_array_gpu.h"
#include "tf_files/cuda_device_array.h"

int main(int argc, char *argv[]) {
    OpKernelContext opKernelContext;
    int num_split = 4;
    tensorflow::CudaDeviceArrayOnHost<float *> ptrs(&opKernelContext, num_split);
    ptrs.Init();
    return 0;
}
<commit_msg>compiles, doesnt link<commit_after>#include <iostream>
#include <functional>

typedef uint32_t uint32;
typedef int32_t int32;
typedef uint64_t uint64;
typedef int64_t int64;
typedef uint16_t uint16;
typedef int8_t int8;

// #define DT_INT8 int8_t
template<typename T>
class DT {
public:
    static const DT<T> get() {
        const DT<T> v;
        return v;
    }
};
#define DT_INT8 DT<int8_t>::get()

#define EIGEN_DEVICE_FUNC __attribute__((device))
#define EIGEN_STRONG_INLINE __inline__

#define TF_RETURN_IF_ERROR(x) x

class Status {
public:
    Status(int value) {
        this->value = value;
    }
    static Status OK() {
        return Status(0);
    }
    int value;
};

struct TensorShape {
    int64_t x;
};

class AllocatorAttributes {
public:
    void set_on_host(bool v) {
        this->on_host = v;
    }
    void set_gpu_compatible(bool v) {
        this->gpu_compatible = v;
    }
    bool on_host = false;
    bool gpu_compatible;
};

namespace perftools {
    namespace gputools {
        struct DeviceMemoryBase {
            float *mem;
            uint64_t size;
        };
    }
}

class Tensor {
public:
    template<typename T>
    Tensor flat() {
        std::cout << "Tensor::flat()" << std::endl;
        Tensor ret;
        return ret;
    }
    bool IsInitialized() const;
    float *data();
    // Tensor data() {
    //     std::cout << "Tensor::data()" << std::endl;
    //     return 0;
    // }
};

class TensorReference {
public:
    TensorReference(Tensor tensor) {
        std::cout << "TensorReference::TensorReference()" << std::endl;
    }
    void Unref() const;
};

class Stream;
class Device;

class OpDeviceContext {
public:
    Stream *stream();
};

class OpKernelContext {
public:
    Status allocate_temp(DT<int8_t> dt, TensorShape tensorShape, Tensor *tensor, AllocatorAttributes attrib) {
        std::cout << "OpKernelContext::allocate_temp(dt, shape, tensor, attrib)" << std::endl;
        return Status::OK();
    }
    Status allocate_temp(DT<int8_t> dt, TensorShape tensorShape, Tensor *tensor) {
        std::cout << "OpKernelContext::allocate_temp(dt, shape, tensor)" << std::endl;
        return Status::OK();
    }
    OpDeviceContext *op_device_context() {
        return &opDeviceContext;
    }
    Device *device();
    OpDeviceContext opDeviceContext;
};

class Stream {
public:
    void ThenMemcpy(perftools::gputools::DeviceMemoryBase *, float *, uint32_t total_bytes);
};
    // stream->ThenMemcpy(&output_values_base,
    //                    out_of_line_values_on_host_.flat<int8>().data(),
    //                    total_bytes_);

class EventMgr {
public:
    void ThenExecute(Stream *stream, std::function<void ()> fn);
};

class GpuDeviceInfo {
public:
    GpuDeviceInfo() {
        event_mgr = new EventMgr();
    }
    ~GpuDeviceInfo() {
        delete event_mgr;
    }
    EventMgr *event_mgr;
};

class Device {
public:
    GpuDeviceInfo *tensorflow_gpu_device_info();
};

#define TF_DISALLOW_COPY_AND_ASSIGN(x)

#include "tf_files/cuda_device_array_gpu.h"
#include "tf_files/cuda_device_array.h"

int main(int argc, char *argv[]) {
    // based loosely on tensorflow split_op.cc:
    OpKernelContext opKernelContext;
    int num_split = 4;
    tensorflow::CudaDeviceArrayOnHost<float *> ptrs(&opKernelContext, num_split);
    ptrs.Init();
    ptrs.Finalize();
    return 0;
}

    // for (int i = 0; i < num_split; ++i) {
    //   Tensor* result = nullptr;
    //   OP_REQUIRES_OK(context,
    //                  context->allocate_output(i, output_shape, &result));
    //   std::cout << "  SplitOpGPU::Compute() i=" << i << " result=" << result << " num_split=" << num_split << std::endl;
    //   std::cout << "  SplitOpGPU::Compute() result->flat<T>().data() " << result->flat<T>().data() << std::endl;
    //   ptrs.Set(i, result->flat<T>().data());
    // }
    // if (prefix_dim_size * split_dim_output_size * suffix_dim_size == 0) {
    //   return;
    // }
    // OP_REQUIRES_OK(context, ptrs.Finalize());

    // std::cout << "  SplitOpGPU::Compute() call .Run(eigen_device, data=" << input.flat<T>().data() <<
    //     " prefix_dim_size=" << prefix_dim_size << " split_dim_size=" << split_dim_size << " ptrs.data().size=" << ptrs.data().size << ")" << std::endl;
    // SplitOpGPULaunch<T>().Run(context->eigen_device<GPUDevice>(),
    //                           input.flat<T>().data(), prefix_dim_size,
    //                           split_dim_size, suffix_dim_size, ptrs.data());
<|endoftext|>