<commit_before>#include "OS.hpp"
#include <port/port.hpp>

PriorityQueue_t<TaskStruct_t, MAX_TASKS> TaskQueue;
TaskStruct_t ActrualRunningTaskStruct;

void sys::boot() {
    InitSysTick();
    ActrualRunningTaskStruct = TaskQueue.front();
    TaskQueue.pop();
    ContextSet(&ActrualRunningTaskStruct.lowLevel);

    // Now we will execute this task (jump to first task)
    ExecutePendingTask();  // This will also enable interrupts

    // This will never execute, aber zicher ist zicher!
    while (1) {}
}

void sys::taskCreate(TaskHandler_t taskHandler,
                     uint8_t priority,
                     uint16_t StackSize) {
    TaskStruct_t task;
    task.priority = priority;
    task.lowLevel = TaskAllocate(taskHandler, StackSize);
    TaskQueue.push(task);
}

void sys::ProcSysTick() {
    ContextGet(&ActrualRunningTaskStruct.lowLevel);
    TaskQueue.push(ActrualRunningTaskStruct);
    ActrualRunningTaskStruct = TaskQueue.front();
    TaskQueue.pop();
    ContextSet(&ActrualRunningTaskStruct.lowLevel);
}
<commit_msg>uninitialized variable!<commit_after>#include "OS.hpp"
#include <port/port.hpp>

PriorityQueue_t<TaskStruct_t, MAX_TASKS> TaskQueue;
TaskStruct_t ActrualRunningTaskStruct;

void sys::boot() {
    InitSysTick();
    ActrualRunningTaskStruct = TaskQueue.front();
    TaskQueue.pop();
    ContextSet(&ActrualRunningTaskStruct.lowLevel);

    // Now we will execute this task (jump to first task)
    ExecutePendingTask();  // This will also enable interrupts

    // This will never execute, aber zicher ist zicher!
    while (1) {}
}

void sys::taskCreate(TaskHandler_t taskHandler,
                     uint8_t priority,
                     uint16_t StackSize) {
    TaskStruct_t task;
    task.priority = priority;
    task.blockingMutexNr = 0;
    task.lowLevel = TaskAllocate(taskHandler, StackSize);
    TaskQueue.push(task);
}

void sys::ProcSysTick() {
    ContextGet(&ActrualRunningTaskStruct.lowLevel);
    TaskQueue.push(ActrualRunningTaskStruct);
    ActrualRunningTaskStruct = TaskQueue.front();
    TaskQueue.pop();
    ContextSet(&ActrualRunningTaskStruct.lowLevel);
}
<|endoftext|>


<commit_before>//===--------------------------------------------------------------------------------*- C++ -*-===//
//                         _       _
//                        | |     | |
//                    __ _| |_ ___| | __ _ _ __   __ _
//                   / _` | __/ __| |/ _` | '_ \ / _` |
//                  | (_| | || (__| | (_| | | | | (_| |
//                   \__, |\__\___|_|\__,_|_| |_|\__, | - GridTools Clang DSL
//                    __/ |                       __/ |
//                   |___/                       |___/
//
//
//  This file is distributed under the MIT License (MIT).
//  See LICENSE.txt for details.
//
//===------------------------------------------------------------------------------------------===//

#ifndef GRIDTOOLS_CLANG_VERIFY_HPP
#define GRIDTOOLS_CLANG_VERIFY_HPP

#include "gridtools/clang_dsl.hpp"
#include <array>
#include <cmath>
#include <cstdlib>
#include <iostream>

namespace gridtools {

namespace clang {

class verifier {
public:
  verifier(const domain& dom,
           double precision = std::is_same<gridtools::float_type, double>::value ? 1e-12 : 1e-6)
      : m_domain(dom), m_precision(precision) {}

  template <class FunctorType, class... StorageTypes>
  void for_each(FunctorType&& functor, StorageTypes&... storages) const {
    for_each_impl(std::forward<FunctorType>(functor), storages...);
  }
  template <class FunctorType, class... StorageTypes>
  void for_each_boundary(FunctorType&& functor, StorageTypes&... storages) const {
    for_each_boundary_impl(std::forward<FunctorType>(functor), storages...);
  }

  template <class ValueType, class... StorageTypes>
  void fill(ValueType value, StorageTypes&... storages) const {
    fill_impl(value, storages...);
  }

  template <class... StorageTypes>
  void fillMath(double a, double b, double c, double d, double e, double f,
                StorageTypes&... storages) const {
    const gridtools::float_type pi = std::atan(1.) * 4.;
    for_each(
        [&](std::array<unsigned int, 3> dims, int i, int j, int k) {
          // 8,2,1.5,1.5,2,4
          double x = i / (gridtools::float_type)dims[0];
          double y = j / (gridtools::float_type)dims[1];
          return k +
                 (gridtools::float_type)a *
                     ((gridtools::float_type)b + cos(pi * (x + (gridtools::float_type)c * y)) +
                      sin((gridtools::float_type)d * pi * (x + (gridtools::float_type)e * y))) /
                     (gridtools::float_type)f;
        },
        storages...);
  }
  template <class... StorageTypes>
  void fill_random(StorageTypes&... storages) const {
    for_each([&](int, int, int) { return static_cast<double>(std::rand()) / RAND_MAX; },
             storages...);
  }

  template <class ValueType, class... StorageTypes>
  void fill_boundaries(ValueType value, StorageTypes&... storages) const {
    boundary_fill_impl(value, storages...);
  }

  template <class StorageType1, class StorageType2>
  bool verify(StorageType1& storage1, StorageType2& storage2, int max_erros = 10) const {
    using namespace gridtools;

    storage1.sync();
    storage2.sync();

    auto meta_data_1 = *storage1.get_storage_info_ptr();
    auto meta_data_2 = *storage2.get_storage_info_ptr();

    const uint_t idim1 = meta_data_1.template unaligned_dim<0>();
    const uint_t jdim1 = meta_data_1.template unaligned_dim<1>();
    const uint_t kdim1 = meta_data_1.template unaligned_dim<2>();

    const uint_t idim2 = meta_data_2.template unaligned_dim<0>();
    const uint_t jdim2 = meta_data_2.template unaligned_dim<1>();
    const uint_t kdim2 = meta_data_2.template unaligned_dim<2>();

    auto storage1_v = make_host_view(storage1);
    auto storage2_v = make_host_view(storage2);

    // Check dimensions
    auto check_dim = [&](uint_t dim1, uint_t dim2, uint_t size, const char* dimstr) {
      if(dim1 != dim2 || dim1 != size) {
        std::cerr << "dimension \"" << dimstr << "\" missmatch in storage pair \""
                  << storage1.name() << "\" : \"" << storage2.name() << "\"\n";
        std::cerr << "  " << dimstr << "-dim storage1: " << dim1 << "\n";
        std::cerr << "  " << dimstr << "-dim storage2: " << dim2 << "\n";
        std::cerr << "  " << dimstr << "-size domain: " << size << "\n";
        return false;
      }
      return true;
    };

    check_dim(idim1, idim2, m_domain.isize(), "i");
    check_dim(jdim1, jdim2, m_domain.jsize(), "j");
    check_dim(kdim1, kdim2, m_domain.ksize(), "k");

    bool verified = true;

    for(int i = m_domain.iminus(); i < (m_domain.isize() - m_domain.iplus()); ++i)
      for(int j = m_domain.jminus(); j < (m_domain.jsize() - m_domain.jplus()); ++j)
        for(int k = m_domain.kminus(); k < (m_domain.ksize() - m_domain.kplus()); ++k) {
          typename StorageType1::data_t value1 = storage1_v(i, j, k);
          typename StorageType2::data_t value2 = storage2_v(i, j, k);
          if(!compare_below_threashold(value1, value2, m_precision)) {
            if(--max_erros >= 0) {
              std::cerr << "( " << i << ", " << j << ", " << k << " ) : "
                        << " " << storage1.name() << " = " << value1 << " ; "
                        << " " << storage2.name() << " = " << value2
                        << "  error: " << std::fabs((value2 - value1) / (value2)) << std::endl;
            }
            verified = false;
          }
        }

    return verified;
  }

private:
  template <typename value_type>
  bool compare_below_threashold(value_type expected, value_type actual,
                                value_type precision) const {
    if(std::fabs(expected) < 1e-3 && std::fabs(actual) < 1e-3) {
      if(std::fabs(expected - actual) < precision)
        return true;
    } else {
      if(std::fabs((expected - actual) / (precision * expected)) < 1.0)
        return true;
    }
    return false;
  }

  template <class StorageType, class FunctorType>
  void for_each_do_it(FunctorType&& functor, StorageType& storage) const {
    using namespace gridtools;

    auto sinfo = *(storage.get_storage_info_ptr());
    auto storage_v = make_host_view(storage);
    const uint_t d1 = sinfo.template unaligned_dim<0>();
    const uint_t d2 = sinfo.template unaligned_dim<1>();
    const uint_t d3 = sinfo.template unaligned_dim<2>();

    for(uint_t i = 0; i < d1; ++i) {
      for(uint_t j = 0; j < d2; ++j) {
        for(uint_t k = 0; k < d3; ++k) {
          storage_v(i, j, k) = functor(std::array<uint_t, 3>{d1, d2, d3}, i, j, k);
        }
      }
    }
  }

  template <class FunctorType, class StorageType>
  void for_each_impl(FunctorType&& functor, StorageType& storage) const {
    for_each_do_it(std::forward<FunctorType>(functor), storage);
  }

  template <class FunctorType, class StorageType, class... StorageTypes>
  void for_each_impl(FunctorType&& functor, StorageType& storage, StorageTypes&... storages) const {
    using namespace gridtools;
    for_each_do_it(std::forward<FunctorType>(functor), storage);
    for_each_impl(std::forward<FunctorType>(functor), storages...);
  }

  template <class StorageType>
  void fill_impl(typename StorageType::data_t value, StorageType& storage) const {
    using namespace gridtools;
    for_each([&](std::array<uint_t, 3> dims, uint_t i, uint_t j, uint_t k) { return value; },
             storage);
  }

  template <class StorageType, class... StorageTypes>
  void fill_impl(typename StorageType::data_t value, StorageType& storage,
                 StorageTypes&... storages) const {
    using namespace gridtools;
    for_each([&](std::array<uint_t, 3> dims, uint_t i, uint_t j, uint_t k) { return value; },
             storage);
    fill_impl(value, storages...);
  }

