<commit_before>#include <ncurses.h>
#include <locale>
#include <chrono>
#include <thread>
#include <string>
#include <vector>
#include <regex>
#include <iostream>
#include <stdexcept>
#include <nanojson.hpp>
#include <cmdline.h>
using namespace std::literals::string_literals;
using std::string;
using std::tuple;
using std::vector;

bool is_utf8_first(uint8_t ch)
{
  return (ch & 0xC0) != 0x80 && (ch & 0xFE) != 0xFE && ((ch & 0x80) == 0 || (ch & 0xC0) == 0xC0);
}

bool is_utf8_cont(uint8_t ch) { return (ch & 0xC0) == 0x80; }

size_t get_utf8_char_length(uint8_t ch)
{
  if (!is_utf8_first(ch)) {
    throw std::runtime_error(string(__FUNCTION__) + ": the first byte is not UTF8");
  }

  for (int i = 0; i < 6; ++i) {
    if ((ch & (0x01 << (7 - i))) == 0) {
      return std::max(1, i);
    }
  }

  throw std::runtime_error(string(__FUNCTION__) + ": unreachable");
}

std::string get_utf8_char()
{
  std::array<uint8_t, 6> buf{0};

  auto ch0 = static_cast<uint8_t>(::getch() & 0x000000FF);
  size_t len = get_utf8_char_length(ch0);
  buf[0] = ch0;

  for (size_t i = 1; i < len; ++i) {
    auto ch = static_cast<uint8_t>(::getch() & 0x000000FF);
    if (!is_utf8_cont(ch)) {
      throw std::runtime_error(string(__FUNCTION__) + ": wrong byte exists");
    }
    buf[i] = ch;
  }

  return std::string(buf.data(), buf.data() + len);
}

void pop_back_utf8(std::string& str)
{
  if (str.empty())
    return;

  for (ssize_t len = str.size() - 1; len >= 0; --len) {
    if (!is_utf8_cont(str[len])) {
      str.resize(len);
      return;
    }
  }
}

enum class Key { Enter, Esc, Alt, Up, Down, Left, Right, Backspace, Char, Unknown };

class Event {
  Key key;
  int mod;
  std::string ch;

public:
  Event(Key key) : key{key}, mod{0}, ch{} {}
  Event(int mod) : key{Key::Alt}, mod{mod}, ch{} {}
  Event(std::string&& ch) : key{Key::Char}, mod{0}, ch{ch} {}

  std::string const& as_chars() const { return ch; }

  inline bool operator==(Key key) const { return this->key == key; }
};

Event poll_event()
{
  int ch = ::getch();
  if (ch == 10) {
    return Event{Key::Enter};
  }
  else if (ch == 27) {
    ::nodelay(stdscr, true);
    int ch = ::getch();
    if (ch == -1) {
      ::nodelay(stdscr, false);
      return Event{Key::Esc};
    }
    else {
      ::nodelay(stdscr, false);
      return Event{ch};
    }
  }
  else if (ch == KEY_UP) {
    return Event{Key::Up};
  }
  else if (ch == KEY_DOWN) {
    return Event{Key::Down};
  }
  else if (ch == KEY_LEFT) {
    return Event{Key::Left};
  }
  else if (ch == KEY_RIGHT) {
    return Event{Key::Right};
  }
  else if (ch == 127) {
    return Event{Key::Backspace};
  }
  else if (is_utf8_first(ch & 0xFF)) {
    ::ungetch(ch);
    auto ch = get_utf8_char();
    return Event{std::move(ch)};
  }
  else {
    return Event{Key::Unknown};
  }
}

// wrapper of Ncurses API.
class Ncurses {
public:
  Ncurses()
  {
    ::initscr();
    ::noecho();
    ::cbreak();
    ::keypad(stdscr, true);
    ::ESCDELAY = 25;

    start_color();
    ::init_pair(1, COLOR_WHITE, COLOR_BLACK);
    ::init_pair(2, COLOR_RED, COLOR_WHITE);
  }
  ~Ncurses() { ::endwin(); }
};

struct Config {
  std::string prompt;
  size_t y_offset;

public:
  void read_from(int argc, char const** argv) {
    static_cast<void>(argc);
    static_cast<void>(argv);
  }
};

// represents a instance of Coco client.
class Coco {
  enum class Status {
    Selected,
    Escaped,
    Continue,
  };

  Config config;

  std::vector<std::string> const& lines;
  std::vector<std::string> filtered;
  std::string query;
  size_t cursor = 0;
  size_t offset = 0;

public:
  Coco(Config const& config, std::vector<std::string> const& lines) : config(config), lines(lines), filtered(lines) {}

  std::tuple<bool, std::string> select_line(Ncurses ncurses);

private:
  void render_screen();
  Status handle_key_event(Event const& ev);
  void update_filter_list();
  std::vector<std::string> filter_by_regex(std::vector<std::string> const& lines) const;
};

void Coco::render_screen()
{
  std::string query_str = config.prompt + query;

  ::werase(stdscr);

  int width, height;
  getmaxyx(stdscr, height, width);
  static_cast<void>(height);

  for (size_t y = 0; y < std::min<size_t>(filtered.size() - offset, width - 1); ++y) {
    mvwaddstr(stdscr, y + 1, 0, filtered[y + offset].c_str());
    if (y == cursor) {
      attrset(COLOR_PAIR(2));
      mvwchgat(stdscr, y + 1, 0, -1, A_NORMAL, 2, nullptr);
      attrset(COLOR_PAIR(1));
    }
  }

  mvwaddstr(stdscr, 0, 0, query_str.c_str());

  ::wrefresh(stdscr);
}

auto Coco::handle_key_event(Event const& ev) -> Status
{
  if (ev == Key::Enter) {
    return filtered.size() > 0 ? Status::Selected : Status::Escaped;
  }
  else if (ev == Key::Esc) {
    return Status::Escaped;
  }
  else if (ev == Key::Up) {
    if (cursor == 0) {
      offset = std::max(0, (int)offset - 1);
    }
    else {
      cursor--;
    }
    return Status::Continue;
  }
  else if (ev == Key::Down) {
    int width, height;
    getmaxyx(stdscr, height, width);

    if (cursor == static_cast<size_t>(height - 1 - config.y_offset)) {
      offset = std::min<size_t>(offset + 1, std::max<int>(0, filtered.size() - height + config.y_offset));
    }
    else {
      cursor = std::min<size_t>(cursor + 1, std::min<size_t>(filtered.size() - offset, height - config.y_offset) - 1);
    }
    return Status::Continue;
  }
  else if (ev == Key::Backspace) {
    if (!query.empty()) {
      pop_back_utf8(query);
      update_filter_list();
    }
    return Status::Continue;
  }
  else if (ev == Key::Char) {
    query += ev.as_chars();
    update_filter_list();
    return Status::Continue;
  }
  else {
    return Status::Continue;
  }
}

std::tuple<bool, std::string> Coco::select_line(Ncurses ncurses)
{
  static_cast<void>(ncurses);

  render_screen();

  while (true) {
    Event ev = poll_event();

    auto result = handle_key_event(ev);
    if (result == Status::Selected) {
      return std::make_tuple(true, filtered[cursor]);
    }
    else if (result == Status::Escaped) {
      break;
    }
    render_screen();
  }

  return std::make_tuple(false, ""s);
}

void Coco::update_filter_list()
{
  filtered = filter_by_regex(lines);
  cursor = 0;
  offset = 0;
}

std::vector<std::string> Coco::filter_by_regex(std::vector<std::string> const& lines) const
{
  if (query.empty()) {
    return lines;
  }
  else {
    std::regex re(query);
    std::vector<std::string> filtered;
    for (auto&& line : lines) {
      if (std::regex_search(line, re)) {
        filtered.push_back(line);
      }
    }
    return filtered;
  }
}

int main(int argc, char const* argv[])
{
  std::setlocale(LC_ALL, "");

  try {
    // read lines from stdin.
    std::regex ansi(R"(\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K])");
    std::vector<std::string> lines;
    for (std::string line; std::getline(std::cin, line);) {
      lines.push_back(std::regex_replace(line, ansi, ""));
    }

    // Initialize Coco application.
    Config config;
    config.prompt = "QUERY> ";
    config.y_offset = 1;
    config.read_from(argc, argv);

    Coco coco{config, lines};

    // reopen file handlers of TTY for Ncurses session.
    freopen("/dev/tty", "r", stdin);
    freopen("/dev/tty", "w", stdout);

    // retrieve a selection from lines.
    // note that it ensures to shutdown ncurses when returned.
    bool is_selected;
    std::string selection;
    std::tie(is_selected, selection) = coco.select_line(Ncurses{});

    // show selected line.
    if (is_selected) {
      std::cout << selection << std::endl;
    }
    return 0;
  }
  catch (std::exception& e) {
    std::cerr << "An error is thrown: " << e.what() << std::endl;
    return -1;
  }
}
<commit_msg>encapsulate ncurse API<commit_after>#include <ncurses.h>
#include <locale>
#include <chrono>
#include <thread>
#include <string>
#include <vector>
#include <regex>
#include <iostream>
#include <stdexcept>
#include <functional>
#include <nanojson.hpp>
#include <cmdline.h>
using namespace std::literals::string_literals;
using std::string;
using std::tuple;
using std::vector;

bool is_utf8_first(uint8_t ch)
{
  return (ch & 0xC0) != 0x80 && (ch & 0xFE) != 0xFE && ((ch & 0x80) == 0 || (ch & 0xC0) == 0xC0);
}

bool is_utf8_cont(uint8_t ch) { return (ch & 0xC0) == 0x80; }

size_t get_utf8_char_length(uint8_t ch)
{
  if (!is_utf8_first(ch)) {
    throw std::runtime_error(string(__FUNCTION__) + ": the first byte is not UTF8");
  }

  for (int i = 0; i < 6; ++i) {
    if ((ch & (0x01 << (7 - i))) == 0) {
      return std::max(1, i);
    }
  }

  throw std::runtime_error(string(__FUNCTION__) + ": unreachable");
}

void pop_back_utf8(std::string& str)
{
  if (str.empty())
    return;

  for (ssize_t len = str.size() - 1; len >= 0; --len) {
    if (!is_utf8_cont(str[len])) {
      str.resize(len);
      return;
    }
  }
}