  template <class StorageType, class FunctorType>
  void for_each_boundary_do_it(FunctorType&& functor, StorageType& storage) const {
    using namespace gridtools;

    auto sinfo = *(storage.get_storage_info_ptr());
    auto storage_v = make_host_view(storage);
    const uint_t start_d1 = sinfo.template total_begin<0>();
    const uint_t halo_d1 = decltype(sinfo)::halo_t::template at<0>();
    const uint_t end_d1 = sinfo.template total_end<0>();

    const uint_t start_d2 = sinfo.template total_begin<1>();
    const uint_t halo_d2 = decltype(sinfo)::halo_t::template at<1>();
    const uint_t end_d2 = sinfo.template total_end<1>();

    const uint_t d3 = sinfo.template unaligned_dim<2>();

    for(uint_t k = 0; k < d3; ++k) {
      for(uint_t i = start_d1; i < halo_d1; ++i) {
        for(uint_t j = start_d2; j < end_d2; ++j) {
          storage_v(i, j, k) = functor(std::array<uint_t, 3>{end_d1, end_d2, d3}, i, j, k);
        }
      }
      for(uint_t i = halo_d1; i < end_d1 - halo_d1; ++i) {
        for(uint_t j = start_d2; j < halo_d2; ++j) {
          storage_v(i, j, k) = functor(std::array<uint_t, 3>{end_d1, end_d2, d3}, i, j, k);
        }
        for(uint_t j = end_d2 - halo_d2; j < end_d2; ++j) {
          storage_v(i, j, k) = functor(std::array<uint_t, 3>{end_d1, end_d2, d3}, i, j, k);
        }
      }
      for(uint_t i = end_d1 - halo_d1; i < end_d1; ++i) {
        for(uint_t j = start_d2; j < end_d2; ++j) {
          storage_v(i, j, k) = functor(std::array<uint_t, 3>{end_d1, end_d2, d3}, i, j, k);
        }
      }
    }
  }

  template <class FunctorType, class StorageType>
  void for_each_boundary_impl(FunctorType&& functor, StorageType& storage) const {
    for_each_boundary_do_it(std::forward<FunctorType>(functor), storage);
  }

  template <class FunctorType, class StorageType, class... StorageTypes>
  void for_each_boundary_impl(FunctorType&& functor, StorageType& storage,
                              StorageTypes&... storages) const {
    using namespace gridtools;
    for_each_boundary_do_it(std::forward<FunctorType>(functor), storage);
    for_each_boundary_impl(std::forward<FunctorType>(functor), storages...);
  }
  template <class StorageType>
  void boundary_fill_impl(typename StorageType::data_t value, StorageType& storage) const {
    using namespace gridtools;
    for_each_boundary(
        [&](std::array<uint_t, 3> dims, uint_t i, uint_t j, uint_t k) { return value; }, storage);
  }

  template <class StorageType, class... StorageTypes>
  void boundary_fill_impl(typename StorageType::data_t value, StorageType& storage,
                          StorageTypes&... storages) const {
    using namespace gridtools;
    for_each_boundary(
        [&](std::array<uint_t, 3> dims, uint_t i, uint_t j, uint_t k) { return value; }, storage);
    boundary_fill_impl(value, storages...);
  }

private:
  domain m_domain;
  double m_precision;
};
}
}

#endif
<commit_msg>fix checks on domain sizes (#53)<commit_after>//===--------------------------------------------------------------------------------*- C++ -*-===//
//                         _       _
//                        | |     | |
//                    __ _| |_ ___| | __ _ _ __   __ _
//                   / _` | __/ __| |/ _` | '_ \ / _` |
//                  | (_| | || (__| | (_| | | | | (_| |
//                   \__, |\__\___|_|\__,_|_| |_|\__, | - GridTools Clang DSL
//                    __/ |                       __/ |
//                   |___/                       |___/
//
//
//  This file is distributed under the MIT License (MIT).
//  See LICENSE.txt for details.
//
//===------------------------------------------------------------------------------------------===//

#ifndef GRIDTOOLS_CLANG_VERIFY_HPP
#define GRIDTOOLS_CLANG_VERIFY_HPP

#include "gridtools/clang_dsl.hpp"
#include <array>
#include <cmath>
#include <cstdlib>
#include <iostream>

namespace gridtools {

namespace clang {

class verifier {
public:
  verifier(const domain& dom,
           double precision = std::is_same<gridtools::float_type, double>::value ? 1e-12 : 1e-6)
      : m_domain(dom), m_precision(precision) {}

  template <class FunctorType, class... StorageTypes>
  void for_each(FunctorType&& functor, StorageTypes&... storages) const {
    for_each_impl(std::forward<FunctorType>(functor), storages...);
  }
  template <class FunctorType, class... StorageTypes>
  void for_each_boundary(FunctorType&& functor, StorageTypes&... storages) const {
    for_each_boundary_impl(std::forward<FunctorType>(functor), storages...);
  }

  template <class ValueType, class... StorageTypes>
  void fill(ValueType value, StorageTypes&... storages) const {
    fill_impl(value, storages...);
  }

  template <class... StorageTypes>
  void fillMath(double a, double b, double c, double d, double e, double f,
                StorageTypes&... storages) const {
    const gridtools::float_type pi = std::atan(1.) * 4.;
    for_each(
        [&](std::array<unsigned int, 3> dims, int i, int j, int k) {
          // 8,2,1.5,1.5,2,4
          double x = i / (gridtools::float_type)dims[0];
          double y = j / (gridtools::float_type)dims[1];
          return k +
                 (gridtools::float_type)a *
                     ((gridtools::float_type)b + cos(pi * (x + (gridtools::float_type)c * y)) +
                      sin((gridtools::float_type)d * pi * (x + (gridtools::float_type)e * y))) /
                     (gridtools::float_type)f;
        },
        storages...);
  }
  template <class... StorageTypes>
  void fill_random(StorageTypes&... storages) const {
    for_each([&](int, int, int) { return static_cast<double>(std::rand()) / RAND_MAX; },
             storages...);
  }

  template <class ValueType, class... StorageTypes>
  void fill_boundaries(ValueType value, StorageTypes&... storages) const {
    boundary_fill_impl(value, storages...);
  }

  template <class StorageType1, class StorageType2>
  bool verify(StorageType1& storage1, StorageType2& storage2, int max_erros = 10) const {
    using namespace gridtools;

    storage1.sync();
    storage2.sync();

    auto meta_data_1 = *storage1.get_storage_info_ptr();
    auto meta_data_2 = *storage2.get_storage_info_ptr();

    const uint_t idim1 = meta_data_1.template unaligned_dim<0>();
    const uint_t jdim1 = meta_data_1.template unaligned_dim<1>();
    const uint_t kdim1 = meta_data_1.template unaligned_dim<2>();

    const uint_t idim2 = meta_data_2.template unaligned_dim<0>();
    const uint_t jdim2 = meta_data_2.template unaligned_dim<1>();
    const uint_t kdim2 = meta_data_2.template unaligned_dim<2>();

    auto storage1_v = make_host_view(storage1);
    auto storage2_v = make_host_view(storage2);

    // Check dimensions
    auto check_dim = [&](uint_t dim1, uint_t dim2, uint_t size, const char* dimstr) {
      if(dim1 != dim2 || dim1 < size) {
        std::cerr << "dimension \"" << dimstr << "\" missmatch in storage pair \""
                  << storage1.name() << "\" : \"" << storage2.name() << "\"\n";
        std::cerr << "  " << dimstr << "-dim storage1: " << dim1 << "\n";
        std::cerr << "  " << dimstr << "-dim storage2: " << dim2 << "\n";
        std::cerr << "  " << dimstr << "-size domain: " << size << "\n";
        return false;
      }
      return true;
    };

    check_dim(idim1, idim2, m_domain.isize(), "i");
    check_dim(jdim1, jdim2, m_domain.jsize(), "j");
    check_dim(kdim1, kdim2, m_domain.ksize(), "k");

    bool verified = true;

    for(int i = m_domain.iminus(); i < (m_domain.isize() - m_domain.iplus()); ++i)
      for(int j = m_domain.jminus(); j < (m_domain.jsize() - m_domain.jplus()); ++j)
        for(int k = m_domain.kminus(); k < (m_domain.ksize() - m_domain.kplus()); ++k) {
          typename StorageType1::data_t value1 = storage1_v(i, j, k);
          typename StorageType2::data_t value2 = storage2_v(i, j, k);
          if(!compare_below_threashold(value1, value2, m_precision)) {
            if(--max_erros >= 0) {
              std::cerr << "( " << i << ", " << j << ", " << k << " ) : "
                        << " " << storage1.name() << " = " << value1 << " ; "
                        << " " << storage2.name() << " = " << value2
                        << "  error: " << std::fabs((value2 - value1) / (value2)) << std::endl;
            }
            verified = false;
          }
        }

    return verified;
  }

private:
  template <typename value_type>
  bool compare_below_threashold(value_type expected, value_type actual,
                                value_type precision) const {
    if(std::fabs(expected) < 1e-3 && std::fabs(actual) < 1e-3) {
      if(std::fabs(expected - actual) < precision)
        return true;
    } else {
      if(std::fabs((expected - actual) / (precision * expected)) < 1.0)
        return true;
    }
    return false;
  }

  template <class StorageType, class FunctorType>
  void for_each_do_it(FunctorType&& functor, StorageType& storage) const {
    using namespace gridtools;

    auto sinfo = *(storage.get_storage_info_ptr());
    auto storage_v = make_host_view(storage);
    const uint_t d1 = sinfo.template unaligned_dim<0>();
    const uint_t d2 = sinfo.template unaligned_dim<1>();
    const uint_t d3 = sinfo.template unaligned_dim<2>();

    for(uint_t i = 0; i < d1; ++i) {
      for(uint_t j = 0; j < d2; ++j) {
        for(uint_t k = 0; k < d3; ++k) {
          storage_v(i, j, k) = functor(std::array<uint_t, 3>{d1, d2, d3}, i, j, k);
        }
      }
    }
  }

  template <class FunctorType, class StorageType>
  void for_each_impl(FunctorType&& functor, StorageType& storage) const {
    for_each_do_it(std::forward<FunctorType>(functor), storage);
  }

  template <class FunctorType, class StorageType, class... StorageTypes>
  void for_each_impl(FunctorType&& functor, StorageType& storage, StorageTypes&... storages) const {
    using namespace gridtools;
    for_each_do_it(std::forward<FunctorType>(functor), storage);
    for_each_impl(std::forward<FunctorType>(functor), storages...);
  }

  template <class StorageType>
  void fill_impl(typename StorageType::data_t value, StorageType& storage) const {
    using namespace gridtools;
    for_each([&](std::array<uint_t, 3> dims, uint_t i, uint_t j, uint_t k) { return value; },
             storage);
  }

  template <class StorageType, class... StorageTypes>
  void fill_impl(typename StorageType::data_t value, StorageType& storage,
                 StorageTypes&... storages) const {
    using namespace gridtools;
    for_each([&](std::array<uint_t, 3> dims, uint_t i, uint_t j, uint_t k) { return value; },
             storage);
    fill_impl(value, storages...);
  }

  template <class StorageType, class FunctorType>
  void for_each_boundary_do_it(FunctorType&& functor, StorageType& storage) const {
    using namespace gridtools;

    auto sinfo = *(storage.get_storage_info_ptr());
    auto storage_v = make_host_view(storage);
    const uint_t start_d1 = sinfo.template total_begin<0>();
    const uint_t halo_d1 = decltype(sinfo)::halo_t::template at<0>();
    const uint_t end_d1 = sinfo.template total_end<0>();

    const uint_t start_d2 = sinfo.template total_begin<1>();
    const uint_t halo_d2 = decltype(sinfo)::halo_t::template at<1>();
    const uint_t end_d2 = sinfo.template total_end<1>();

    const uint_t d3 = sinfo.template unaligned_dim<2>();

    for(uint_t k = 0; k < d3; ++k) {
      for(uint_t i = start_d1; i < halo_d1; ++i) {
        for(uint_t j = start_d2; j < end_d2; ++j) {
          storage_v(i, j, k) = functor(std::array<uint_t, 3>{end_d1, end_d2, d3}, i, j, k);
        }
      }
      for(uint_t i = halo_d1; i < end_d1 - halo_d1; ++i) {
        for(uint_t j = start_d2; j < halo_d2; ++j) {
          storage_v(i, j, k) = functor(std::array<uint_t, 3>{end_d1, end_d2, d3}, i, j, k);
        }
        for(uint_t j = end_d2 - halo_d2; j < end_d2; ++j) {
          storage_v(i, j, k) = functor(std::array<uint_t, 3>{end_d1, end_d2, d3}, i, j, k);
        }
      }
      for(uint_t i = end_d1 - halo_d1; i < end_d1; ++i) {
        for(uint_t j = start_d2; j < end_d2; ++j) {
          storage_v(i, j, k) = functor(std::array<uint_t, 3>{end_d1, end_d2, d3}, i, j, k);
        }
      }
    }
  }

  template <class FunctorType, class StorageType>
  void for_each_boundary_impl(FunctorType&& functor, StorageType& storage) const {
    for_each_boundary_do_it(std::forward<FunctorType>(functor), storage);
  }

  template <class FunctorType, class StorageType, class... StorageTypes>
  void for_each_boundary_impl(FunctorType&& functor, StorageType& storage,
                              StorageTypes&... storages) const {
    using namespace gridtools;
    for_each_boundary_do_it(std::forward<FunctorType>(functor), storage);
    for_each_boundary_impl(std::forward<FunctorType>(functor), storages...);
  }
  template <class StorageType>
  void boundary_fill_impl(typename StorageType::data_t value, StorageType& storage) const {
    using namespace gridtools;
    for_each_boundary(
        [&](std::array<uint_t, 3> dims, uint_t i, uint_t j, uint_t k) { return value; }, storage);
  }

  template <class StorageType, class... StorageTypes>
  void boundary_fill_impl(typename StorageType::data_t value, StorageType& storage,
                          StorageTypes&... storages) const {
    using namespace gridtools;
    for_each_boundary(
        [&](std::array<uint_t, 3> dims, uint_t i, uint_t j, uint_t k) { return value; }, storage);
    boundary_fill_impl(value, storages...);
  }

private:
  domain m_domain;
  double m_precision;
};
}
}

#endif
<|endoftext|>


<commit_before>/*
    Copyright 2016 Jonathan Bayle, Thomas Medioni

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "cyclist.hpp"
#include <sstream>
/**
 *
 * CYCLIST
 *
 */
Cyclist::Cyclist() : speed_(1.), sprinting_(false), sprinting_ratio_(1.)
{
    sprite_ = std::unique_ptr<ALLEGRO_BITMAP, al_bitmap_deleter>(al_create_bitmap(32, 68));
    al_set_target_bitmap(sprite_.get());
    al_clear_to_color(al_map_rgb(255, 0, 255));
    al_set_target_bitmap(al_get_backbuffer(al_get_current_display()));
}

Cyclist::~Cyclist()
{
}

void Cyclist::update(double delta_t)
{
    //update cyclist movement
    update_sprinting_ratio(delta_t);
    pos_.y += speed_ * 50. * sprinting_ratio_ * delta_t;
}

void Cyclist::draw()
{
    al_draw_bitmap(sprite_.get(), 380 + pos_.x, 280 - pos_.y, 0);
}

void Cyclist::handle(const ALLEGRO_EVENT& event)
{
    (void) event;
    //Handle events : void for bots
}

void Cyclist::update_sprinting_ratio(double delta_t)
{
    if (sprinting_)
        sprinting_ratio_ = glm::clamp(sprinting_ratio_ + (1 * delta_t), 1., 2.);
    else
        sprinting_ratio_ = glm::clamp(sprinting_ratio_ - (1* delta_t), 1., 2.);
}

/**
 *
 * PLAYER CYCLIST
 *
 */
PlayerCyclist::PlayerCyclist() : Cyclist(), power_(1000)
{
    add_draw_back( [&]() {
            al_draw_rectangle(772, 150, 790, 500, al_map_rgb(0, 255, 0), 1.);

            const int size = glm::clamp(power_, 0, maxpower) * 350 / maxpower;
            al_draw_filled_rectangle(772, 500 - size, 790, 500, al_map_rgb(0, 240, 0));
            std::ostringstream oss;
            oss << power_ << " kcal";
            al_draw_text(debug_font(), al_map_rgb(0, 255, 0), 790, 130, ALLEGRO_ALIGN_RIGHT, oss.str().c_str());
            });

#ifndef NDEBUG
    #define POS
    #define SPT_RATIO
#ifdef POS
    add_draw_back( [&]() {
            std::ostringstream oss;
            oss.precision(5);
            oss << "x: " << pos_.x << " y: " << pos_.y;
            al_draw_text(debug_font(), al_map_rgb(255, 255, 255), 10, 10, ALLEGRO_ALIGN_LEFT, oss.str().c_str());
            });
#endif
#ifdef SPT_RATIO
    add_draw_back( [&]() {
            std::ostringstream oss;
            oss.precision(3);
            oss << "SPT ratio: " << sprinting_ratio_;
            al_draw_text(debug_font(), al_map_rgb(255, 255, 255), 10, 20, ALLEGRO_ALIGN_LEFT, oss.str().c_str());
            });
#endif
#endif
}

PlayerCyclist::~PlayerCyclist()
{
}
void PlayerCyclist::update(double delta_t)
{
    Cyclist::update(delta_t);
    power_ -= speed_ * 50. * delta_t;

    if (power_ < 0) //LOST
    {
        power_ = 0;
    }
}
void PlayerCyclist::draw()
{
    Cyclist::draw();
    Object_split_aggregator::draw();
}
void PlayerCyclist::handle(const ALLEGRO_EVENT& event)
{
    Object_split_aggregator::handle(event);
    switch(event.type)
    {
        case ALLEGRO_EVENT_KEY_DOWN:
            switch(event.keyboard.keycode)
            {
                case ALLEGRO_KEY_LCTRL:
                    sprinting_ = true;
                    break;
            }
            break;
        case ALLEGRO_EVENT_KEY_UP:
            switch(event.keyboard.keycode)
            {
                case ALLEGRO_KEY_LCTRL:
                    sprinting_ = false;
                    break;
            }
            break;
    }
}

bool PlayerCyclist::alive()
{
    return power_ > 0;
}
<commit_msg>little fix, update power wrt sprinting ratio<commit_after>/*
    Copyright 2016 Jonathan Bayle, Thomas Medioni

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "cyclist.hpp"
#include <sstream>
/**
 *
 * CYCLIST
 *
 */
Cyclist::Cyclist() : speed_(1.), sprinting_(false), sprinting_ratio_(1.)
{
    sprite_ = std::unique_ptr<ALLEGRO_BITMAP, al_bitmap_deleter>(al_create_bitmap(32, 68));
    al_set_target_bitmap(sprite_.get());
    al_clear_to_color(al_map_rgb(255, 0, 255));
    al_set_target_bitmap(al_get_backbuffer(al_get_current_display()));
}

Cyclist::~Cyclist()
{
}

void Cyclist::update(double delta_t)
{
    //update cyclist movement
    update_sprinting_ratio(delta_t);
    pos_.y += speed_ * 50. * sprinting_ratio_ * delta_t;
}

void Cyclist::draw()
{
    al_draw_bitmap(sprite_.get(), 380 + pos_.x, 280 - pos_.y, 0);
}

void Cyclist::handle(const ALLEGRO_EVENT& event)
{
    (void) event;
    //Handle events : void for bots
}

void Cyclist::update_sprinting_ratio(double delta_t)
{
    if (sprinting_)
        sprinting_ratio_ = glm::clamp(sprinting_ratio_ + (1 * delta_t), 1., 2.);
    else
        sprinting_ratio_ = glm::clamp(sprinting_ratio_ - (1 * delta_t), 1., 2.);
}

/**
 *
 * PLAYER CYCLIST
 *
 */
PlayerCyclist::PlayerCyclist() : Cyclist(), power_(1000)
{
    add_draw_back( [&]() {
            al_draw_rectangle(772, 150, 790, 500, al_map_rgb(0, 255, 0), 1.);

            const int size = glm::clamp(power_, 0, maxpower) * 350 / maxpower;
            al_draw_filled_rectangle(772, 500 - size, 790, 500, al_map_rgb(0, 240, 0));
            std::ostringstream oss;
            oss << power_ << " kcal";
            al_draw_text(debug_font(), al_map_rgb(0, 255, 0), 790, 130, ALLEGRO_ALIGN_RIGHT, oss.str().c_str());
            });

#ifndef NDEBUG
    #define POS
    #define SPT_RATIO
#ifdef POS
    add_draw_back( [&]() {
            std::ostringstream oss;
            oss.precision(5);
            oss << "x: " << pos_.x << " y: " << pos_.y;
            al_draw_text(debug_font(), al_map_rgb(255, 255, 255), 10, 10, ALLEGRO_ALIGN_LEFT, oss.str().c_str());
            });
#endif
#ifdef SPT_RATIO
    add_draw_back( [&]() {
            std::ostringstream oss;
            oss.precision(3);
            oss << "SPT ratio: " << sprinting_ratio_;
            al_draw_text(debug_font(), al_map_rgb(255, 255, 255), 10, 20, ALLEGRO_ALIGN_LEFT, oss.str().c_str());
            });
#endif
#endif
}

PlayerCyclist::~PlayerCyclist()
{
}
void PlayerCyclist::update(double delta_t)
{
    Cyclist::update(delta_t);
    power_ -= speed_ * 50. * sprinting_ratio_ * delta_t;

    if (power_ < 0) //LOST
    {
        power_ = 0;
    }
}
void PlayerCyclist::draw()
{
    Cyclist::draw();
    Object_split_aggregator::draw();
}
void PlayerCyclist::handle(const ALLEGRO_EVENT& event)
{
    Object_split_aggregator::handle(event);
    switch(event.type)
    {
        case ALLEGRO_EVENT_KEY_DOWN:
            switch(event.keyboard.keycode)
            {
                case ALLEGRO_KEY_LCTRL:
                    sprinting_ = true;
                    break;
            }
            break;
        case ALLEGRO_EVENT_KEY_UP:
            switch(event.keyboard.keycode)
            {
                case ALLEGRO_KEY_LCTRL:
                    sprinting_ = false;
                    break;
            }
            break;
    }
}

bool PlayerCyclist::alive()
{
    return power_ > 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "jni_internal.h"
#include "class_linker.h"
#include "object.h"
#include "object_utils.h"
#include "reflection.h"

#include "JniConstants.h" // Last to avoid problems with LOG redefinition.

namespace art {

static bool GetFieldValue(Object* o, Field* f, JValue& value, bool allow_references) {
  ScopedThreadStateChange tsc(Thread::Current(), kRunnable);
  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), true, true)) {
    return false;
  }
  switch (FieldHelper(f).GetTypeAsPrimitiveType()) {
  case Primitive::kPrimBoolean:
    value.z = f->GetBoolean(o);
    return true;
  case Primitive::kPrimByte:
    value.b = f->GetByte(o);
    return true;
  case Primitive::kPrimChar:
    value.c = f->GetChar(o);
    return true;
  case Primitive::kPrimDouble:
    value.d = f->GetDouble(o);
    return true;
  case Primitive::kPrimFloat:
    value.f = f->GetFloat(o);
    return true;
  case Primitive::kPrimInt:
    value.i = f->GetInt(o);
    return true;
  case Primitive::kPrimLong:
    value.j = f->GetLong(o);
    return true;
  case Primitive::kPrimShort:
    value.s = f->GetShort(o);
    return true;
  case Primitive::kPrimNot:
    if (allow_references) {
      value.l = f->GetObject(o);
      return true;
    }
    // Else break to report an error.
    break;
  case Primitive::kPrimVoid:
    // Never okay.
    break;
  }
  Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
      "Not a primitive field: %s", PrettyField(f).c_str());
  return false;
}