enum class Key { Enter, Esc, Alt, Up, Down, Left, Right, Backspace, Char, Unknown };

class Event {
  Key key;
  int mod;
  std::string ch;

public:
  Event(Key key) : key{key}, mod{0}, ch{} {}
  Event(int mod) : key{Key::Alt}, mod{mod}, ch{} {}
  Event(std::string&& ch) : key{Key::Char}, mod{0}, ch{ch} {}

  std::string const& as_chars() const { return ch; }

  inline bool operator==(Key key) const { return this->key == key; }
};

// wrapper of Ncurses API.
class Ncurses {
public:
  Ncurses()
  {
    ::initscr();
    ::noecho();
    ::cbreak();
    ::keypad(stdscr, true);
    ::ESCDELAY = 25;

    start_color();
    ::init_pair(1, COLOR_WHITE, COLOR_BLACK);
    ::init_pair(2, COLOR_RED, COLOR_WHITE);
  }

  ~Ncurses() { ::endwin(); }

  void erase() { ::werase(stdscr); }

  void refresh() { ::wrefresh(stdscr); }

  std::tuple<int, int> get_width_height() const
  {
    int width, height;
    getmaxyx(stdscr, height, width);
    return std::make_tuple(width, height);
  }

  void add_string(int x, int y, std::string const& text) { mvwaddstr(stdscr, y, x, text.c_str()); }

  void change_attr(int x, int y, int n, int col)
  {
    attrset(COLOR_PAIR(col));
    mvwchgat(stdscr, y, x, n, A_NORMAL, col, nullptr);
    attrset(COLOR_PAIR(1));
  }

  Event poll_event()
  {
    int ch = ::getch();
    if (ch == 10) {
      return Event{Key::Enter};
    }
    else if (ch == 27) {
      ::nodelay(stdscr, true);
      int ch = ::getch();
      if (ch == -1) {
        ::nodelay(stdscr, false);
        return Event{Key::Esc};
      }
      else {
        ::nodelay(stdscr, false);
        return Event{ch};
      }
    }
    else if (ch == KEY_UP) {
      return Event{Key::Up};
    }
    else if (ch == KEY_DOWN) {
      return Event{Key::Down};
    }
    else if (ch == KEY_LEFT) {
      return Event{Key::Left};
    }
    else if (ch == KEY_RIGHT) {
      return Event{Key::Right};
    }
    else if (ch == 127) {
      return Event{Key::Backspace};
    }
    else if (is_utf8_first(ch & 0xFF)) {
      ::ungetch(ch);
      auto ch = get_utf8_char();
      return Event{std::move(ch)};
    }
    else {
      return Event{Key::Unknown};
    }
  }

private:
  std::string get_utf8_char()
  {
    std::array<uint8_t, 6> buf{0};

    auto ch0 = static_cast<uint8_t>(::getch() & 0x000000FF);
    size_t len = get_utf8_char_length(ch0);
    buf[0] = ch0;

    for (size_t i = 1; i < len; ++i) {
      auto ch = static_cast<uint8_t>(::getch() & 0x000000FF);
      if (!is_utf8_cont(ch)) {
        throw std::runtime_error(string(__FUNCTION__) + ": wrong byte exists");
      }
      buf[i] = ch;
    }

    return std::string(buf.data(), buf.data() + len);
  }
};

struct Config {
  std::string prompt;
  size_t y_offset;

public:
  void read_from(int argc, char const** argv)
  {
    static_cast<void>(argc);
    static_cast<void>(argv);
  }
};

// represents a instance of Coco client.
class Coco {
  enum class Status {
    Selected,
    Escaped,
    Continue,
  };

  Config config;

  std::vector<std::string> const& lines;
  std::vector<std::string> filtered;
  std::string query;
  size_t cursor = 0;
  size_t offset = 0;

public:
  Coco(Config const& config, std::vector<std::string> const& lines) : config(config), lines(lines), filtered(lines) {}

  std::tuple<bool, std::string> select_line(Ncurses term)
  {
    render_screen(term);

    while (true) {
      Event ev = term.poll_event();
      auto result = handle_key_event(term, ev);

      if (result == Status::Selected) {
        return std::make_tuple(true, filtered[cursor]);
      }
      else if (result == Status::Escaped) {
        break;
      }

      render_screen(term);
    }

    return std::make_tuple(false, ""s);
  }

private:
  void render_screen(Ncurses& term)
  {
    std::string query_str = config.prompt + query;

    term.erase();

    int width;
    std::tie(width, std::ignore) = term.get_width_height();

    for (size_t y = 0; y < std::min<size_t>(filtered.size() - offset, width - 1); ++y) {
      term.add_string(0, y + 1, filtered[y + offset]);
      if (y == cursor) {
        term.change_attr(0, y + 1, -1, 2);
      }
    }

    term.add_string(0, 0, query_str);

    term.refresh();
  }

  Status handle_key_event(Ncurses& term, Event const& ev)
  {
    if (ev == Key::Enter) {
      return filtered.size() > 0 ? Status::Selected : Status::Escaped;
    }
    else if (ev == Key::Esc) {
      return Status::Escaped;
    }
    else if (ev == Key::Up) {
      if (cursor == 0) {
        offset = std::max(0, (int)offset - 1);
      }
      else {
        cursor--;
      }
      return Status::Continue;
    }
    else if (ev == Key::Down) {
      int height;
      std::tie(std::ignore, height) = term.get_width_height();

      if (cursor == static_cast<size_t>(height - 1 - config.y_offset)) {
        offset = std::min<size_t>(offset + 1, std::max<int>(0, filtered.size() - height + config.y_offset));
      }
      else {
        cursor = std::min<size_t>(cursor + 1, std::min<size_t>(filtered.size() - offset, height - config.y_offset) - 1);
      }
      return Status::Continue;
    }
    else if (ev == Key::Backspace) {
      if (!query.empty()) {
        pop_back_utf8(query);
        update_filter_list();
      }
      return Status::Continue;
    }
    else if (ev == Key::Char) {
      query += ev.as_chars();
      update_filter_list();
      return Status::Continue;
    }
    else {
      return Status::Continue;
    }
  }

  void update_filter_list()
  {
    filtered = filter_by_regex(lines);
    cursor = 0;
    offset = 0;
  }

  std::vector<std::string> filter_by_regex(std::vector<std::string> const& lines) const
  {
    if (query.empty()) {
      return lines;
    }
    else {
      std::regex re(query);
      std::vector<std::string> filtered;
      for (auto&& line : lines) {
        if (std::regex_search(line, re)) {
          filtered.push_back(line);
        }
      }
      return filtered;
    }
  }
};

int main(int argc, char const* argv[])
{
  std::setlocale(LC_ALL, "");

  try {
    // read lines from stdin.
    std::regex ansi(R"(\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K])");
    std::vector<std::string> lines;
    for (std::string line; std::getline(std::cin, line);) {
      lines.push_back(std::regex_replace(line, ansi, ""));
    }

    // Initialize Coco application.
    Config config;
    config.prompt = "QUERY> ";
    config.y_offset = 1;
    config.read_from(argc, argv);

    Coco coco{config, lines};

    // reopen file handlers of TTY for Ncurses session.
    freopen("/dev/tty", "r", stdin);
    freopen("/dev/tty", "w", stdout);

    // retrieve a selection from lines.
    // note that it ensures to shutdown ncurses when returned.
    bool is_selected;
    std::string selection;
    std::tie(is_selected, selection) = coco.select_line(Ncurses{});

    // show selected line.
    if (is_selected) {
      std::cout << selection << std::endl;
    }
    return 0;
  }
  catch (std::exception& e) {
    std::cerr << "An error is thrown: " << e.what() << std::endl;
    return -1;
  }
}
<|endoftext|>


<commit_before><commit_msg>Add alignment requirement to char buffer<commit_after><|endoftext|>


<commit_before><commit_msg>Cartesian::to_string prints the scaled cartesian<commit_after><|endoftext|>


<commit_before>/* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of NVIDIA CORPORATION nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <stdlib.h>

#include <boost/serialization/shared_ptr.hpp>

#include "model/model-base.hpp"
#include "model/arithmetic.hpp"
#include "model/topology.hpp"
#include "mapping/mapping.hpp"
#include "loop-analysis/nest-analysis.hpp"
#include "compound-config/compound-config.hpp"

namespace model
{

class Engine : public Module
{
 public:
  struct Specs
  {
    Topology::Specs topology;
  };

 private:
  // Specs.
  Specs specs_;

  // Organization.
  Topology topology_;

  // Utilities.
  analysis::NestAnalysis nest_analysis_;

  // Serialization.
  friend class boost::serialization::access;
  template <class Archive>
  void serialize(Archive& ar, const unsigned int version=0)
  {
    if (version == 0)
    {
      ar& BOOST_SERIALIZATION_NVP(topology_);
    }
  }

 public:

  // The hierarchical ParseSpecs functions are static and do not
  // affect the internal specs_ data structure, which is set by
  // the dynamic Spec() call later.
  static Specs ParseSpecs(config::CompoundConfigNode setting)
  {
    Specs specs;
    std::string version;

    if (!setting.exists("version") || (setting.lookupValue("version", version) && version != "0.2")) {
      // format used in the ISPASS paper
      // std::cout << "ParseSpecs" << std::endl;
      auto arithmetic = setting.lookup("arithmetic");
      auto topology = setting.lookup("storage");
      specs.topology = Topology::ParseSpecs(topology, arithmetic);
    } else {
      // format used in Accelergy v0.2
      // std::cout << "ParseTreeSpecs" << std::endl;
      specs.topology = Topology::ParseTreeSpecs(setting);
    }

    return specs;
  }

  void Spec(Specs specs)
  {
    specs_ = specs;
    topology_.Spec(specs.topology);
    is_specced_ = true;
  }

  const Topology& GetTopology() const { return topology_; }

  std::vector<EvalStatus> PreEvaluationCheck(const Mapping& mapping, problem::Workload& workload, bool break_on_failure = true)
  {
    nest_analysis_.Init(&workload, &mapping.loop_nest);
    return topology_.PreEvaluationCheck(mapping, &nest_analysis_, break_on_failure);
  }

  std::vector<EvalStatus> Evaluate(Mapping& mapping, problem::Workload& workload, bool break_on_failure = true)
  {
    nest_analysis_.Init(&workload, &mapping.loop_nest);

    auto eval_status = topology_.Evaluate(mapping, &nest_analysis_, workload, break_on_failure);

    is_evaluated_ = std::accumulate(eval_status.begin(), eval_status.end(), true,
                                    [](bool cur, const EvalStatus& status)
                                    { return cur && status.success; });

    return eval_status;
  }

  double Energy() const
  {
    return topology_.Energy();
  }

  double Area() const
  {
    return topology_.Area();
  }

  std::uint64_t Cycles() const
  {
    return topology_.Cycles();
  }

  double Utilization() const
  {
    return topology_.Utilization();
  }

  friend std::ostream& operator << (std::ostream& out, Engine& engine)
  {
    out << engine.topology_;
    return out;
  }
};

} // namespace model
<commit_msg>[model/engine.hpp] accept v0.3 arch<commit_after>/* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of NVIDIA CORPORATION nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <stdlib.h>

#include <boost/serialization/shared_ptr.hpp>

#include "model/model-base.hpp"
#include "model/arithmetic.hpp"
#include "model/topology.hpp"
#include "mapping/mapping.hpp"
#include "loop-analysis/nest-analysis.hpp"
#include "compound-config/compound-config.hpp"

namespace model
{

class Engine : public Module
{
 public:
  struct Specs
  {
    Topology::Specs topology;
  };

 private:
  // Specs.
  Specs specs_;

  // Organization.
  Topology topology_;

  // Utilities.
  analysis::NestAnalysis nest_analysis_;

  // Serialization.
  friend class boost::serialization::access;
  template <class Archive>
  void serialize(Archive& ar, const unsigned int version=0)
  {
    if (version == 0)
    {
      ar& BOOST_SERIALIZATION_NVP(topology_);
    }
  }

 public:

  // The hierarchical ParseSpecs functions are static and do not
  // affect the internal specs_ data structure, which is set by
  // the dynamic Spec() call later.
  static Specs ParseSpecs(config::CompoundConfigNode setting)
  {
    Specs specs;
    std::string version;

    if (!setting.exists("version") || (setting.lookupValue("version", version) && (version != "0.2" && version != "0.3"))) {
      // format used in the ISPASS paper
      // std::cout << "ParseSpecs" << std::endl;
      auto arithmetic = setting.lookup("arithmetic");
      auto topology = setting.lookup("storage");
      specs.topology = Topology::ParseSpecs(topology, arithmetic);
    } else {
      // format used in Accelergy v0.2/v0.3
      // std::cout << "ParseTreeSpecs" << std::endl;
      specs.topology = Topology::ParseTreeSpecs(setting);
    }

    return specs;
  }

  void Spec(Specs specs)
  {
    specs_ = specs;
    topology_.Spec(specs.topology);
    is_specced_ = true;
  }

  const Topology& GetTopology() const { return topology_; }

  std::vector<EvalStatus> PreEvaluationCheck(const Mapping& mapping, problem::Workload& workload, bool break_on_failure = true)
  {
    nest_analysis_.Init(&workload, &mapping.loop_nest);
    return topology_.PreEvaluationCheck(mapping, &nest_analysis_, break_on_failure);
  }

  std::vector<EvalStatus> Evaluate(Mapping& mapping, problem::Workload& workload, bool break_on_failure = true)
  {
    nest_analysis_.Init(&workload, &mapping.loop_nest);

    auto eval_status = topology_.Evaluate(mapping, &nest_analysis_, workload, break_on_failure);

    is_evaluated_ = std::accumulate(eval_status.begin(), eval_status.end(), true,
                                    [](bool cur, const EvalStatus& status)
                                    { return cur && status.success; });

    return eval_status;
  }

  double Energy() const
  {
    return topology_.Energy();
  }

  double Area() const
  {
    return topology_.Area();
  }

  std::uint64_t Cycles() const
  {
    return topology_.Cycles();
  }

  double Utilization() const
  {
    return topology_.Utilization();
  }

  friend std::ostream& operator << (std::ostream& out, Engine& engine)
  {
    out << engine.topology_;
    return out;
  }
};

} // namespace model
<|endoftext|>


<commit_before><commit_msg>Don't light up form fields we aren't filling, and don't light up the submit button.<commit_after><|endoftext|>


<commit_before>/**
 * Copyright 2014 Truphone
 */
#include "XmppDisconnectCommand.h"

#include <QString>
#include <QObject>

#include "Connection.h"
#include "XmppResourceStore.h"

namespace truphone
{
namespace test
{
namespace cascades
{
    const QString XMPPDisconnectCommand::CMD_NAME = "xmppDisconnect";

    XMPPDisconnectCommand::XMPPDisconnectCommand(Connection * const socket,
                                             QObject* parent)
        : Command(parent),
          client(socket)
    {
    }

    XMPPDisconnectCommand::~XMPPDisconnectCommand()
    {
    }

    bool XMPPDisconnectCommand::executeCommand(QStringList * const arguments)
    {
        bool ret = false;
        if (arguments->length() not_eq 1)
        {
            this->client->write("ERROR: xmppDisconnect <resource>\r\n");
        }
        else
        {
            QXmppClient * const client =
                    XMPPResourceStore::instance()->getFromStore(arguments->first());
            arguments->removeFirst();
            if (client)
            {
                client->disconnectFromServer();
                XMPPResourceStore::instance()->removeFromStore(arguments->first());
                ret = true;
            }
            else
            {
                this->client->write("ERROR: Unknown resource\r\n");
            }
        }
        return ret;
    }

    void XMPPDisconnectCommand::showHelp()
    {
        this->client->write("> xmppDisconnect <resource>\r\n");
        this->client->write("Disconnect a resource's connection.\r\n");
    }
}  // namespace cascades
}  // namespace test
}  // namespace truphone
<commit_msg>Fix ASSERT in Disconnect.<commit_after>/**
 * Copyright 2014 Truphone
 */
#include "XmppDisconnectCommand.h"

#include <QString>
#include <QObject>

#include "Connection.h"
#include "XmppResourceStore.h"

namespace truphone
{
namespace test
{
namespace cascades
{
    const QString XMPPDisconnectCommand::CMD_NAME = "xmppDisconnect";

    XMPPDisconnectCommand::XMPPDisconnectCommand(Connection * const socket,
                                             QObject* parent)
        : Command(parent),
          client(socket)
    {
    }

    XMPPDisconnectCommand::~XMPPDisconnectCommand()
    {
    }

    bool XMPPDisconnectCommand::executeCommand(QStringList * const arguments)
    {
        bool ret = false;
        if (arguments->length() not_eq 1)
        {
            this->client->write("ERROR: xmppDisconnect <resource>\r\n");
        }
        else
        {
            const QString resource = arguments->first();
            QXmppClient * const client =
                    XMPPResourceStore::instance()->getFromStore(resource);
            arguments->removeFirst();
            if (client)
            {
                client->disconnectFromServer();
                XMPPResourceStore::instance()->removeFromStore(resource);
                ret = true;
            }
            else
            {
                this->client->write("ERROR: Unknown resource\r\n");
            }
        }
        return ret;
    }

    void XMPPDisconnectCommand::showHelp()
    {
        this->client->write("> xmppDisconnect <resource>\r\n");
        this->client->write("Disconnect a resource's connection.\r\n");
    }
}  // namespace cascades
}  // namespace test
}  // namespace truphone
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 "base/file_path.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/ui/npapi_test_helper.h"
#include "chrome/test/ui_test_utils.h"

#if defined(OS_WIN)
static const char kPepperTestPluginName[] = "npapi_pepper_test_plugin.dll";
#elif defined(OS_MACOSX)
static const char kPepperTestPluginName[] = "npapi_pepper_test_plugin.plugin";
#elif defined(OS_LINUX)
static const char kPepperTestPluginName[] = "libnpapi_pepper_test_plugin.so";
#endif

using npapi_test::kTestCompleteCookie;
using npapi_test::kTestCompleteSuccess;

// Helper class pepper NPAPI tests.
class PepperTester : public NPAPITesterBase {
 protected:
  PepperTester() : NPAPITesterBase(kPepperTestPluginName) {}

  virtual void SetUp() {
    // TODO(alokp): Remove no-sandbox flag once gpu plugin can run in sandbox.
    launch_arguments_.AppendSwitch(switches::kNoSandbox);
    launch_arguments_.AppendSwitch(switches::kInternalPepper);
    launch_arguments_.AppendSwitch(switches::kEnableGPUPlugin);
    NPAPITesterBase::SetUp();
  }
};

// Test that a pepper 3d plugin loads and renders.
// TODO(alokp): Enable the test after making sure it works on all platforms
// and buildbots have OpenGL support.
#if defined(OS_WIN)
TEST_F(PepperTester, FAILS_Pepper3D) {
  const FilePath dir(FILE_PATH_LITERAL("pepper"));
  const FilePath file(FILE_PATH_LITERAL("pepper_3d.html"));
  GURL url = ui_test_utils::GetTestUrl(dir, file);
  ASSERT_NO_FATAL_FAILURE(NavigateToURL(url));
  WaitForFinish("pepper_3d", "1", url,
                kTestCompleteCookie, kTestCompleteSuccess,
                action_max_timeout_ms());
}
#endif
<commit_msg>Enabled pepper 3d test after fixing glsl translator. TBR=gman@chromium.org Review URL: http://codereview.chromium.org/2286001<commit_after>// Copyright (c) 2010 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 "base/file_path.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/ui/npapi_test_helper.h"
#include "chrome/test/ui_test_utils.h"

#if defined(OS_WIN)
static const char kPepperTestPluginName[] = "npapi_pepper_test_plugin.dll";
#elif defined(OS_MACOSX)
static const char kPepperTestPluginName[] = "npapi_pepper_test_plugin.plugin";
#elif defined(OS_LINUX)
static const char kPepperTestPluginName[] = "libnpapi_pepper_test_plugin.so";
#endif

using npapi_test::kTestCompleteCookie;
using npapi_test::kTestCompleteSuccess;

// Helper class pepper NPAPI tests.
class PepperTester : public NPAPITesterBase {
 protected:
  PepperTester() : NPAPITesterBase(kPepperTestPluginName) {}