static bool CheckReceiver(JNIEnv* env, jobject javaObj, Field* f, Object*& o) {
  if (f->IsStatic()) {
    o = NULL;
    return true;
  }

  o = Decode<Object*>(env, javaObj);
  Class* declaringClass = f->GetDeclaringClass();
  if (!VerifyObjectInClass(env, o, declaringClass)) {
    return false;
  }
  return true;
}

static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) {
  Field* f = DecodeField(env->FromReflectedField(javaField));
  Object* o = NULL;
  if (!CheckReceiver(env, javaObj, f, o)) {
    return NULL;
  }

  // Get the field's value, boxing if necessary.
  JValue value = { 0 };
  if (!GetFieldValue(o, f, value, true)) {
    return NULL;
  }
  BoxPrimitive(FieldHelper(f).GetTypeAsPrimitiveType(), value);

  return AddLocalReference<jobject>(env, value.l);
}

static JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char dst_descriptor) {
  Field* f = DecodeField(env->FromReflectedField(javaField));
  Object* o = NULL;
  if (!CheckReceiver(env, javaObj, f, o)) {
    return JValue();
  }

  // Read the value.
  JValue field_value = { 0 };
  if (!GetFieldValue(o, f, field_value, false)) {
    return JValue();
  }

  // Widen it if necessary (and possible).
  JValue wide_value;
  Class* dst_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor);
  if (!ConvertPrimitiveValue(FieldHelper(f).GetTypeAsPrimitiveType(), dst_type->GetPrimitiveType(),
                             field_value, wide_value)) {
    return JValue();
  }
  return wide_value;
}

static jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'Z').z;
}

static jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'B').b;
}

static jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'C').c;
}

static jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'D').d;
}

static jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'F').f;
}

static jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'I').i;
}

static jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'J').j;
}

static jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'S').s;
}

static void SetFieldValue(Object* o, Field* f, const JValue& new_value, bool allow_references) {
  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), true, true)) {
    return;
  }
  switch (FieldHelper(f).GetTypeAsPrimitiveType()) {
  case Primitive::kPrimBoolean:
    f->SetBoolean(o, new_value.z);
    break;
  case Primitive::kPrimByte:
    f->SetByte(o, new_value.b);
    break;
  case Primitive::kPrimChar:
    f->SetChar(o, new_value.c);
    break;
  case Primitive::kPrimDouble:
    f->SetDouble(o, new_value.d);
    break;
  case Primitive::kPrimFloat:
    f->SetFloat(o, new_value.f);
    break;
  case Primitive::kPrimInt:
    f->SetInt(o, new_value.i);
    break;
  case Primitive::kPrimLong:
    f->SetLong(o, new_value.j);
    break;
  case Primitive::kPrimShort:
    f->SetShort(o, new_value.s);
    break;
  case Primitive::kPrimNot:
    if (allow_references) {
      f->SetObject(o, new_value.l);
      break;
    }
    // Else fall through to report an error.
  case Primitive::kPrimVoid:
    // Never okay.
    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
        "Not a primitive field: %s", PrettyField(f).c_str());
    return;
  }

  // Special handling for final fields on SMP systems.
  // We need a store/store barrier here (JMM requirement).
  if (f->IsFinal()) {
    ANDROID_MEMBAR_STORE();
  }
}

static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) {
  ScopedThreadStateChange tsc(Thread::Current(), kRunnable);
  Field* f = DecodeField(env->FromReflectedField(javaField));

  // Unbox the value, if necessary.
  Object* boxed_value = Decode<Object*>(env, javaValue);
  JValue unboxed_value;
  if (!UnboxPrimitive(boxed_value, FieldHelper(f).GetType(), unboxed_value, "field")) {
    return;
  }

  // Check that the receiver is non-null and an instance of the field's declaring class.
  Object* o = NULL;
  if (!CheckReceiver(env, javaObj, f, o)) {
    return;
  }

  SetFieldValue(o, f, unboxed_value, true);
}

static void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor,
                              const JValue& new_value) {
  ScopedThreadStateChange tsc(Thread::Current(), kRunnable);
  Field* f = DecodeField(env->FromReflectedField(javaField));
  Object* o = NULL;
  if (!CheckReceiver(env, javaObj, f, o)) {
    return;
  }
  FieldHelper fh(f);
  if (!fh.IsPrimitiveType()) {
    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
        "Not a primitive field: %s", PrettyField(f).c_str());
    return;
  }

  // Widen the value if necessary (and possible).
  JValue wide_value;
  Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor);
  if (!ConvertPrimitiveValue(src_type->GetPrimitiveType(), fh.GetTypeAsPrimitiveType(),
                             new_value, wide_value)) {
    return;
  }

  // Write the value.
  SetFieldValue(o, f, wide_value, false);
}

static void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean value) {
  JValue v = { 0 };
  v.z = value;
  SetPrimitiveField(env, javaField, javaObj, 'Z', v);
}

static void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte value) {
  JValue v = { 0 };
  v.b = value;
  SetPrimitiveField(env, javaField, javaObj, 'B', v);
}

static void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar value) {
  JValue v = { 0 };
  v.c = value;
  SetPrimitiveField(env, javaField, javaObj, 'C', v);
}

static void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble value) {
  JValue v = { 0 };
  v.d = value;
  SetPrimitiveField(env, javaField, javaObj, 'D', v);
}

static void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat value) {
  JValue v = { 0 };
  v.f = value;
  SetPrimitiveField(env, javaField, javaObj, 'F', v);
}

static void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint value) {
  JValue v = { 0 };
  v.i = value;
  SetPrimitiveField(env, javaField, javaObj, 'I', v);
}

static void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong value) {
  JValue v = { 0 };
  v.j = value;
  SetPrimitiveField(env, javaField, javaObj, 'J', v);
}

static void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort value) {
  JValue v = { 0 };
  v.s = value;
  SetPrimitiveField(env, javaField, javaObj, 'S', v);
}

static JNINativeMethod gMethods[] = {
  NATIVE_METHOD(Field, get,        "(Ljava/lang/Object;)Ljava/lang/Object;"),
  NATIVE_METHOD(Field, getBoolean, "(Ljava/lang/Object;)Z"),
  NATIVE_METHOD(Field, getByte,    "(Ljava/lang/Object;)B"),
  NATIVE_METHOD(Field, getChar,    "(Ljava/lang/Object;)C"),
  NATIVE_METHOD(Field, getDouble,  "(Ljava/lang/Object;)D"),
  NATIVE_METHOD(Field, getFloat,   "(Ljava/lang/Object;)F"),
  NATIVE_METHOD(Field, getInt,     "(Ljava/lang/Object;)I"),
  NATIVE_METHOD(Field, getLong,    "(Ljava/lang/Object;)J"),
  NATIVE_METHOD(Field, getShort,   "(Ljava/lang/Object;)S"),
  NATIVE_METHOD(Field, set,        "(Ljava/lang/Object;Ljava/lang/Object;)V"),
  NATIVE_METHOD(Field, setBoolean, "(Ljava/lang/Object;Z)V"),
  NATIVE_METHOD(Field, setByte,    "(Ljava/lang/Object;B)V"),
  NATIVE_METHOD(Field, setChar,    "(Ljava/lang/Object;C)V"),
  NATIVE_METHOD(Field, setDouble,  "(Ljava/lang/Object;D)V"),
  NATIVE_METHOD(Field, setFloat,   "(Ljava/lang/Object;F)V"),
  NATIVE_METHOD(Field, setInt,     "(Ljava/lang/Object;I)V"),
  NATIVE_METHOD(Field, setLong,    "(Ljava/lang/Object;J)V"),
  NATIVE_METHOD(Field, setShort,   "(Ljava/lang/Object;S)V"),
};

void register_java_lang_reflect_Field(JNIEnv* env) {
  jniRegisterNativeMethods(env, "java/lang/reflect/Field", gMethods, NELEM(gMethods));
}

}  // namespace art
<commit_msg>am 4b952e74: Merge "Ensure byte and short values are sign extended before boxing." into ics-mr1-plus-art<commit_after>/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "jni_internal.h"
#include "class_linker.h"
#include "object.h"
#include "object_utils.h"
#include "reflection.h"

#include "JniConstants.h" // Last to avoid problems with LOG redefinition.

namespace art {

static bool GetFieldValue(Object* o, Field* f, JValue& value, bool allow_references) {
  DCHECK_EQ(value.j, 0LL);
  ScopedThreadStateChange tsc(Thread::Current(), kRunnable);
  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), true, true)) {
    return false;
  }
  switch (FieldHelper(f).GetTypeAsPrimitiveType()) {
  case Primitive::kPrimBoolean:
    value.z = f->GetBoolean(o);
    return true;
  case Primitive::kPrimByte:
    // Read byte and ensure it is fully sign-extended to an int.
    value.i = ((int32_t)f->GetByte(o) << 24) >> 24;
    return true;
  case Primitive::kPrimChar:
    value.c = f->GetChar(o);
    return true;
  case Primitive::kPrimDouble:
    value.d = f->GetDouble(o);
    return true;
  case Primitive::kPrimFloat:
    value.f = f->GetFloat(o);
    return true;
  case Primitive::kPrimInt:
    value.i = f->GetInt(o);
    return true;
  case Primitive::kPrimLong:
    value.j = f->GetLong(o);
    return true;
  case Primitive::kPrimShort:
    // Read short and ensure it is fully sign-extended to an int.
    value.i = ((int32_t)f->GetShort(o) << 16) >> 16;
    return true;
  case Primitive::kPrimNot:
    if (allow_references) {
      value.l = f->GetObject(o);
      return true;
    }
    // Else break to report an error.
    break;
  case Primitive::kPrimVoid:
    // Never okay.
    break;
  }
  Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
      "Not a primitive field: %s", PrettyField(f).c_str());
  return false;
}

static bool CheckReceiver(JNIEnv* env, jobject javaObj, Field* f, Object*& o) {
  if (f->IsStatic()) {
    o = NULL;
    return true;
  }

  o = Decode<Object*>(env, javaObj);
  Class* declaringClass = f->GetDeclaringClass();
  if (!VerifyObjectInClass(env, o, declaringClass)) {
    return false;
  }
  return true;
}

static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) {
  Field* f = DecodeField(env->FromReflectedField(javaField));
  Object* o = NULL;
  if (!CheckReceiver(env, javaObj, f, o)) {
    return NULL;
  }

  // Get the field's value, boxing if necessary.
  JValue value = { 0 };
  if (!GetFieldValue(o, f, value, true)) {
    return NULL;
  }
  BoxPrimitive(FieldHelper(f).GetTypeAsPrimitiveType(), value);

  return AddLocalReference<jobject>(env, value.l);
}

static JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char dst_descriptor) {
  Field* f = DecodeField(env->FromReflectedField(javaField));
  Object* o = NULL;
  if (!CheckReceiver(env, javaObj, f, o)) {
    return JValue();
  }

  // Read the value.
  JValue field_value = { 0 };
  if (!GetFieldValue(o, f, field_value, false)) {
    return JValue();
  }

  // Widen it if necessary (and possible).
  JValue wide_value;
  Class* dst_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor);
  if (!ConvertPrimitiveValue(FieldHelper(f).GetTypeAsPrimitiveType(), dst_type->GetPrimitiveType(),
                             field_value, wide_value)) {
    return JValue();
  }
  return wide_value;
}

static jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'Z').z;
}

static jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'B').b;
}

static jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'C').c;
}

static jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'D').d;
}

static jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'F').f;
}

static jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'I').i;
}

static jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'J').j;
}

static jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) {
  return GetPrimitiveField(env, javaField, javaObj, 'S').s;
}

static void SetFieldValue(Object* o, Field* f, const JValue& new_value, bool allow_references) {
  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), true, true)) {
    return;
  }
  switch (FieldHelper(f).GetTypeAsPrimitiveType()) {
  case Primitive::kPrimBoolean:
    f->SetBoolean(o, new_value.z);
    break;
  case Primitive::kPrimByte:
    f->SetByte(o, new_value.b);
    break;
  case Primitive::kPrimChar:
    f->SetChar(o, new_value.c);
    break;
  case Primitive::kPrimDouble:
    f->SetDouble(o, new_value.d);
    break;
  case Primitive::kPrimFloat:
    f->SetFloat(o, new_value.f);
    break;
  case Primitive::kPrimInt:
    f->SetInt(o, new_value.i);
    break;
  case Primitive::kPrimLong:
    f->SetLong(o, new_value.j);
    break;
  case Primitive::kPrimShort:
    f->SetShort(o, new_value.s);
    break;
  case Primitive::kPrimNot:
    if (allow_references) {
      f->SetObject(o, new_value.l);
      break;
    }
    // Else fall through to report an error.
  case Primitive::kPrimVoid:
    // Never okay.
    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
        "Not a primitive field: %s", PrettyField(f).c_str());
    return;
  }

  // Special handling for final fields on SMP systems.
  // We need a store/store barrier here (JMM requirement).
  if (f->IsFinal()) {
    ANDROID_MEMBAR_STORE();
  }
}

static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) {
  ScopedThreadStateChange tsc(Thread::Current(), kRunnable);
  Field* f = DecodeField(env->FromReflectedField(javaField));

  // Unbox the value, if necessary.
  Object* boxed_value = Decode<Object*>(env, javaValue);
  JValue unboxed_value;
  if (!UnboxPrimitive(boxed_value, FieldHelper(f).GetType(), unboxed_value, "field")) {
    return;
  }

  // Check that the receiver is non-null and an instance of the field's declaring class.
  Object* o = NULL;
  if (!CheckReceiver(env, javaObj, f, o)) {
    return;
  }

  SetFieldValue(o, f, unboxed_value, true);
}

static void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor,
                              const JValue& new_value) {
  ScopedThreadStateChange tsc(Thread::Current(), kRunnable);
  Field* f = DecodeField(env->FromReflectedField(javaField));
  Object* o = NULL;
  if (!CheckReceiver(env, javaObj, f, o)) {
    return;
  }
  FieldHelper fh(f);
  if (!fh.IsPrimitiveType()) {
    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
        "Not a primitive field: %s", PrettyField(f).c_str());
    return;
  }

  // Widen the value if necessary (and possible).
  JValue wide_value;
  Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor);
  if (!ConvertPrimitiveValue(src_type->GetPrimitiveType(), fh.GetTypeAsPrimitiveType(),
                             new_value, wide_value)) {
    return;
  }

  // Write the value.
  SetFieldValue(o, f, wide_value, false);
}

static void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean value) {
  JValue v = { 0 };
  v.z = value;
  SetPrimitiveField(env, javaField, javaObj, 'Z', v);
}

static void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte value) {
  JValue v = { 0 };
  v.b = value;
  SetPrimitiveField(env, javaField, javaObj, 'B', v);
}

static void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar value) {
  JValue v = { 0 };
  v.c = value;
  SetPrimitiveField(env, javaField, javaObj, 'C', v);
}

static void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble value) {
  JValue v = { 0 };
  v.d = value;
  SetPrimitiveField(env, javaField, javaObj, 'D', v);
}

static void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat value) {
  JValue v = { 0 };
  v.f = value;
  SetPrimitiveField(env, javaField, javaObj, 'F', v);
}

static void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint value) {
  JValue v = { 0 };
  v.i = value;
  SetPrimitiveField(env, javaField, javaObj, 'I', v);
}

static void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong value) {
  JValue v = { 0 };
  v.j = value;
  SetPrimitiveField(env, javaField, javaObj, 'J', v);
}

static void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort value) {
  JValue v = { 0 };
  v.s = value;
  SetPrimitiveField(env, javaField, javaObj, 'S', v);
}

static JNINativeMethod gMethods[] = {
  NATIVE_METHOD(Field, get,        "(Ljava/lang/Object;)Ljava/lang/Object;"),
  NATIVE_METHOD(Field, getBoolean, "(Ljava/lang/Object;)Z"),
  NATIVE_METHOD(Field, getByte,    "(Ljava/lang/Object;)B"),
  NATIVE_METHOD(Field, getChar,    "(Ljava/lang/Object;)C"),
  NATIVE_METHOD(Field, getDouble,  "(Ljava/lang/Object;)D"),
  NATIVE_METHOD(Field, getFloat,   "(Ljava/lang/Object;)F"),
  NATIVE_METHOD(Field, getInt,     "(Ljava/lang/Object;)I"),
  NATIVE_METHOD(Field, getLong,    "(Ljava/lang/Object;)J"),
  NATIVE_METHOD(Field, getShort,   "(Ljava/lang/Object;)S"),
  NATIVE_METHOD(Field, set,        "(Ljava/lang/Object;Ljava/lang/Object;)V"),
  NATIVE_METHOD(Field, setBoolean, "(Ljava/lang/Object;Z)V"),
  NATIVE_METHOD(Field, setByte,    "(Ljava/lang/Object;B)V"),
  NATIVE_METHOD(Field, setChar,    "(Ljava/lang/Object;C)V"),
  NATIVE_METHOD(Field, setDouble,  "(Ljava/lang/Object;D)V"),
  NATIVE_METHOD(Field, setFloat,   "(Ljava/lang/Object;F)V"),
  NATIVE_METHOD(Field, setInt,     "(Ljava/lang/Object;I)V"),
  NATIVE_METHOD(Field, setLong,    "(Ljava/lang/Object;J)V"),
  NATIVE_METHOD(Field, setShort,   "(Ljava/lang/Object;S)V"),
};

void register_java_lang_reflect_Field(JNIEnv* env) {
  jniRegisterNativeMethods(env, "java/lang/reflect/Field", gMethods, NELEM(gMethods));
}

}  // namespace art
<|endoftext|>


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

#include "TextAndDescription.h"

namespace Interaction {

DEFINE_ITEM_COMMON(TextAndDescription, "item")

using namespace Visualization;

TextAndDescription::TextAndDescription(Item* parent, const StyleType* style)
	: Super{parent, style}, textVis_{}, descriptionVis_{}
{
}

TextAndDescription::TextAndDescription(const QString& text, const QString& description, const StyleType* style)
	: TextAndDescription{nullptr, style}
{
	setContents(text, description);
}

TextAndDescription::~TextAndDescription()
{
	// These will automatically be deleted by layout's destructor
	textVis_ = nullptr;
	descriptionVis_ = nullptr;
}

bool TextAndDescription::sizeDependsOnParent() const
{
	return true;
}

void TextAndDescription::setContents(const QString& text, const QString& description)
{
	text_ = text;
	description_ = description;
}

void TextAndDescription::determineChildren()
{
	layout()->synchronizeFirst(textVis_, !text_.isEmpty(), &style()->text());
	layout()->synchronizeLast(descriptionVis_, !description_.isEmpty(), &style()->description());

	layout()->setStyle( &style()->layout() );
	if (textVis_)
	{
		textVis_->setStyle( &style()->text() );
		textVis_->setText(text_);
	}
	if (descriptionVis_)
	{
		descriptionVis_->setStyle( &style()->description() );
		descriptionVis_->setText(description_);
	}
}

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

#include "TextAndDescription.h"

namespace Interaction {

DEFINE_ITEM_COMMON(TextAndDescription, "item")

using namespace Visualization;

TextAndDescription::TextAndDescription(Item* parent, const StyleType* style)
	: Super{parent, style}, textVis_{}, descriptionVis_{}
{
}

TextAndDescription::TextAndDescription(const QString& text, const QString& description, const StyleType* style)
	: TextAndDescription{nullptr, style}
{
	setContents(text, description);
}

TextAndDescription::~TextAndDescription()
{
	// These will automatically be deleted by layout's destructor
	textVis_ = nullptr;
	descriptionVis_ = nullptr;
}

bool TextAndDescription::sizeDependsOnParent() const
{
	return true;
}

void TextAndDescription::setContents(const QString& text, const QString& description)
{
	text_ = text;
	description_ = description;
}

void TextAndDescription::determineChildren()
{
	layout()->synchronizeFirst(textVis_, !text_.isEmpty(), &style()->text());
	layout()->synchronizeLast(descriptionVis_, !description_.isEmpty(), &style()->description());

	layout()->setStyle( &style()->layout() );
	if (textVis_)
	{
		textVis_->setStyle( &style()->text() );
		textVis_->setText(text_);
	}
	if (descriptionVis_)
	{
		descriptionVis_->setStyle( &style()->description() );
		descriptionVis_->setText(description_);
		descriptionVis_->setTextFormat(Qt::RichText);
	}
}

}
<|endoftext|>


<commit_before>/*

Copyright (c) 2014, Project OSRM, Dennis Luxen, others
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.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.

*/

#ifndef DISTANCE_TABLE_PLUGIN_H
#define DISTANCE_TABLE_PLUGIN_H

#include "plugin_base.hpp"

#include "../algorithms/object_encoder.hpp"
#include "../data_structures/json_container.hpp"
#include "../data_structures/query_edge.hpp"
#include "../data_structures/search_engine.hpp"
#include "../descriptors/descriptor_base.hpp"
#include "../Util/json_renderer.hpp"
#include "../Util/make_unique.hpp"
#include "../Util/StringUtil.h"
#include "../Util/timing_util.hpp"

#include <cstdlib>

#include <algorithm>
#include <memory>
#include <unordered_map>
#include <string>
#include <vector>

template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
{
  private:
    std::unique_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;

  public:
    explicit DistanceTablePlugin(DataFacadeT *facade) : descriptor_string("table"), facade(facade)
    {
        search_engine_ptr = osrm::make_unique<SearchEngine<DataFacadeT>>(facade);
    }

    virtual ~DistanceTablePlugin() {}

    const std::string GetDescriptor() const final { return descriptor_string; }

    void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
    {
        if (!check_all_coordinates(route_parameters.coordinates))
        {
            reply = http::Reply::StockReply(http::Reply::badRequest);
            return;
        }

        const bool checksum_OK = (route_parameters.check_sum == facade->GetCheckSum());
        unsigned max_locations =
            std::min(100u, static_cast<unsigned>(route_parameters.coordinates.size()));
        PhantomNodeArray phantom_node_vector(max_locations);
        for (const auto i : osrm::irange(1u, max_locations))
        {
            if (checksum_OK && i < route_parameters.hints.size() &&
                !route_parameters.hints[i].empty())
            {
                PhantomNode current_phantom_node;
                ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], current_phantom_node);
                if (current_phantom_node.is_valid(facade->GetNumberOfNodes()))
                {
                    phantom_node_vector[i].emplace_back(std::move(current_phantom_node));
                    continue;
                }
            }
            facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates[i],
                                                            phantom_node_vector[i],
                                                            1);