  virtual void SetUp() {
    // TODO(alokp): Remove no-sandbox flag once gpu plugin can run in sandbox.
    launch_arguments_.AppendSwitch(switches::kNoSandbox);
    launch_arguments_.AppendSwitch(switches::kInternalPepper);
    launch_arguments_.AppendSwitch(switches::kEnableGPUPlugin);
    NPAPITesterBase::SetUp();
  }
};

// Test that a pepper 3d plugin loads and renders.
// TODO(alokp): Enable the test after making sure it works on all platforms
// and buildbots have OpenGL support.
#if defined(OS_WIN)
TEST_F(PepperTester, Pepper3D) {
  const FilePath dir(FILE_PATH_LITERAL("pepper"));
  const FilePath file(FILE_PATH_LITERAL("pepper_3d.html"));
  GURL url = ui_test_utils::GetTestUrl(dir, file);
  ASSERT_NO_FATAL_FAILURE(NavigateToURL(url));
  WaitForFinish("pepper_3d", "1", url,
                kTestCompleteCookie, kTestCompleteSuccess,
                action_max_timeout_ms());
}
#endif
<|endoftext|>


<commit_before>// This file is part of the hdf5_handler implementing for the CF-compliant
// Copyright (c) 2011-2016 The HDF Group, Inc. and OPeNDAP, Inc.
//
// This is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 2.1 of the License, or (at your
// option) any later version.
//
// This software is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
// You can contact The HDF Group, Inc. at 1800 South Oak Street,
// Suite 203, Champaign, IL 61820

/////////////////////////////////////////////////////////////////////////////
/// \file HDF5CFModule.cc
/// \brief This file includes the implementation to distinguish the different categories of HDF5 products for the CF option
///
///
/// \author Kent Yang <myang6@hdfgroup.org>
///
/// Copyright (C) 2011-2016 The HDF Group
///
/// All rights reserved.

#include <InternalErr.h>
#include "HDF5CFModule.h"

using namespace libdap;

H5CFModule check_module(hid_t fileid) {

    if (true == check_eos5(fileid))
        return HDF_EOS5;
    else if(true == check_jpss(fileid))
        return HDF5_JPSS;
    else
        return HDF5_GENERAL;

}

bool check_eos5(hid_t file_id) {

    // check HDF-EOS5 group
    string eos5_check_group = "/HDFEOS INFORMATION";
    string eos5_check_attr  = "HDFEOSVersion";
    string eos5_dataset     = "StructMetadata.0";
    htri_t has_eos_group    = -1;
    bool   eos5_module_fields    = true;

    has_eos_group = H5Lexists(file_id,eos5_check_group.c_str(),H5P_DEFAULT);

    if (has_eos_group > 0){

        hid_t eos_group_id = -1;
        htri_t has_eos_attr = -1;

        // Open the group
        if((eos_group_id = H5Gopen(file_id, eos5_check_group.c_str(),H5P_DEFAULT))<0) {

            string msg = "cannot open the HDF5 group  ";
            msg += eos5_check_group;
//            H5Fclose(file_id);
            throw InternalErr(__FILE__, __LINE__, msg);
        }

        // check the existence of the EOS5 attribute
        has_eos_attr = H5Aexists(eos_group_id, eos5_check_attr.c_str());

        if (has_eos_attr >0) {

            // All HDF-EOS5 conditions are fulfilled, return true;
            // Otherwise, return false or throw an error.
            htri_t has_eos_dset = -1;

            // check the existence of the EOS5 dataset
            has_eos_dset = H5Lexists(eos_group_id,eos5_dataset.c_str(),H5P_DEFAULT);
            if (has_eos_dset >0) {
                // We still need to check if there are non-EOS5 fields that the
                // current HDF-EOS5 module cannot handle.
                // If yes, the file cannot be handled by the HDF-EOS5 module since
                // the current module is very tight to the HDF-EOS5 model.
                // We will treat this file as a general HDF5 file.
                eos5_module_fields = check_eos5_module_fields(file_id);
                return eos5_module_fields;
            }
            else if(0 == has_eos_dset)
                return false;
            else {
                string msg = "Fail to determine if the HDF5 dataset  ";
                msg += eos5_dataset;
                msg +=" exists ";
                H5Gclose(eos_group_id);
//                H5Fclose(file_id);
                throw InternalErr(__FILE__, __LINE__, msg);
            }
        }
        else if(0 == has_eos_attr)
                return false;
        else {
            string msg = "Fail to determine if the HDF5 attribute  ";
            msg += eos5_check_attr;
            msg +=" exists ";
            H5Gclose(eos_group_id);
 //           H5Fclose(file_id);
            throw InternalErr(__FILE__, __LINE__, msg);
        }
    }
    else if( 0 == has_eos_group) {
        return false;
    }
    else {
        string msg = "Fail to determine if the HDF5 group  ";
        msg += eos5_check_group;
        msg +=" exists ";
//        H5Fclose(file_id);
        throw InternalErr(__FILE__, __LINE__, msg);
    }
}

bool check_jpss(hid_t fileid) {
  // Currently not supported.
  return false;
}

bool check_eos5_module_fields(hid_t fileid){

    bool ret_value = true;
    string eos5_swath_group = "/HDFEOS/SWATHS";
    string eos5_grid_group  = "/HDFEOS/GRIDS";
    string eos5_zas_group   = "/HDFEOS/ZAS";
    bool swath_unsupported_dset = false;
    bool grid_unsupported_dset  = false;
    bool zas_unsupported_dset   = false;
    if(H5Lexists(fileid,eos5_swath_group.c_str(),H5P_DEFAULT)>0)
        swath_unsupported_dset = grp_has_dset(fileid,eos5_swath_group);
    if(swath_unsupported_dset == true)
        return false;
    else {
        if(H5Lexists(fileid,eos5_grid_group.c_str(),H5P_DEFAULT)>0)
            grid_unsupported_dset = grp_has_dset(fileid,eos5_grid_group);
        if(grid_unsupported_dset == true)
            return false;
        else {
            if(H5Lexists(fileid,eos5_zas_group.c_str(),H5P_DEFAULT)>0)
                zas_unsupported_dset = grp_has_dset(fileid,eos5_zas_group);
            if(zas_unsupported_dset == true)
                return false;
        }
    }

    return ret_value;
}

bool grp_has_dset(hid_t fileid, const string & grp_path ) {

    bool ret_value = false;
    H5O_info_t oinfo;
    if(H5Oget_info_by_name(fileid, grp_path.c_str(),&oinfo,H5P_DEFAULT)<0) {
        string msg = "Fail to obtain the HDF5 object information by name for the object.";
        msg += grp_path;
        throw InternalErr(__FILE__, __LINE__, msg);
    }

    unsigned nelems = oinfo.rc;

    for (unsigned i = 0; i<nelems;i++) {

        H5O_info_t s_oinfo;
        if(H5Oget_info_by_idx(fileid, grp_path.c_str(), H5_INDEX_NAME, H5_ITER_NATIVE,
                                            i, &s_oinfo, H5P_DEFAULT)<0) {
            string msg = "Error obtaining the info for the group";
            msg += grp_path;
            throw InternalErr(__FILE__, __LINE__, msg);
        }
        if(s_oinfo.type == H5O_TYPE_DATASET) {
            ret_value = true;
            break;
        }
    }
    return ret_value;
}
<commit_msg>HFVHANDLER-239, using H5Gget_info to check if the member is an HDF5 dataset. The DAp output can be plotted by Panoply. Dimensions and coordinates are all right.<commit_after>// This file is part of the hdf5_handler implementing for the CF-compliant
// Copyright (c) 2011-2016 The HDF Group, Inc. and OPeNDAP, Inc.
//
// This is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 2.1 of the License, or (at your
// option) any later version.
//
// This software is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
// You can contact The HDF Group, Inc. at 1800 South Oak Street,
// Suite 203, Champaign, IL 61820

/////////////////////////////////////////////////////////////////////////////
/// \file HDF5CFModule.cc
/// \brief This file includes the implementation to distinguish the different categories of HDF5 products for the CF option
///
///
/// \author Kent Yang <myang6@hdfgroup.org>
///
/// Copyright (C) 2011-2016 The HDF Group
///
/// All rights reserved.

#include <InternalErr.h>
#include "HDF5CFModule.h"

using namespace libdap;

H5CFModule check_module(hid_t fileid) {

    if (true == check_eos5(fileid))
        return HDF_EOS5;
    else if(true == check_jpss(fileid))
        return HDF5_JPSS;
    else
        return HDF5_GENERAL;

}

bool check_eos5(hid_t file_id) {

    // check HDF-EOS5 group
    string eos5_check_group = "/HDFEOS INFORMATION";
    string eos5_check_attr  = "HDFEOSVersion";
    string eos5_dataset     = "StructMetadata.0";
    htri_t has_eos_group    = -1;
    bool   eos5_module_fields    = true;

    has_eos_group = H5Lexists(file_id,eos5_check_group.c_str(),H5P_DEFAULT);

    if (has_eos_group > 0){

        hid_t eos_group_id = -1;
        htri_t has_eos_attr = -1;

        // Open the group
        if((eos_group_id = H5Gopen(file_id, eos5_check_group.c_str(),H5P_DEFAULT))<0) {

            string msg = "cannot open the HDF5 group  ";
            msg += eos5_check_group;
//            H5Fclose(file_id);
            throw InternalErr(__FILE__, __LINE__, msg);
        }

        // check the existence of the EOS5 attribute
        has_eos_attr = H5Aexists(eos_group_id, eos5_check_attr.c_str());

        if (has_eos_attr >0) {

            // All HDF-EOS5 conditions are fulfilled, return true;
            // Otherwise, return false or throw an error.
            htri_t has_eos_dset = -1;

            // check the existence of the EOS5 dataset
            has_eos_dset = H5Lexists(eos_group_id,eos5_dataset.c_str(),H5P_DEFAULT);
            if (has_eos_dset >0) {
                // We still need to check if there are non-EOS5 fields that the
                // current HDF-EOS5 module cannot handle.
                // If yes, the file cannot be handled by the HDF-EOS5 module since
                // the current module is very tight to the HDF-EOS5 model.
                // We will treat this file as a general HDF5 file.
                eos5_module_fields = check_eos5_module_fields(file_id);
                return eos5_module_fields;
            }
            else if(0 == has_eos_dset)
                return false;
            else {
                string msg = "Fail to determine if the HDF5 dataset  ";
                msg += eos5_dataset;
                msg +=" exists ";
                H5Gclose(eos_group_id);
//                H5Fclose(file_id);
                throw InternalErr(__FILE__, __LINE__, msg);
            }
        }
        else if(0 == has_eos_attr)
                return false;
        else {
            string msg = "Fail to determine if the HDF5 attribute  ";
            msg += eos5_check_attr;
            msg +=" exists ";
            H5Gclose(eos_group_id);
 //           H5Fclose(file_id);
            throw InternalErr(__FILE__, __LINE__, msg);
        }
    }
    else if( 0 == has_eos_group) {
        return false;
    }
    else {
        string msg = "Fail to determine if the HDF5 group  ";
        msg += eos5_check_group;
        msg +=" exists ";
//        H5Fclose(file_id);
        throw InternalErr(__FILE__, __LINE__, msg);
    }
}

bool check_jpss(hid_t fileid) {
  // Currently not supported.
  return false;
}

bool check_eos5_module_fields(hid_t fileid){

    bool ret_value = true;
    string eos5_swath_group = "/HDFEOS/SWATHS";
    string eos5_grid_group  = "/HDFEOS/GRIDS";
    string eos5_zas_group   = "/HDFEOS/ZAS";
    bool swath_unsupported_dset = false;
    bool grid_unsupported_dset  = false;
    bool zas_unsupported_dset   = false;
    if(H5Lexists(fileid,eos5_swath_group.c_str(),H5P_DEFAULT)>0)
        swath_unsupported_dset = grp_has_dset(fileid,eos5_swath_group);
    if(swath_unsupported_dset == true)
        return false;
    else {
        if(H5Lexists(fileid,eos5_grid_group.c_str(),H5P_DEFAULT)>0)
            grid_unsupported_dset = grp_has_dset(fileid,eos5_grid_group);
        if(grid_unsupported_dset == true)
            return false;
        else {
            if(H5Lexists(fileid,eos5_zas_group.c_str(),H5P_DEFAULT)>0)
                zas_unsupported_dset = grp_has_dset(fileid,eos5_zas_group);
            if(zas_unsupported_dset == true)
                return false;
        }
    }

    return ret_value;
}

bool grp_has_dset(hid_t fileid, const string & grp_path ) {

    bool ret_value = false;
    hid_t pid = -1;
    if((pid = H5Gopen(fileid,grp_path.c_str(),H5P_DEFAULT))<0){
        string msg = "Unable to open the HDF5 group ";
        msg += grp_path;
        throw InternalErr(__FILE__, __LINE__, msg);
    }

    H5G_info_t g_info;

    if (H5Gget_info(pid, &g_info) < 0) {
        H5Gclose(pid);
        string msg = "Unable to obtain the HDF5 group info. for ";
        msg += grp_path;
        throw InternalErr(__FILE__, __LINE__, msg);
    }

    hsize_t nelems = g_info.nlinks;

    for (hsize_t i = 0; i < nelems; i++) {

        // Obtain the object type
        H5O_info_t oinfo;
        if (H5Oget_info_by_idx(pid, ".", H5_INDEX_NAME, H5_ITER_NATIVE, i, &oinfo, H5P_DEFAULT) < 0) {
            string msg = "Cannot obtain the object info for the group";
            msg += grp_path;
            throw InternalErr(__FILE__, __LINE__, msg);
        }

        if(oinfo.type == H5O_TYPE_DATASET) {
            ret_value = true;
            break;
        }
    }
    H5Gclose(pid);
    return ret_value;
}
<|endoftext|>


<commit_before>// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

#include "Texture.h"

#include <nvmath/Vector.h>
#include <nvmath/Matrix.h>

#include <nvimage/Filter.h>

using namespace nv;
using namespace nvtt;

namespace
{
	// 1 -> 1, 2 -> 2, 3 -> 2, 4 -> 4, 5 -> 4, ...
	static uint previousPowerOfTwo(const uint v)
	{
		return nextPowerOfTwo(v + 1) / 2;
	}

	static uint nearestPowerOfTwo(const uint v)
	{
		const uint np2 = nextPowerOfTwo(v);
		const uint pp2 = previousPowerOfTwo(v);

		if (np2 - v <= v - pp2)
		{
			return np2;
		}
		else
		{
			return pp2;
		}
	}
}

Texture::Texture() : m(new Texture::Private())
{
}

Texture::Texture(const Texture & tex) : m(tex.m)
{
	m->addRef();
}

Texture::~Texture()
{
	m->release();
	m = NULL;
}

void Texture::operator=(const Texture & tex)
{
	tex.m->addRef();
	m = tex.m;
	m->release();
}

void Texture::detach()
{
	if (m->refCount() > 1)
	{
		m = new Texture::Private(*m);
		m->addRef();
		nvDebugCheck(m->refCount() == 1);
	}
}

void Texture::setType(TextureType type)
{
	if (m->type != type)
	{
		detach();
		m->type = type;
	}
}

void Texture::setWrapMode(WrapMode wrapMode)
{
	if (m->wrapMode != wrapMode)
	{
		detach();
		m->wrapMode = wrapMode;
	}
}

void Texture::setAlphaMode(AlphaMode alphaMode)
{
	if (m->alphaMode != alphaMode)
	{
		detach();
		m->alphaMode = alphaMode;
	}
}

void Texture::setNormalMap(bool isNormalMap)
{
	if (m->isNormalMap != isNormalMap)
	{
		detach();
		m->isNormalMap = isNormalMap;
	}
}

bool Texture::load(const char * fileName)
{
	// @@ Not implemented.
	return false;
}

void Texture::setTexture2D(InputFormat format, int w, int h, int idx, void * data)
{
	// @@ Not implemented.
}

void Texture::resize(int w, int h, ResizeFilter filter)
{
	if (m->imageArray.count() > 0)
	{
		if (w == m->imageArray[0].width() && h == m->imageArray[0].height()) return;
	}

	// @TODO: if cubemap, make sure w == h.

	detach();

	foreach(i, m->imageArray)
	{
		FloatImage::WrapMode wrapMode = (FloatImage::WrapMode)m->wrapMode;

		if (m->alphaMode == AlphaMode_Transparency)
		{
			if (filter == ResizeFilter_Box)
			{
				BoxFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode, 3);
			}
			else if (filter == ResizeFilter_Triangle)
			{
				TriangleFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode, 3);
			}
			else if (filter == ResizeFilter_Kaiser)
			{
				//KaiserFilter filter(inputOptions.kaiserWidth);
				//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
				KaiserFilter filter(3);
				m->imageArray[i].resize(filter, w, h, wrapMode, 3);
			}
			else //if (filter == ResizeFilter_Mitchell)
			{
				nvDebugCheck(filter == ResizeFilter_Mitchell);
				MitchellFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode, 3);
			}
		}
		else
		{
			if (filter == ResizeFilter_Box)
			{
				BoxFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode);
			}
			else if (filter == ResizeFilter_Triangle)
			{
				TriangleFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode);
			}
			else if (filter == ResizeFilter_Kaiser)
			{
				//KaiserFilter filter(inputOptions.kaiserWidth);
				//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
				KaiserFilter filter(3);
				m->imageArray[i].resize(filter, w, h, wrapMode);
			}
			else //if (filter == ResizeFilter_Mitchell)
			{
				nvDebugCheck(filter == ResizeFilter_Mitchell);
				MitchellFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode);
			}
		}
	}
}

void Texture::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
{
	if (m->imageArray.count() > 0)
	{
		int w = m->imageArray[0].width();
		int h = m->imageArray[0].height();

		nvDebugCheck(w > 0);
		nvDebugCheck(h > 0);

		if (roundMode != RoundMode_None)
		{
			// rounded max extent should never be higher than original max extent.
			maxExtent = previousPowerOfTwo(maxExtent);
		}

		// Scale extents without changing aspect ratio.
		uint maxwh = max(w, h);
		if (maxExtent != 0 && maxwh > maxExtent)
		{
			w = max((w * maxExtent) / maxwh, 1U);
			h = max((h * maxExtent) / maxwh, 1U);
		}

		// Round to power of two.
		if (roundMode == RoundMode_ToNextPowerOfTwo)
		{
			w = nextPowerOfTwo(w);
			h = nextPowerOfTwo(h);
		}
		else if (roundMode == RoundMode_ToNearestPowerOfTwo)
		{
			w = nearestPowerOfTwo(w);
			h = nearestPowerOfTwo(h);
		}
		else if (roundMode == RoundMode_ToPreviousPowerOfTwo)
		{
			w = previousPowerOfTwo(w);
			h = previousPowerOfTwo(h);
		}

		resize(w, h, filter);
	}
}

bool Texture::buildNextMipmap(MipmapFilter filter)
{
	detach();

	foreach(i, m->imageArray)
	{
		FloatImage::WrapMode wrapMode = (FloatImage::WrapMode)m->wrapMode;

		if (m->alphaMode == AlphaMode_Transparency)
		{
			if (filter == MipmapFilter_Box)
			{
				BoxFilter filter;
				m->imageArray[i].downSample(filter, wrapMode, 3);
			}
			else if (filter == MipmapFilter_Triangle)
			{
				TriangleFilter filter;
				m->imageArray[i].downSample(filter, wrapMode, 3);
			}
			else if (filter == MipmapFilter_Kaiser)
			{
				nvDebugCheck(filter == MipmapFilter_Kaiser);
				//KaiserFilter filter(inputOptions.kaiserWidth);
				//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
				KaiserFilter filter(3);
				m->imageArray[i].downSample(filter, wrapMode, 3);
			}
		}
		else
		{
			if (filter == MipmapFilter_Box)
			{
				m->imageArray[i].fastDownSample();
			}
			else if (filter == MipmapFilter_Triangle)
			{
				TriangleFilter filter;
				m->imageArray[i].downSample(filter, wrapMode);
			}
			else //if (filter == MipmapFilter_Kaiser)
			{
				nvDebugCheck(filter == MipmapFilter_Kaiser);
				//KaiserFilter filter(inputOptions.kaiserWidth);
				//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
				KaiserFilter filter(3);
				m->imageArray[i].downSample(filter, wrapMode);
			}
		}
	}
}