            BOOST_ASSERT(phantom_node_vector[i].front().is_valid(facade->GetNumberOfNodes()));
        }

        // TIMER_START(distance_table);
        std::shared_ptr<std::vector<EdgeWeight>> result_table =
            search_engine_ptr->distance_table(phantom_node_vector);
        // TIMER_STOP(distance_table);

        if (!result_table)
        {
            reply = http::Reply::StockReply(http::Reply::badRequest);
            return;
        }
        JSON::Object json_object;
        JSON::Array json_array;
        const unsigned number_of_locations = static_cast<unsigned>(phantom_node_vector.size());
        for (unsigned row = 0; row < number_of_locations; ++row)
        {
            JSON::Array json_row;
            auto row_begin_iterator = result_table->begin() + (row * number_of_locations);
            auto row_end_iterator = result_table->begin() + ((row + 1) * number_of_locations);
            json_row.values.insert(json_row.values.end(), row_begin_iterator, row_end_iterator);
            json_array.values.push_back(json_row);
        }
        json_object.values["distance_table"] = json_array;
        JSON::render(reply.content, json_object);
    }

  private:
    std::string descriptor_string;
    DataFacadeT *facade;
};

#endif // DISTANCE_TABLE_PLUGIN_H
<commit_msg>Fix off-by-one in distance table plugin.<commit_after>/*

Copyright (c) 2014, Project OSRM, Dennis Luxen, others
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.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.

*/

#ifndef DISTANCE_TABLE_PLUGIN_H
#define DISTANCE_TABLE_PLUGIN_H

#include "plugin_base.hpp"

#include "../algorithms/object_encoder.hpp"
#include "../data_structures/json_container.hpp"
#include "../data_structures/query_edge.hpp"
#include "../data_structures/search_engine.hpp"
#include "../descriptors/descriptor_base.hpp"
#include "../Util/json_renderer.hpp"
#include "../Util/make_unique.hpp"
#include "../Util/StringUtil.h"
#include "../Util/timing_util.hpp"

#include <cstdlib>

#include <algorithm>
#include <memory>
#include <unordered_map>
#include <string>
#include <vector>

template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
{
  private:
    std::unique_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;

  public:
    explicit DistanceTablePlugin(DataFacadeT *facade) : descriptor_string("table"), facade(facade)
    {
        search_engine_ptr = osrm::make_unique<SearchEngine<DataFacadeT>>(facade);
    }

    virtual ~DistanceTablePlugin() {}

    const std::string GetDescriptor() const final { return descriptor_string; }

    void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
    {
        if (!check_all_coordinates(route_parameters.coordinates))
        {
            reply = http::Reply::StockReply(http::Reply::badRequest);
            return;
        }

        const bool checksum_OK = (route_parameters.check_sum == facade->GetCheckSum());
        unsigned max_locations =
            std::min(100u, static_cast<unsigned>(route_parameters.coordinates.size()));
        PhantomNodeArray phantom_node_vector(max_locations);
        for (const auto i : osrm::irange(0u, max_locations))
        {
            if (checksum_OK && i < route_parameters.hints.size() &&
                !route_parameters.hints[i].empty())
            {
                PhantomNode current_phantom_node;
                ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], current_phantom_node);
                if (current_phantom_node.is_valid(facade->GetNumberOfNodes()))
                {
                    phantom_node_vector[i].emplace_back(std::move(current_phantom_node));
                    continue;
                }
            }
            facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates[i],
                                                            phantom_node_vector[i],
                                                            1);

            BOOST_ASSERT(phantom_node_vector[i].front().is_valid(facade->GetNumberOfNodes()));
        }

        // TIMER_START(distance_table);
        std::shared_ptr<std::vector<EdgeWeight>> result_table =
            search_engine_ptr->distance_table(phantom_node_vector);
        // TIMER_STOP(distance_table);

        if (!result_table)
        {
            reply = http::Reply::StockReply(http::Reply::badRequest);
            return;
        }
        JSON::Object json_object;
        JSON::Array json_array;
        const unsigned number_of_locations = static_cast<unsigned>(phantom_node_vector.size());
        for (unsigned row = 0; row < number_of_locations; ++row)
        {
            JSON::Array json_row;
            auto row_begin_iterator = result_table->begin() + (row * number_of_locations);
            auto row_end_iterator = result_table->begin() + ((row + 1) * number_of_locations);
            json_row.values.insert(json_row.values.end(), row_begin_iterator, row_end_iterator);
            json_array.values.push_back(json_row);
        }
        json_object.values["distance_table"] = json_array;
        JSON::render(reply.content, json_object);
    }

  private:
    std::string descriptor_string;
    DataFacadeT *facade;
};

#endif // DISTANCE_TABLE_PLUGIN_H
<|endoftext|>


<commit_before>/**
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2004 projectM Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * See 'LICENSE.txt' included within this release
 *
 */

#include <stdio.h>

#include "Common.hpp"
#include "fatal.h"
#include "KeyHandler.hpp"
#include "event.h"
#include "BeatDetect.hpp"
#include "PresetChooser.hpp"
#include "Renderer.hpp"
#include "projectM.hpp"

#include <iostream>
#include "TimeKeeper.hpp"

class Preset;
interface_t current_interface = DEFAULT_INTERFACE;

void selectRandom(const bool hardCut);
void selectNext(const bool hardCut);
void selectPrevious(const bool hardCut);

std::string round_float(float number)
{
    std::string num_text = std::to_string(number);
    std::string rounded = num_text.substr(0, num_text.find(".")+3);
	return rounded;
}

void refreshConsole() {

  switch (current_interface) {

  case MENU_INTERFACE:
    // unimplemented
    break;
  case SHELL_INTERFACE:
    // unimplemented
    break;
  case EDITOR_INTERFACE:
    // unimplemented
    break;
  case DEFAULT_INTERFACE:
    break;
  case BROWSER_INTERFACE:
    // unimplemented
    break;
  default:
    break;
  }

}

void projectM::key_handler( projectMEvent event,
                            projectMKeycode keycode, projectMModifier modifier ) {

	switch( event ) {

	case PROJECTM_KEYDOWN:

	  //default_key_handler();
	  switch (current_interface)
	    {

	    case MENU_INTERFACE:
//	      menu_key_handler(this, event, keycode);
	      break;
	    case SHELL_INTERFACE:
	      //shell_key_handler();
	      break;
	    case EDITOR_INTERFACE:
//	      editor_key_handler(event,keycode);
	      break;
	    case BROWSER_INTERFACE:
//	      browser_key_handler(event,keycode,modifier);
	      break;
	    case DEFAULT_INTERFACE:
	      default_key_handler(event,keycode);
	      break;
	    default:
	      default_key_handler(event,keycode);
	      break;

	    }
	  break;
	default:
		break;

	}
}