// Color transforms.
void Texture::toLinear(float gamma)
{
	if (equal(gamma, 1.0f)) return;

	detach();

	foreach(i, m->imageArray)
	{
		m->imageArray[i].toLinear(0, 3, gamma);
	}
}

void Texture::toGamma(float gamma)
{
	if (equal(gamma, 1.0f)) return;

	detach();

	foreach(i, m->imageArray)
	{
		m->imageArray[i].toGamma(0, 3, gamma);
	}
}

void Texture::transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4])
{
	detach();

	Matrix xform(
		Vector4(w0[0], w0[1], w0[2], w0[3]),
		Vector4(w1[0], w1[1], w1[2], w1[3]),
		Vector4(w2[0], w2[1], w2[2], w2[3]),
		Vector4(w3[0], w3[1], w3[2], w3[3]));

	Vector4 voffset(offset[0], offset[1], offset[2], offset[3]);

	foreach(i, m->imageArray)
	{
		m->imageArray[i].transform(0, xform, voffset);
	}
}

void Texture::swizzle(int r, int g, int b, int a)
{
	if (r == 0 && g == 1 && b == 2 && a == 3) return;

	detach();

	foreach(i, m->imageArray)
	{
		m->imageArray[i].swizzle(0, r, g, b, a);
	}
}

void Texture::scaleBias(int channel, float scale, float bias)
{
	if (equal(scale, 1.0f) && equal(bias, 0.0f)) return;

	detach();

	foreach(i, m->imageArray)
	{
		m->imageArray[i].scaleBias(channel, 1, scale, bias);
	}
}

void Texture::normalizeNormals()
{
	detach();

	foreach(i, m->imageArray)
	{
		m->imageArray[i].normalize(0);
	}
}

void Texture::blend(float r, float g, float b, float a)
{
	detach();

	foreach(i, m->imageArray)
	{
		// @@ Not implemented.
	}
}

void Texture::premultiplyAlpha()
{
	detach();

	// @@ Not implemented.
}

<commit_msg>Eliminate some warnings with MSVC.<commit_after>// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

#include "Texture.h"

#include <nvmath/Vector.h>
#include <nvmath/Matrix.h>

#include <nvimage/Filter.h>

using namespace nv;
using namespace nvtt;

namespace
{
	// 1 -> 1, 2 -> 2, 3 -> 2, 4 -> 4, 5 -> 4, ...
	static uint previousPowerOfTwo(const uint v)
	{
		return nextPowerOfTwo(v + 1) / 2;
	}

	static uint nearestPowerOfTwo(const uint v)
	{
		const uint np2 = nextPowerOfTwo(v);
		const uint pp2 = previousPowerOfTwo(v);

		if (np2 - v <= v - pp2)
		{
			return np2;
		}
		else
		{
			return pp2;
		}
	}
}

Texture::Texture() : m(new Texture::Private())
{
}

Texture::Texture(const Texture & tex) : m(tex.m)
{
	m->addRef();
}

Texture::~Texture()
{
	m->release();
	m = NULL;
}

void Texture::operator=(const Texture & tex)
{
	tex.m->addRef();
	m = tex.m;
	m->release();
}

void Texture::detach()
{
	if (m->refCount() > 1)
	{
		m = new Texture::Private(*m);
		m->addRef();
		nvDebugCheck(m->refCount() == 1);
	}
}

void Texture::setType(TextureType type)
{
	if (m->type != type)
	{
		detach();
		m->type = type;
	}
}

void Texture::setWrapMode(WrapMode wrapMode)
{
	if (m->wrapMode != wrapMode)
	{
		detach();
		m->wrapMode = wrapMode;
	}
}

void Texture::setAlphaMode(AlphaMode alphaMode)
{
	if (m->alphaMode != alphaMode)
	{
		detach();
		m->alphaMode = alphaMode;
	}
}

void Texture::setNormalMap(bool isNormalMap)
{
	if (m->isNormalMap != isNormalMap)
	{
		detach();
		m->isNormalMap = isNormalMap;
	}
}

bool Texture::load(const char * fileName)
{
	// @@ Not implemented.
	return false;
}

void Texture::setTexture2D(InputFormat format, int w, int h, int idx, void * data)
{
	// @@ Not implemented.
}

void Texture::resize(int w, int h, ResizeFilter filter)
{
	if (m->imageArray.count() > 0)
	{
		if (w == m->imageArray[0].width() && h == m->imageArray[0].height()) return;
	}

	// @TODO: if cubemap, make sure w == h.

	detach();

	foreach(i, m->imageArray)
	{
		FloatImage::WrapMode wrapMode = (FloatImage::WrapMode)m->wrapMode;

		if (m->alphaMode == AlphaMode_Transparency)
		{
			if (filter == ResizeFilter_Box)
			{
				BoxFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode, 3);
			}
			else if (filter == ResizeFilter_Triangle)
			{
				TriangleFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode, 3);
			}
			else if (filter == ResizeFilter_Kaiser)
			{
				//KaiserFilter filter(inputOptions.kaiserWidth);
				//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
				KaiserFilter filter(3);
				m->imageArray[i].resize(filter, w, h, wrapMode, 3);
			}
			else //if (filter == ResizeFilter_Mitchell)
			{
				nvDebugCheck(filter == ResizeFilter_Mitchell);
				MitchellFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode, 3);
			}
		}
		else
		{
			if (filter == ResizeFilter_Box)
			{
				BoxFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode);
			}
			else if (filter == ResizeFilter_Triangle)
			{
				TriangleFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode);
			}
			else if (filter == ResizeFilter_Kaiser)
			{
				//KaiserFilter filter(inputOptions.kaiserWidth);
				//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
				KaiserFilter filter(3);
				m->imageArray[i].resize(filter, w, h, wrapMode);
			}
			else //if (filter == ResizeFilter_Mitchell)
			{
				nvDebugCheck(filter == ResizeFilter_Mitchell);
				MitchellFilter filter;
				m->imageArray[i].resize(filter, w, h, wrapMode);
			}
		}
	}
}

void Texture::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
{
	if (m->imageArray.count() > 0)
	{
		int w = m->imageArray[0].width();
		int h = m->imageArray[0].height();

		nvDebugCheck(w > 0);
		nvDebugCheck(h > 0);

		if (roundMode != RoundMode_None)
		{
			// rounded max extent should never be higher than original max extent.
			maxExtent = previousPowerOfTwo(maxExtent);
		}

		// Scale extents without changing aspect ratio.
		int maxwh = max(w, h);
		if (maxExtent != 0 && maxwh > maxExtent)
		{
			w = max((w * maxExtent) / maxwh, 1);
			h = max((h * maxExtent) / maxwh, 1);
		}

		// Round to power of two.
		if (roundMode == RoundMode_ToNextPowerOfTwo)
		{
			w = nextPowerOfTwo(w);
			h = nextPowerOfTwo(h);
		}
		else if (roundMode == RoundMode_ToNearestPowerOfTwo)
		{
			w = nearestPowerOfTwo(w);
			h = nearestPowerOfTwo(h);
		}
		else if (roundMode == RoundMode_ToPreviousPowerOfTwo)
		{
			w = previousPowerOfTwo(w);
			h = previousPowerOfTwo(h);
		}

		resize(w, h, filter);
	}
}

bool Texture::buildNextMipmap(MipmapFilter filter)
{
	if (m->imageArray.count() > 0)
	{
		int w = m->imageArray[0].width();
		int h = m->imageArray[0].height();

		nvDebugCheck(w > 0);
		nvDebugCheck(h > 0);

        if (w == 1 && h == 1)
        {
            return false;
        }
    }

    detach();

	foreach(i, m->imageArray)
	{
		FloatImage::WrapMode wrapMode = (FloatImage::WrapMode)m->wrapMode;

		if (m->alphaMode == AlphaMode_Transparency)
		{
			if (filter == MipmapFilter_Box)
			{
				BoxFilter filter;
				m->imageArray[i].downSample(filter, wrapMode, 3);
			}
			else if (filter == MipmapFilter_Triangle)
			{
				TriangleFilter filter;
				m->imageArray[i].downSample(filter, wrapMode, 3);
			}
			else if (filter == MipmapFilter_Kaiser)
			{
				nvDebugCheck(filter == MipmapFilter_Kaiser);
				//KaiserFilter filter(inputOptions.kaiserWidth);
				//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
				KaiserFilter filter(3);
				m->imageArray[i].downSample(filter, wrapMode, 3);
			}
		}
		else
		{
			if (filter == MipmapFilter_Box)
			{
				m->imageArray[i].fastDownSample();
			}
			else if (filter == MipmapFilter_Triangle)
			{
				TriangleFilter filter;
				m->imageArray[i].downSample(filter, wrapMode);
			}
			else //if (filter == MipmapFilter_Kaiser)
			{
				nvDebugCheck(filter == MipmapFilter_Kaiser);
				//KaiserFilter filter(inputOptions.kaiserWidth);
				//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
				KaiserFilter filter(3);
				m->imageArray[i].downSample(filter, wrapMode);
			}
		}
	}

    return true;
}

// Color transforms.
void Texture::toLinear(float gamma)
{
	if (equal(gamma, 1.0f)) return;

	detach();

	foreach(i, m->imageArray)
	{
		m->imageArray[i].toLinear(0, 3, gamma);
	}
}

void Texture::toGamma(float gamma)
{
	if (equal(gamma, 1.0f)) return;

	detach();

	foreach(i, m->imageArray)
	{
		m->imageArray[i].toGamma(0, 3, gamma);
	}
}

void Texture::transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4])
{
	detach();

	Matrix xform(
		Vector4(w0[0], w0[1], w0[2], w0[3]),
		Vector4(w1[0], w1[1], w1[2], w1[3]),
		Vector4(w2[0], w2[1], w2[2], w2[3]),
		Vector4(w3[0], w3[1], w3[2], w3[3]));

	Vector4 voffset(offset[0], offset[1], offset[2], offset[3]);

	foreach(i, m->imageArray)
	{
		m->imageArray[i].transform(0, xform, voffset);
	}
}