void projectM::default_key_handler( projectMEvent event, projectMKeycode keycode) {

	switch( event ) {

	case PROJECTM_KEYDOWN:

		switch (keycode)
		{
		case PROJECTM_K_HOME:
			if (renderer->showmenu) { // pageup only does something when the preset menu is active.
				selectPreset(0);  // jump to top of presets.
			}
			break;
		case PROJECTM_K_END:
			if (renderer->showmenu) { // pageup only does something when the preset menu is active.
				selectPreset(m_presetLoader->size() - 1);  // jump to bottom of presets.
			}
			break;
		case PROJECTM_K_PAGEUP:
			if (renderer->showmenu) { // pageup only does something when the preset menu is active.
				int upPreset = m_presetPos->lastIndex() - (renderer->textMenuPageSize / 2.0f); // jump up by page size / 2
				if (upPreset < 0) // handle lower boundary
					upPreset = m_presetLoader->size() - 1;
				selectPreset(upPreset);  // jump up menu half a page.
			}
			break;
		case PROJECTM_K_PAGEDOWN:
			if (renderer->showmenu) { // pagedown only does something when the preset menu is active.
				int downPreset = m_presetPos->lastIndex() + (renderer->textMenuPageSize / 2.0f); // jump down by page size / 2
				if (downPreset >= (m_presetLoader->size() - 1)) // handle upper boundary
					downPreset = 0;
				selectPreset(downPreset); // jump down menu half a page.
			}
			break;
		case PROJECTM_K_UP:
			if (renderer->showmenu) {
				selectPrevious(true);
			}
			else {
				beatDetect->beatSensitivity += 0.25;
				if (beatDetect->beatSensitivity > 5.0) beatDetect->beatSensitivity = 5.0;
				renderer->setToastMessage("Beat Sensitivity: " + round_float(beatDetect->beatSensitivity));
			}
			break;
		case PROJECTM_K_DOWN:
			if (renderer->showmenu) {
				selectNext(true);
			}
			else {
				beatDetect->beatSensitivity -= 0.25;
				if (beatDetect->beatSensitivity < 0) beatDetect->beatSensitivity = 0;
				renderer->setToastMessage("Beat Sensitivity: " + round_float(beatDetect->beatSensitivity));
			}
			break;
		case PROJECTM_K_h:
			renderer->showhelp = !renderer->showhelp;
			renderer->showstats = false;
			renderer->showmenu = false;
		case PROJECTM_K_F1:
			renderer->showhelp = !renderer->showhelp;
			renderer->showstats = false;
			renderer->showmenu = false;
			break;
		case PROJECTM_K_y:
			this->setShuffleEnabled(!this->isShuffleEnabled());
			if (this->isShuffleEnabled()) {
				renderer->setToastMessage("Shuffle Enabled");
			}
			else {
				renderer->setToastMessage("Shuffle Disabled");
			}
			break;

		case PROJECTM_K_F5:
			renderer->showfps = !renderer->showfps;
			// Initialize counters and reset frame count.
			renderer->lastTimeFPS = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
			renderer->currentTimeFPS = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
			renderer->totalframes = 0;
			// Hide preset name from screen and replace it with FPS counter.
			if (renderer->showfps)
			{
				renderer->showpreset = false;
			}
			break;
		case PROJECTM_K_F4:
			renderer->showstats = !renderer->showstats;
			if (renderer->showstats) {
				renderer->showhelp = false;
				renderer->showmenu = false;
			}
			break;
		case PROJECTM_K_F3: {
			renderer->showpreset = !renderer->showpreset;
			// Hide FPS from screen and replace it with preset name.
			if (renderer->showpreset)
			{
				renderer->showfps = false;
			}
			break;
		}
		case PROJECTM_K_F2:
			renderer->showtitle = !renderer->showtitle;
			break;
#ifndef MACOS
		case PROJECTM_K_F9:
#else
		case PROJECTM_K_F8:
#endif

			renderer->studio = !renderer->studio;
			break;

		case PROJECTM_K_ESCAPE: {
			//	        exit( 1 );
			break;
		}
		case PROJECTM_K_f:

			break;
		case PROJECTM_K_a:
			renderer->correction = !renderer->correction;
			break;
		case PROJECTM_K_b:
			break;
		case PROJECTM_K_H:
		case PROJECTM_K_m:
			renderer->showmenu = !renderer->showmenu;
			if (renderer->showmenu) {
				renderer->showhelp = false;
				renderer->showstats = false;
				populatePresetMenu();
			}
			break;
		case PROJECTM_K_M:
			renderer->showmenu = !renderer->showmenu;
			if (renderer->showmenu)
			{
				renderer->showhelp=false;
				renderer->showstats=false;
				populatePresetMenu();
			}
          break;
      case PROJECTM_K_n:
          selectNext(true);
          break;
      case PROJECTM_K_N:
          selectNext(false);
          break;
	    case PROJECTM_K_r:
		selectRandom(true);
		break;
	    case PROJECTM_K_R:
		selectRandom(false);
		break;
	    case PROJECTM_K_p:
	      selectPrevious(true);
	      break;
	    case PROJECTM_K_P:
	    case PROJECTM_K_BACKSPACE:
	      selectPrevious(false);
	      break;
	    case PROJECTM_K_l:
			setPresetLock(!isPresetLocked());
			break;
	    case PROJECTM_K_s:
            	renderer->studio = !renderer->studio;
	    case PROJECTM_K_i:
	        break;
	    case PROJECTM_K_z:
	      break;
	    case PROJECTM_K_0:
//	      nWaveMode=0;
	      break;
	    case PROJECTM_K_6:
//	      nWaveMode=6;
	      break;
	    case PROJECTM_K_7:
//	      nWaveMode=7;
	      break;
	    case PROJECTM_K_t:
	      break;
	    case PROJECTM_K_EQUALS:
	    case PROJECTM_K_PLUS:

	    	unsigned int index;

	    	if (selectedPresetIndex(index)) {

	    		const int oldRating = getPresetRating(index, HARD_CUT_RATING_TYPE);

	    		if (oldRating >= 6)
	    			  break;

	    		const int rating = oldRating + 1;

	    		changePresetRating(index, rating, HARD_CUT_RATING_TYPE);
	    	}

	    	break;

	    case PROJECTM_K_MINUS:
	    	if (selectedPresetIndex(index)) {

	    		const int oldRating = getPresetRating(index, HARD_CUT_RATING_TYPE);

	    		if (oldRating <= 1)
	    			  break;

	    		const int rating = oldRating - 1;

	    		changePresetRating(index, rating, HARD_CUT_RATING_TYPE);
	    	}
	    	break;

	    default:
	      break;
	    }
	default:
		break;

	}
}
<commit_msg>tweak beat sensitivity to be more sensitive / granular<commit_after>/**
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2004 projectM Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * See 'LICENSE.txt' included within this release
 *
 */

#include <stdio.h>

#include "Common.hpp"
#include "fatal.h"
#include "KeyHandler.hpp"
#include "event.h"
#include "BeatDetect.hpp"
#include "PresetChooser.hpp"
#include "Renderer.hpp"
#include "projectM.hpp"

#include <iostream>
#include "TimeKeeper.hpp"

class Preset;
interface_t current_interface = DEFAULT_INTERFACE;

void selectRandom(const bool hardCut);
void selectNext(const bool hardCut);
void selectPrevious(const bool hardCut);

std::string round_float(float number)
{
    std::string num_text = std::to_string(number);
    std::string rounded = num_text.substr(0, num_text.find(".")+3);
	return rounded;
}

void refreshConsole() {

  switch (current_interface) {

  case MENU_INTERFACE:
    // unimplemented
    break;
  case SHELL_INTERFACE:
    // unimplemented
    break;
  case EDITOR_INTERFACE:
    // unimplemented
    break;
  case DEFAULT_INTERFACE:
    break;
  case BROWSER_INTERFACE:
    // unimplemented
    break;
  default:
    break;
  }

}

void projectM::key_handler( projectMEvent event,
                            projectMKeycode keycode, projectMModifier modifier ) {

	switch( event ) {

	case PROJECTM_KEYDOWN:

	  //default_key_handler();
	  switch (current_interface)
	    {

	    case MENU_INTERFACE:
//	      menu_key_handler(this, event, keycode);
	      break;
	    case SHELL_INTERFACE:
	      //shell_key_handler();
	      break;
	    case EDITOR_INTERFACE:
//	      editor_key_handler(event,keycode);
	      break;
	    case BROWSER_INTERFACE:
//	      browser_key_handler(event,keycode,modifier);
	      break;
	    case DEFAULT_INTERFACE:
	      default_key_handler(event,keycode);
	      break;
	    default:
	      default_key_handler(event,keycode);
	      break;

	    }
	  break;
	default:
		break;

	}
}

void projectM::default_key_handler( projectMEvent event, projectMKeycode keycode) {

	switch( event ) {

	case PROJECTM_KEYDOWN:

		switch (keycode)
		{
		case PROJECTM_K_HOME:
			if (renderer->showmenu) { // pageup only does something when the preset menu is active.
				selectPreset(0);  // jump to top of presets.
			}
			break;
		case PROJECTM_K_END:
			if (renderer->showmenu) { // pageup only does something when the preset menu is active.
				selectPreset(m_presetLoader->size() - 1);  // jump to bottom of presets.
			}
			break;
		case PROJECTM_K_PAGEUP:
			if (renderer->showmenu) { // pageup only does something when the preset menu is active.
				int upPreset = m_presetPos->lastIndex() - (renderer->textMenuPageSize / 2.0f); // jump up by page size / 2
				if (upPreset < 0) // handle lower boundary
					upPreset = m_presetLoader->size() - 1;
				selectPreset(upPreset);  // jump up menu half a page.
			}
			break;
		case PROJECTM_K_PAGEDOWN:
			if (renderer->showmenu) { // pagedown only does something when the preset menu is active.
				int downPreset = m_presetPos->lastIndex() + (renderer->textMenuPageSize / 2.0f); // jump down by page size / 2
				if (downPreset >= (m_presetLoader->size() - 1)) // handle upper boundary
					downPreset = 0;
				selectPreset(downPreset); // jump down menu half a page.
			}
			break;
		case PROJECTM_K_UP:
			if (renderer->showmenu) {
				selectPrevious(true);
			}
			else {
				beatDetect->beatSensitivity += 0.01;
				if (beatDetect->beatSensitivity > 5.0) beatDetect->beatSensitivity = 5.0;
				renderer->setToastMessage("Beat Sensitivity: " + round_float(beatDetect->beatSensitivity));
			}
			break;
		case PROJECTM_K_DOWN:
			if (renderer->showmenu) {
				selectNext(true);
			}
			else {
				beatDetect->beatSensitivity -= 0.01;
				if (beatDetect->beatSensitivity < 0) beatDetect->beatSensitivity = 0;
				renderer->setToastMessage("Beat Sensitivity: " + round_float(beatDetect->beatSensitivity));
			}
			break;
		case PROJECTM_K_h:
			renderer->showhelp = !renderer->showhelp;
			renderer->showstats = false;
			renderer->showmenu = false;
		case PROJECTM_K_F1:
			renderer->showhelp = !renderer->showhelp;
			renderer->showstats = false;
			renderer->showmenu = false;
			break;
		case PROJECTM_K_y:
			this->setShuffleEnabled(!this->isShuffleEnabled());
			if (this->isShuffleEnabled()) {
				renderer->setToastMessage("Shuffle Enabled");
			}
			else {
				renderer->setToastMessage("Shuffle Disabled");
			}
			break;

		case PROJECTM_K_F5:
			renderer->showfps = !renderer->showfps;
			// Initialize counters and reset frame count.
			renderer->lastTimeFPS = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
			renderer->currentTimeFPS = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
			renderer->totalframes = 0;
			// Hide preset name from screen and replace it with FPS counter.
			if (renderer->showfps)
			{
				renderer->showpreset = false;
			}
			break;
		case PROJECTM_K_F4:
			renderer->showstats = !renderer->showstats;
			if (renderer->showstats) {
				renderer->showhelp = false;
				renderer->showmenu = false;
			}
			break;
		case PROJECTM_K_F3: {
			renderer->showpreset = !renderer->showpreset;
			// Hide FPS from screen and replace it with preset name.
			if (renderer->showpreset)
			{
				renderer->showfps = false;
			}
			break;
		}
		case PROJECTM_K_F2:
			renderer->showtitle = !renderer->showtitle;
			break;
#ifndef MACOS
		case PROJECTM_K_F9:
#else
		case PROJECTM_K_F8:
#endif

			renderer->studio = !renderer->studio;
			break;

		case PROJECTM_K_ESCAPE: {
			//	        exit( 1 );
			break;
		}
		case PROJECTM_K_f:

			break;
		case PROJECTM_K_a:
			renderer->correction = !renderer->correction;
			break;
		case PROJECTM_K_b:
			break;
		case PROJECTM_K_H:
		case PROJECTM_K_m:
			renderer->showmenu = !renderer->showmenu;
			if (renderer->showmenu) {
				renderer->showhelp = false;
				renderer->showstats = false;
				populatePresetMenu();
			}
			break;
		case PROJECTM_K_M:
			renderer->showmenu = !renderer->showmenu;
			if (renderer->showmenu)
			{
				renderer->showhelp=false;
				renderer->showstats=false;
				populatePresetMenu();
			}
          break;
      case PROJECTM_K_n:
          selectNext(true);
          break;
      case PROJECTM_K_N:
          selectNext(false);
          break;
	    case PROJECTM_K_r:
		selectRandom(true);
		break;
	    case PROJECTM_K_R:
		selectRandom(false);
		break;
	    case PROJECTM_K_p:
	      selectPrevious(true);
	      break;
	    case PROJECTM_K_P:
	    case PROJECTM_K_BACKSPACE:
	      selectPrevious(false);
	      break;
	    case PROJECTM_K_l:
			setPresetLock(!isPresetLocked());
			break;
	    case PROJECTM_K_s:
            	renderer->studio = !renderer->studio;
	    case PROJECTM_K_i:
	        break;
	    case PROJECTM_K_z:
	      break;
	    case PROJECTM_K_0:
//	      nWaveMode=0;
	      break;
	    case PROJECTM_K_6:
//	      nWaveMode=6;
	      break;
	    case PROJECTM_K_7:
//	      nWaveMode=7;
	      break;
	    case PROJECTM_K_t:
	      break;
	    case PROJECTM_K_EQUALS:
	    case PROJECTM_K_PLUS:

	    	unsigned int index;

	    	if (selectedPresetIndex(index)) {

	    		const int oldRating = getPresetRating(index, HARD_CUT_RATING_TYPE);

	    		if (oldRating >= 6)
	    			  break;

	    		const int rating = oldRating + 1;

	    		changePresetRating(index, rating, HARD_CUT_RATING_TYPE);
	    	}

	    	break;

	    case PROJECTM_K_MINUS:
	    	if (selectedPresetIndex(index)) {

	    		const int oldRating = getPresetRating(index, HARD_CUT_RATING_TYPE);

	    		if (oldRating <= 1)
	    			  break;

	    		const int rating = oldRating - 1;

	    		changePresetRating(index, rating, HARD_CUT_RATING_TYPE);
	    	}
	    	break;

	    default:
	      break;
	    }
	default:
		break;

	}
}
<|endoftext|>


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

#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/eval/eval/tensor_function.h>
#include <vespa/eval/eval/test/eval_fixture.h>
#include <vespa/eval/eval/test/gen_spec.h>
#include <vespa/eval/instruction/join_with_number_function.h>

#include <vespa/vespalib/util/stringfmt.h>

using namespace vespalib;
using namespace vespalib::eval;
using namespace vespalib::eval::test;
using namespace vespalib::eval::tensor_function;

using vespalib::make_string_short::fmt;

using Primary = JoinWithNumberFunction::Primary;

namespace vespalib::eval {

std::ostream &operator<<(std::ostream &os, Primary primary)
{
    switch(primary) {
    case Primary::LHS: return os << "LHS";
    case Primary::RHS: return os << "RHS";
    }
    abort();
}

}

struct FunInfo {
    using LookFor = JoinWithNumberFunction;
    Primary primary;
    bool inplace;
    void verify(const EvalFixture &fixture, const LookFor &fun) const {
        EXPECT_TRUE(fun.result_is_mutable());
        EXPECT_EQUAL(fun.primary(), primary);
        EXPECT_EQUAL(fun.inplace(), inplace);
        if (inplace) {
            size_t idx = (fun.primary() == Primary::LHS) ? 0 : 1;
            EXPECT_EQUAL(fixture.result_value().cells().data,
                         fixture.param_value(idx).cells().data);
        }
    }
};

void verify_optimized(const vespalib::string &expr, Primary primary, bool inplace) {
    // fprintf(stderr, "%s\n", expr.c_str());
    const auto stable_types = CellTypeSpace({CellType::FLOAT, CellType::DOUBLE}, 2);
    FunInfo stable_details{primary, inplace};
    TEST_DO(EvalFixture::verify<FunInfo>(expr, {stable_details}, stable_types));
}

void verify_not_optimized(const vespalib::string &expr) {
    // fprintf(stderr, "%s\n", expr.c_str());
    CellTypeSpace all_types(CellTypeUtils::list_types(), 2);
    TEST_DO(EvalFixture::verify<FunInfo>(expr, {}, all_types));
}

TEST("require that dense number join can be optimized") {
    TEST_DO(verify_optimized("x3y5+reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)+x3y5", Primary::RHS, false));
    TEST_DO(verify_optimized("x3y5*reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)*x3y5", Primary::RHS, false));
}

TEST("require that dense number join can be inplace") {
    TEST_DO(verify_optimized("@x3y5*reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)*@x3y5", Primary::RHS, true));
    TEST_DO(verify_optimized("@x3y5+reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)+@x3y5", Primary::RHS, true));
}

TEST("require that asymmetric operations work") {
    TEST_DO(verify_optimized("x3y5/reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)/x3y5", Primary::RHS, false));
    TEST_DO(verify_optimized("x3y5-reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)-x3y5", Primary::RHS, false));
}

TEST("require that sparse number join can be optimized") {
    TEST_DO(verify_optimized("x3_1z2_1+reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)+x3_1z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1z2_1<reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)<x3_1z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1z2_1+reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)+x3_1z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1z2_1<reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)<x3_1z2_1", Primary::RHS, false));
}

TEST("require that sparse number join can be inplace") {
    TEST_DO(verify_optimized("@x3_1z2_1+reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)+@x3_1z2_1", Primary::RHS, true));
    TEST_DO(verify_optimized("@x3_1z2_1<reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)<@x3_1z2_1", Primary::RHS, true));
}

TEST("require that mixed number join can be optimized") {
    TEST_DO(verify_optimized("x3_1y5z2_1+reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)+x3_1y5z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1y5z2_1<reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)<x3_1y5z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1y5z2_1+reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)+x3_1y5z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1y5z2_1<reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)<x3_1y5z2_1", Primary::RHS, false));
}

TEST("require that mixed number join can be inplace") {
    TEST_DO(verify_optimized("@x3_1y5z2_1+reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)+@x3_1y5z2_1", Primary::RHS, true));
    TEST_DO(verify_optimized("@x3_1y5z2_1<reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)<@x3_1y5z2_1", Primary::RHS, true));
}

TEST("require that inappropriate cases are not optimized") {
    for (vespalib::string lhs: {"y5", "x3_1z2_1", "x3_1y5z2_1"}) {
        for (vespalib::string rhs: {"y5", "x3_1z2_1", "x3_1y5z2_1"}) {
            auto expr = fmt("%s$1*%s$2", lhs.c_str(), rhs.c_str());
            verify_not_optimized(expr);
        }
        verify_optimized(fmt("reduce(v3,sum)*%s", lhs.c_str()), Primary::RHS, false);
        verify_optimized(fmt("%s*reduce(v3,sum)", lhs.c_str()), Primary::LHS, false);
    }
    // two scalars -> not optimized
    verify_not_optimized("reduce(v3,sum)*reduce(k4,sum)");
}

TEST_MAIN() { TEST_RUN_ALL(); }
<commit_msg>test unstable cell types for JoinWithNumberFunction<commit_after>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/eval/eval/tensor_function.h>
#include <vespa/eval/eval/test/eval_fixture.h>
#include <vespa/eval/eval/test/gen_spec.h>
#include <vespa/eval/instruction/join_with_number_function.h>

#include <vespa/vespalib/util/stringfmt.h>

using namespace vespalib;
using namespace vespalib::eval;
using namespace vespalib::eval::test;
using namespace vespalib::eval::tensor_function;

using vespalib::make_string_short::fmt;

using Primary = JoinWithNumberFunction::Primary;

namespace vespalib::eval {

std::ostream &operator<<(std::ostream &os, Primary primary)
{
    switch(primary) {
    case Primary::LHS: return os << "LHS";
    case Primary::RHS: return os << "RHS";
    }
    abort();
}

}

struct FunInfo {
    using LookFor = JoinWithNumberFunction;
    Primary primary;
    bool inplace;
    void verify(const EvalFixture &fixture, const LookFor &fun) const {
        EXPECT_TRUE(fun.result_is_mutable());
        EXPECT_EQUAL(fun.primary(), primary);
        EXPECT_EQUAL(fun.inplace(), inplace);
        if (inplace) {
            size_t idx = (fun.primary() == Primary::LHS) ? 0 : 1;
            EXPECT_EQUAL(fixture.result_value().cells().data,
                         fixture.param_value(idx).cells().data);
        }
    }
};

void verify_optimized(const vespalib::string &expr, Primary primary, bool inplace) {
    // fprintf(stderr, "%s\n", expr.c_str());
    const auto stable_types = CellTypeSpace({CellType::FLOAT, CellType::DOUBLE}, 2);
    FunInfo stable_details{primary, inplace};
    TEST_DO(EvalFixture::verify<FunInfo>(expr, {stable_details}, stable_types));
    const auto unstable_types = CellTypeSpace({CellType::BFLOAT16, CellType::INT8}, 2);
    TEST_DO(EvalFixture::verify<FunInfo>(expr, {}, unstable_types));
}

void verify_not_optimized(const vespalib::string &expr) {
    // fprintf(stderr, "%s\n", expr.c_str());
    CellTypeSpace all_types(CellTypeUtils::list_types(), 2);
    TEST_DO(EvalFixture::verify<FunInfo>(expr, {}, all_types));
}

TEST("require that dense number join can be optimized") {
    TEST_DO(verify_optimized("x3y5+reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)+x3y5", Primary::RHS, false));
    TEST_DO(verify_optimized("x3y5*reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)*x3y5", Primary::RHS, false));
}

TEST("require that dense number join can be inplace") {
    TEST_DO(verify_optimized("@x3y5*reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)*@x3y5", Primary::RHS, true));
    TEST_DO(verify_optimized("@x3y5+reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)+@x3y5", Primary::RHS, true));
}

TEST("require that asymmetric operations work") {
    TEST_DO(verify_optimized("x3y5/reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)/x3y5", Primary::RHS, false));
    TEST_DO(verify_optimized("x3y5-reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)-x3y5", Primary::RHS, false));
}

TEST("require that sparse number join can be optimized") {
    TEST_DO(verify_optimized("x3_1z2_1+reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)+x3_1z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1z2_1<reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)<x3_1z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1z2_1+reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)+x3_1z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1z2_1<reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)<x3_1z2_1", Primary::RHS, false));
}

TEST("require that sparse number join can be inplace") {
    TEST_DO(verify_optimized("@x3_1z2_1+reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)+@x3_1z2_1", Primary::RHS, true));
    TEST_DO(verify_optimized("@x3_1z2_1<reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)<@x3_1z2_1", Primary::RHS, true));
}

TEST("require that mixed number join can be optimized") {
    TEST_DO(verify_optimized("x3_1y5z2_1+reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)+x3_1y5z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1y5z2_1<reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)<x3_1y5z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1y5z2_1+reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)+x3_1y5z2_1", Primary::RHS, false));
    TEST_DO(verify_optimized("x3_1y5z2_1<reduce(v3,sum)", Primary::LHS, false));
    TEST_DO(verify_optimized("reduce(v3,sum)<x3_1y5z2_1", Primary::RHS, false));
}

TEST("require that mixed number join can be inplace") {
    TEST_DO(verify_optimized("@x3_1y5z2_1+reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)+@x3_1y5z2_1", Primary::RHS, true));
    TEST_DO(verify_optimized("@x3_1y5z2_1<reduce(v3,sum)", Primary::LHS, true));
    TEST_DO(verify_optimized("reduce(v3,sum)<@x3_1y5z2_1", Primary::RHS, true));
}

TEST("require that inappropriate cases are not optimized") {
    for (vespalib::string lhs: {"y5", "x3_1z2_1", "x3_1y5z2_1"}) {
        for (vespalib::string rhs: {"y5", "x3_1z2_1", "x3_1y5z2_1"}) {
            auto expr = fmt("%s$1*%s$2", lhs.c_str(), rhs.c_str());
            verify_not_optimized(expr);
        }
        verify_optimized(fmt("reduce(v3,sum)*%s", lhs.c_str()), Primary::RHS, false);
        verify_optimized(fmt("%s*reduce(v3,sum)", lhs.c_str()), Primary::LHS, false);
    }
    // two scalars -> not optimized
    verify_not_optimized("reduce(v3,sum)*reduce(k4,sum)");
}

TEST_MAIN() { TEST_RUN_ALL(); }
<|endoftext|>