void Texture::swizzle(int r, int g, int b, int a)
{
	if (r == 0 && g == 1 && b == 2 && a == 3) return;

	detach();

	foreach(i, m->imageArray)
	{
		m->imageArray[i].swizzle(0, r, g, b, a);
	}
}

void Texture::scaleBias(int channel, float scale, float bias)
{
	if (equal(scale, 1.0f) && equal(bias, 0.0f)) return;

	detach();

	foreach(i, m->imageArray)
	{
		m->imageArray[i].scaleBias(channel, 1, scale, bias);
	}
}

void Texture::normalizeNormals()
{
	detach();

	foreach(i, m->imageArray)
	{
		m->imageArray[i].normalize(0);
	}
}

void Texture::blend(float r, float g, float b, float a)
{
	detach();

	foreach(i, m->imageArray)
	{
		// @@ Not implemented.
	}
}

void Texture::premultiplyAlpha()
{
	detach();

	// @@ Not implemented.
}

<|endoftext|>


<commit_before>/*
Copyright (c) 2013 Daniele Bartolini, Michele Rossi
Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto

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

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

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

#include "Mutex.h"
#include "Assert.h"

namespace crown
{
namespace os
{

//-----------------------------------------------------------------------------
Mutex::Mutex()
{
	bool init = InitializeCriticalSectionAndSpinCount(&m_cs, 0x00000400);

	CE_ASSERT(init, "Unable to create mutex");
}

//-----------------------------------------------------------------------------
Mutex::~Mutex()
{
	DeleteCriticalSection(&m_cs);
}

//-----------------------------------------------------------------------------
void Mutex::lock()
{
    EnterCriticalSection(&m_cs);
}

//-----------------------------------------------------------------------------
void Mutex::unlock()
{
    LeaveCriticalSection(&m_cs);
}

//-----------------------------------------------------------------------------
CRITICAL_SECTION Mutex::handle()
{
	return m_cs;
}

} // namespace os
} // namespace crown
<commit_msg>Spin count not necessary<commit_after>/*
Copyright (c) 2013 Daniele Bartolini, Michele Rossi
Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto

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

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

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

#include "Mutex.h"
#include "Assert.h"

namespace crown
{
namespace os
{

//-----------------------------------------------------------------------------
Mutex::Mutex()
{
	InitializeCriticalSection(&m_cs);
}

//-----------------------------------------------------------------------------
Mutex::~Mutex()
{
	DeleteCriticalSection(&m_cs);
}

//-----------------------------------------------------------------------------
void Mutex::lock()
{
    EnterCriticalSection(&m_cs);
}

//-----------------------------------------------------------------------------
void Mutex::unlock()
{
    LeaveCriticalSection(&m_cs);
}

//-----------------------------------------------------------------------------
CRITICAL_SECTION Mutex::handle()
{
	return m_cs;
}

} // namespace os
} // namespace crown
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2011
  \file      rdorss.cpp
  \authors   Барс Александр
  \authors   Урусов Андрей (rdo@rk9.bmstu.ru)
  \authors   Романов Ярослав (robot.xet@gmail.com)
  \date
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "simulator/compiler/parser/pch.h"
// ----------------------------------------------------------------------- INCLUDES
#include <boost/bind.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/compiler/parser/rdorss.h"
#include "simulator/compiler/parser/rdortp.h"
#include "simulator/compiler/parser/rdoparser.h"
#include "simulator/compiler/parser/rdoparser_lexer.h"
#include "simulator/runtime/calc/resource/calc_resource.h"
#include "simulator/runtime/calc/resource/calc_create_resource.h"
// --------------------------------------------------------------------------------

OPEN_RDO_PARSER_NAMESPACE

// --------------------------------------------------------------------------------
// -------------------- RDORSSResource
// --------------------------------------------------------------------------------
const std::string RDORSSResource::GET_RESOURCE = "resource_expression";

RDORSSResource::RDORSSResource(CREF(LPRDOParser) pParser, CREF(RDOParserSrcInfo) src_info, CREF(LPRDORTPResType) pResType, std::size_t id)
	: RDOParserSrcInfo(src_info                                      )
	, m_pResType      (pResType                                      )
	, m_id            (id == UNDEFINED_ID ? pParser->getRSS_id() : id)
	, trace           (false                                         )
	, isNested        (false                                         )
{
	ASSERT(m_pResType);
	pParser->insertRSSResource(LPRDORSSResource(this));
	m_currParam = m_pResType->getParams().begin();
	RDOParser::s_parser()->contextStack()->push(this);
}

RDORSSResource::~RDORSSResource()
{}

void RDORSSResource::end()
{
	RDOParser::s_parser()->contextStack()->pop<RDORSSResource>();
}

namespace
{

LPExpression contextSetTrace(const rdo::runtime::LPRDOCalc& getResource, bool traceValue, const RDOParserSrcInfo& srcInfo)
{
	return rdo::Factory<Expression>::create(
		rdo::Factory<TypeInfo>::delegate<RDOType__void>(srcInfo),
		rdo::Factory<rdo::runtime::RDOCalcSetResourceTrace>::create(getResource, traceValue),
		srcInfo
	);
}

}

Context::FindResult RDORSSResource::onFindContext(const std::string& method, const Context::Params& params, const RDOParserSrcInfo& srcInfo) const
{
	if (method == Context::METHOD_GET)
	{
		const std::string paramName = params.identifier();

		const std::size_t parNumb = getType()->getRTPParamNumber(paramName);
		if (parNumb == RDORTPResType::UNDEFINED_PARAM)
		{
			RDOParser::s_parser()->error().error(srcInfo, rdo::format("Неизвестный параметр ресурса: %s", paramName.c_str()));
		}

		Context::Params params_;
		params_[RDORSSResource::GET_RESOURCE] = createGetResourceExpression(srcInfo);
		params_[RDOParam::CONTEXT_PARAM_PARAM_ID] = parNumb;

		LPContext pParam = getType()->findRTPParam(paramName);
		ASSERT(pParam);
		return pParam->find(Context::METHOD_GET, params_, srcInfo);
	}

	if (method == "trace()")
	{
		rdo::runtime::LPRDOCalc getResource = rdo::Factory<rdo::runtime::RDOCalcGetResourceByID>::create(getID());
		const bool traceValue = params.get<bool>("traceValue");
		return FindResult(CreateExpression(boost::bind(&contextSetTrace, getResource, traceValue, srcInfo)));
	}

	return FindResult();
}

LPExpression RDORSSResource::createGetResourceExpression(const RDOParserSrcInfo& srcInfo) const
{
	return rdo::Factory<Expression>::create(
		rdo::Factory<TypeInfo>::create(getType(), getType()->src_info()),
		rdo::Factory<rdo::runtime::RDOCalcGetResourceByID>::create(getID()),
		srcInfo
	);
}

void RDORSSResource::writeModelStructure(std::ostream& stream) const
{
	stream << (getID() + 1) << " " << name() << " " << getType()->getNumber() << std::endl;
}

void RDORSSResource::addParam(CREF(LPRDOValue) pParam)
{
	ASSERT(pParam);

	LPRDOValue pAddParamValue;
	LPExpression pAddParam;

	if (m_currParam == getType()->getParams().end())
	{
		RDOParser::s_parser()->error().push_only(pParam->src_info(), "Слишком много параметров");
		RDOParser::s_parser()->error().push_only(getType()->src_info(), "См. тип ресурса");
		RDOParser::s_parser()->error().push_done();
	}

	try
	{
		if (pParam->value().getAsString() == "*")
		{
			if (!(*m_currParam)->getDefault()->defined())
			{
				RDOParser::s_parser()->error().push_only(pParam->src_info(), "Невозможно использовать '*', к.т. отсутствует значение по умолчанию");
				/// @todo src_info() без параметра RDOParserSrcInfo()
				RDOParser::s_parser()->error().push_only((*m_currParam)->getTypeInfo()->src_info(RDOParserSrcInfo()), "См. описание параметра");
				RDOParser::s_parser()->error().push_done();
			}
			pAddParamValue = (*m_currParam)->getDefault();
		}
		else if (pParam->value().getAsString() == "#")
		{
			pAddParamValue = (*m_currParam)->getDefault()->defined()
				? (*m_currParam)->getDefault()
				: rdo::Factory<rdo::compiler::parser::RDOValue>::create(
					(*m_currParam)->getTypeInfo()->type()->get_default(),
					(*m_currParam)->getTypeInfo()->src_info(RDOParserSrcInfo()),
					(*m_currParam)->getTypeInfo()
				);
			ASSERT(pAddParamValue);
			pAddParamValue->value().setUndefined(true);
		}
		else
		{
			pAddParamValue = (*m_currParam)->getTypeInfo()->value_cast(pParam);
		}
	}
	catch(const RDOSyntaxException&)
	{
		RDOParser::s_parser()->error().modify(rdo::format("Для параметра '%s': ", (*m_currParam)->name().c_str()));
	}

	ASSERT(pAddParamValue);
	try
	{
		if(pAddParamValue->value().type().object_dynamic_cast<rdo::runtime::RDOResourceTypeList>())
		{
			LPRDORSSResource pResourceValue = pAddParamValue->value().getPointerByType<RDORTPResType>();
			ASSERT(pResourceValue);

			std::vector<rdo::runtime::LPRDOCalc> paramList;
			for (const auto& param : pResourceValue->params())
				paramList.push_back(param.param()->calc());

			rdo::runtime::LPRDOCalc pCalc = rdo::Factory<rdo::runtime::RDOCalcCreateResource>::create(
				pResourceValue->getType()->getNumber(),
				paramList,
				pResourceValue->getTrace(),
				pResourceValue->getType()->isPermanent()
			);

			pAddParam = rdo::Factory<Expression>::create(
				rdo::Factory<TypeInfo>::create(pAddParamValue->typeInfo()),
				pCalc,
				pAddParamValue->src_info()
			);
		}
		else
			pAddParam = rdo::Factory<Expression>::create(
				rdo::Factory<TypeInfo>::create(pAddParamValue->typeInfo()),
				rdo::Factory<rdo::runtime::RDOCalcConst>::create(pAddParamValue->value().clone()),
				pAddParamValue->src_info()
			);
	}
	catch (const rdo::runtime::RDOValueException& e)
	{
		RDOParser::s_parser()->error().error(pParam->src_info(), rdo::format("Для параметра '%s': %s", (*m_currParam)->name().c_str(), e.message().c_str()));
	}
	m_paramList.push_back(Param(pAddParam));
	m_currParam++;
}

bool RDORSSResource::defined() const
{
	return m_currParam == getType()->getParams().end();
}

std::vector<rdo::runtime::LPRDOCalc> RDORSSResource::createCalc() const
{
	std::vector<rdo::runtime::LPRDOCalc> calcList;
	std::vector<rdo::runtime::LPRDOCalc> paramList;
	for (const auto& param: params())
		paramList.push_back(param.param()->calc());

	rdo::runtime::LPRDOCalc pCalc = rdo::Factory<rdo::runtime::RDOCalcCreateResource>::create(
		getType()->getNumber(),
		paramList,
		getTrace(),
		getType()->isPermanent()
	);
	ASSERT(pCalc);
	rdo::runtime::RDOSrcInfo srcInfo(src_info());
	srcInfo.setSrcText("Создание ресурса " + src_text());
	pCalc->setSrcInfo(srcInfo);

	calcList.push_back(pCalc);
	if (m_traceCalc)
		calcList.push_back(m_traceCalc);

	return calcList;
}

CLOSE_RDO_PARSER_NAMESPACE
<commit_msg>пробел после if<commit_after>/*!
  \copyright (c) RDO-Team, 2011
  \file      rdorss.cpp
  \authors   Барс Александр
  \authors   Урусов Андрей (rdo@rk9.bmstu.ru)
  \authors   Романов Ярослав (robot.xet@gmail.com)
  \date
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "simulator/compiler/parser/pch.h"
// ----------------------------------------------------------------------- INCLUDES
#include <boost/bind.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/compiler/parser/rdorss.h"
#include "simulator/compiler/parser/rdortp.h"
#include "simulator/compiler/parser/rdoparser.h"
#include "simulator/compiler/parser/rdoparser_lexer.h"
#include "simulator/runtime/calc/resource/calc_resource.h"
#include "simulator/runtime/calc/resource/calc_create_resource.h"
// --------------------------------------------------------------------------------

OPEN_RDO_PARSER_NAMESPACE

// --------------------------------------------------------------------------------
// -------------------- RDORSSResource
// --------------------------------------------------------------------------------
const std::string RDORSSResource::GET_RESOURCE = "resource_expression";

RDORSSResource::RDORSSResource(CREF(LPRDOParser) pParser, CREF(RDOParserSrcInfo) src_info, CREF(LPRDORTPResType) pResType, std::size_t id)
	: RDOParserSrcInfo(src_info                                      )
	, m_pResType      (pResType                                      )
	, m_id            (id == UNDEFINED_ID ? pParser->getRSS_id() : id)
	, trace           (false                                         )
	, isNested        (false                                         )
{
	ASSERT(m_pResType);
	pParser->insertRSSResource(LPRDORSSResource(this));
	m_currParam = m_pResType->getParams().begin();
	RDOParser::s_parser()->contextStack()->push(this);
}

RDORSSResource::~RDORSSResource()
{}

void RDORSSResource::end()
{
	RDOParser::s_parser()->contextStack()->pop<RDORSSResource>();
}

namespace
{

LPExpression contextSetTrace(const rdo::runtime::LPRDOCalc& getResource, bool traceValue, const RDOParserSrcInfo& srcInfo)
{
	return rdo::Factory<Expression>::create(
		rdo::Factory<TypeInfo>::delegate<RDOType__void>(srcInfo),
		rdo::Factory<rdo::runtime::RDOCalcSetResourceTrace>::create(getResource, traceValue),
		srcInfo
	);
}

}

Context::FindResult RDORSSResource::onFindContext(const std::string& method, const Context::Params& params, const RDOParserSrcInfo& srcInfo) const
{
	if (method == Context::METHOD_GET)
	{
		const std::string paramName = params.identifier();

		const std::size_t parNumb = getType()->getRTPParamNumber(paramName);
		if (parNumb == RDORTPResType::UNDEFINED_PARAM)
		{
			RDOParser::s_parser()->error().error(srcInfo, rdo::format("Неизвестный параметр ресурса: %s", paramName.c_str()));
		}

		Context::Params params_;
		params_[RDORSSResource::GET_RESOURCE] = createGetResourceExpression(srcInfo);
		params_[RDOParam::CONTEXT_PARAM_PARAM_ID] = parNumb;

		LPContext pParam = getType()->findRTPParam(paramName);
		ASSERT(pParam);
		return pParam->find(Context::METHOD_GET, params_, srcInfo);
	}

	if (method == "trace()")
	{
		rdo::runtime::LPRDOCalc getResource = rdo::Factory<rdo::runtime::RDOCalcGetResourceByID>::create(getID());
		const bool traceValue = params.get<bool>("traceValue");
		return FindResult(CreateExpression(boost::bind(&contextSetTrace, getResource, traceValue, srcInfo)));
	}

	return FindResult();
}

LPExpression RDORSSResource::createGetResourceExpression(const RDOParserSrcInfo& srcInfo) const
{
	return rdo::Factory<Expression>::create(
		rdo::Factory<TypeInfo>::create(getType(), getType()->src_info()),
		rdo::Factory<rdo::runtime::RDOCalcGetResourceByID>::create(getID()),
		srcInfo
	);
}

void RDORSSResource::writeModelStructure(std::ostream& stream) const
{
	stream << (getID() + 1) << " " << name() << " " << getType()->getNumber() << std::endl;
}

void RDORSSResource::addParam(CREF(LPRDOValue) pParam)
{
	ASSERT(pParam);

	LPRDOValue pAddParamValue;
	LPExpression pAddParam;

	if (m_currParam == getType()->getParams().end())
	{
		RDOParser::s_parser()->error().push_only(pParam->src_info(), "Слишком много параметров");
		RDOParser::s_parser()->error().push_only(getType()->src_info(), "См. тип ресурса");
		RDOParser::s_parser()->error().push_done();
	}

	try
	{
		if (pParam->value().getAsString() == "*")
		{
			if (!(*m_currParam)->getDefault()->defined())
			{
				RDOParser::s_parser()->error().push_only(pParam->src_info(), "Невозможно использовать '*', к.т. отсутствует значение по умолчанию");
				/// @todo src_info() без параметра RDOParserSrcInfo()
				RDOParser::s_parser()->error().push_only((*m_currParam)->getTypeInfo()->src_info(RDOParserSrcInfo()), "См. описание параметра");
				RDOParser::s_parser()->error().push_done();
			}
			pAddParamValue = (*m_currParam)->getDefault();
		}
		else if (pParam->value().getAsString() == "#")
		{
			pAddParamValue = (*m_currParam)->getDefault()->defined()
				? (*m_currParam)->getDefault()
				: rdo::Factory<rdo::compiler::parser::RDOValue>::create(
					(*m_currParam)->getTypeInfo()->type()->get_default(),
					(*m_currParam)->getTypeInfo()->src_info(RDOParserSrcInfo()),
					(*m_currParam)->getTypeInfo()
				);
			ASSERT(pAddParamValue);
			pAddParamValue->value().setUndefined(true);
		}
		else
		{
			pAddParamValue = (*m_currParam)->getTypeInfo()->value_cast(pParam);
		}
	}
	catch(const RDOSyntaxException&)
	{
		RDOParser::s_parser()->error().modify(rdo::format("Для параметра '%s': ", (*m_currParam)->name().c_str()));
	}

	ASSERT(pAddParamValue);
	try
	{
		if (pAddParamValue->value().type().object_dynamic_cast<rdo::runtime::RDOResourceTypeList>())
		{
			LPRDORSSResource pResourceValue = pAddParamValue->value().getPointerByType<RDORTPResType>();
			ASSERT(pResourceValue);

			std::vector<rdo::runtime::LPRDOCalc> paramList;
			for (const auto& param : pResourceValue->params())
				paramList.push_back(param.param()->calc());

			rdo::runtime::LPRDOCalc pCalc = rdo::Factory<rdo::runtime::RDOCalcCreateResource>::create(
				pResourceValue->getType()->getNumber(),
				paramList,
				pResourceValue->getTrace(),
				pResourceValue->getType()->isPermanent()
			);

			pAddParam = rdo::Factory<Expression>::create(
				rdo::Factory<TypeInfo>::create(pAddParamValue->typeInfo()),
				pCalc,
				pAddParamValue->src_info()
			);
		}
		else
			pAddParam = rdo::Factory<Expression>::create(
				rdo::Factory<TypeInfo>::create(pAddParamValue->typeInfo()),
				rdo::Factory<rdo::runtime::RDOCalcConst>::create(pAddParamValue->value().clone()),
				pAddParamValue->src_info()
			);
	}
	catch (const rdo::runtime::RDOValueException& e)
	{
		RDOParser::s_parser()->error().error(pParam->src_info(), rdo::format("Для параметра '%s': %s", (*m_currParam)->name().c_str(), e.message().c_str()));
	}
	m_paramList.push_back(Param(pAddParam));
	m_currParam++;
}

bool RDORSSResource::defined() const
{
	return m_currParam == getType()->getParams().end();
}

std::vector<rdo::runtime::LPRDOCalc> RDORSSResource::createCalc() const
{
	std::vector<rdo::runtime::LPRDOCalc> calcList;
	std::vector<rdo::runtime::LPRDOCalc> paramList;
	for (const auto& param: params())
		paramList.push_back(param.param()->calc());

	rdo::runtime::LPRDOCalc pCalc = rdo::Factory<rdo::runtime::RDOCalcCreateResource>::create(
		getType()->getNumber(),
		paramList,
		getTrace(),
		getType()->isPermanent()
	);
	ASSERT(pCalc);
	rdo::runtime::RDOSrcInfo srcInfo(src_info());
	srcInfo.setSrcText("Создание ресурса " + src_text());
	pCalc->setSrcInfo(srcInfo);

	calcList.push_back(pCalc);
	if (m_traceCalc)
		calcList.push_back(m_traceCalc);

	return calcList;
}

CLOSE_RDO_PARSER_NAMESPACE
<|endoftext|>