<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * 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 "modules/perception/obstacle/onboard/ultrasonic_obstacle_subnode.h"

#include <cmath>
#include <utility>

#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/log.h"
#include "modules/common/math/quaternion.h"
#include "modules/common/time/timer.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/perception/onboard/subnode_helper.h"

namespace apollo {
namespace perception {

using apollo::common::VehicleStateProvider;

void UltrasonicObstacleSubnode::OnUltrasonic(
    const apollo::canbus::Chassis& message) {
  ++seq_num_;
  PERF_BLOCK_START();
  std::shared_ptr<SensorObjects> sensor_objects(new SensorObjects);
  double timestamp = message.header().timestamp_sec();
  sensor_objects->timestamp = timestamp;
  sensor_objects->sensor_type = SensorType::ULTRASONIC;
  sensor_objects->sensor_id = device_id_;
  sensor_objects->seq_num = seq_num_;

  BuildAllObjects(message.surround(), sensor_objects);

  if (!PublishDataAndEvent(timestamp, sensor_objects)) {
    AERROR << "Failed to publish data.";
    sensor_objects->error_code = apollo::common::PERCEPTION_ERROR_PROCESS;
    return;
  }
  ADEBUG << "ultrasonic object size: " << sensor_objects->objects.size();
  PERF_BLOCK_END("ultrasonic_detect");
}

bool UltrasonicObstacleSubnode::PublishDataAndEvent(
    const double timestamp, const SharedDataPtr<SensorObjects>& data) {
  std::string key;
  if (!SubnodeHelper::ProduceSharedDataKey(timestamp, device_id_, &key)) {
    AERROR << "Failed to produce shared key. time: "
           << GLOG_TIMESTAMP(timestamp) << ", device_id: " << device_id_;
    return false;
  }

  for (size_t idx = 0; idx < pub_meta_events_.size(); ++idx) {
    const EventMeta& event_meta = pub_meta_events_[idx];
    Event event;
    event.event_id = event_meta.event_id;
    event.timestamp = timestamp;
    event.reserve = device_id_;
    event_manager_->Publish(event);
  }

  return true;
}

void UltrasonicObstacleSubnode::BuildSingleObject(
    const apollo::canbus::Sonar& sonar,
    std::shared_ptr<Object> object_ptr) {
  object_ptr->track_id = 0;
  object_ptr->type = ObjectType::UNKNOWN;
  object_ptr->velocity = {0.0, 0.0, 0.0};
  double vehicle_x = VehicleStateProvider::instance()->x();
  double vehicle_y = VehicleStateProvider::instance()->y();
  double vehicle_z = VehicleStateProvider::instance()->z();
  double vehicle_heading = VehicleStateProvider::instance()->heading();
  double sonar_x = vehicle_x + sonar.translation().x();
  double sonar_y = vehicle_y + sonar.translation().y();
  double sonar_z = vehicle_z + sonar.translation().z();
  double sonar_relative_heading = apollo::common::math::QuaternionToHeading(
      sonar.rotation().qw(), sonar.rotation().qx(),
      sonar.rotation().qy(), sonar.rotation().qz());
  double sonar_heading = vehicle_heading + sonar_relative_heading;
  double sonar_obs_x = sonar_x + sonar.range() * std::cos(sonar_heading);
  double sonar_obs_y = sonar_y + sonar.range() * std::cos(sonar_heading);
  double half_width = 0.2;  // TODO(kechxu) refactor
  double length = 0.2;  // TODO(kechxu) refactor
  double alpha = sonar_heading - M_PI / 2.0;
  std::vector<std::pair<double, double>> vertices;
  double near_left_x = sonar_obs_x - half_width * half_width * std::cos(alpha);
  double near_left_y = sonar_obs_y - half_width * half_width * std::sin(alpha);
  double near_right_x = sonar_obs_x + half_width * half_width * std::cos(alpha);
  double near_right_y = sonar_obs_y + half_width * half_width * std::sin(alpha);
  vertices.emplace_back(near_left_x, near_left_y);
  vertices.emplace_back(near_right_x, near_right_y);
  vertices.emplace_back(
      near_right_x + length * std::cos(sonar_heading),
      near_right_y + length * std::sin(sonar_heading));
  vertices.emplace_back(
      near_left_x + length * std::cos(sonar_heading),
      near_left_y + length * std::sin(sonar_heading));

  auto& polygon = object_ptr->polygon;
  polygon.resize(vertices.size());
  for (std::size_t i = 0; i < vertices.size(); ++i) {
    polygon.points[i].x = vertices[i].first;
    polygon.points[i].y = vertices[i].second;
    polygon.points[i].z = sonar_z;
  }
  CHECK_GT(polygon.points.size(), 0);
  object_ptr->theta = sonar_heading;
  Eigen::Vector3d direction(std::cos(sonar_heading),
                            std::sin(sonar_heading), 0.0);
  object_ptr->direction = direction;
  object_ptr->length = length;
  object_ptr->width = 2.0 * half_width;
  object_ptr->height = sonar_z;
  double anchor_x = 0.0;
  double anchor_y = 0.0;
  for (size_t i = 0; i < polygon.points.size(); ++i) {
    anchor_x += polygon.points[i].x;
    anchor_y += polygon.points[i].y;
  }
  anchor_x /= static_cast<double>(polygon.points.size());
  anchor_y /= static_cast<double>(polygon.points.size());
  double anchor_z = 0.5 * sonar_z;
  Eigen::Vector3d anchor_point(anchor_x, anchor_y, anchor_z);
  object_ptr->anchor_point = anchor_point;
  // TODO(kechxu) object_ptr->score_type
}

void UltrasonicObstacleSubnode::BuildAllObjects(
    const apollo::canbus::Surround& surround,
    std::shared_ptr<SensorObjects> sensor_objects) {
  for (const auto& sonar : surround.sonar()) {
    std::shared_ptr<Object> object_ptr(new Object);
    BuildSingleObject(sonar, object_ptr);
    sensor_objects->objects.push_back(std::move(object_ptr));
  }
}

}  // namespace perception
}  // namespace apollo
<commit_msg>Perception: ultrasonic subnode InitInternal()<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * 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 "modules/perception/obstacle/onboard/ultrasonic_obstacle_subnode.h"

#include <cmath>
#include <utility>
#include <unordered_map>

#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/log.h"
#include "modules/common/math/quaternion.h"
#include "modules/common/time/timer.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/perception/onboard/subnode_helper.h"

namespace apollo {
namespace perception {

using apollo::common::adapter::AdapterManager;
using apollo::common::VehicleStateProvider;

bool UltrasonicObstacleSubnode::InitInternal() {
  // parse reserve fileds
  std::unordered_map<std::string, std::string> reserve_field_map;
  if (!SubnodeHelper::ParseReserveField(reserve_, &reserve_field_map)) {
    AERROR << "Failed to parse reserve filed: " << reserve_;
    return false;
  }

  if (reserve_field_map.find("device_id") == reserve_field_map.end()) {
    AERROR << "Failed to find field device_id, reserve: " << reserve_;
    return false;
  }
  device_id_ = reserve_field_map["device_id"];

  CHECK(AdapterManager::GetChassis()) << "Failed to get Ultrasonic adapter";
  AdapterManager::AddChassisCallback(
      &UltrasonicObstacleSubnode::OnUltrasonic, this);

  ADEBUG << "Succeed to finish ultrasonic detector initialization!";

  return true;
}

void UltrasonicObstacleSubnode::OnUltrasonic(
    const apollo::canbus::Chassis& message) {
  ++seq_num_;
  PERF_BLOCK_START();
  std::shared_ptr<SensorObjects> sensor_objects(new SensorObjects);
  double timestamp = message.header().timestamp_sec();
  sensor_objects->timestamp = timestamp;
  sensor_objects->sensor_type = SensorType::ULTRASONIC;
  sensor_objects->sensor_id = device_id_;
  sensor_objects->seq_num = seq_num_;

  BuildAllObjects(message.surround(), sensor_objects);

  if (!PublishDataAndEvent(timestamp, sensor_objects)) {
    AERROR << "Failed to publish data.";
    sensor_objects->error_code = apollo::common::PERCEPTION_ERROR_PROCESS;
    return;
  }
  ADEBUG << "ultrasonic object size: " << sensor_objects->objects.size();
  PERF_BLOCK_END("ultrasonic_detect");
}

bool UltrasonicObstacleSubnode::PublishDataAndEvent(
    const double timestamp, const SharedDataPtr<SensorObjects>& data) {
  std::string key;
  if (!SubnodeHelper::ProduceSharedDataKey(timestamp, device_id_, &key)) {
    AERROR << "Failed to produce shared key. time: "
           << GLOG_TIMESTAMP(timestamp) << ", device_id: " << device_id_;
    return false;
  }

  for (size_t idx = 0; idx < pub_meta_events_.size(); ++idx) {
    const EventMeta& event_meta = pub_meta_events_[idx];
    Event event;
    event.event_id = event_meta.event_id;
    event.timestamp = timestamp;
    event.reserve = device_id_;
    event_manager_->Publish(event);
  }

  return true;
}

void UltrasonicObstacleSubnode::BuildSingleObject(
    const apollo::canbus::Sonar& sonar,
    std::shared_ptr<Object> object_ptr) {
  object_ptr->track_id = 0;
  object_ptr->type = ObjectType::UNKNOWN;
  object_ptr->velocity = {0.0, 0.0, 0.0};
  double vehicle_x = VehicleStateProvider::instance()->x();
  double vehicle_y = VehicleStateProvider::instance()->y();
  double vehicle_z = VehicleStateProvider::instance()->z();
  double vehicle_heading = VehicleStateProvider::instance()->heading();
  double sonar_x = vehicle_x + sonar.translation().x();
  double sonar_y = vehicle_y + sonar.translation().y();
  double sonar_z = vehicle_z + sonar.translation().z();
  double sonar_relative_heading = apollo::common::math::QuaternionToHeading(
      sonar.rotation().qw(), sonar.rotation().qx(),
      sonar.rotation().qy(), sonar.rotation().qz());
  double sonar_heading = vehicle_heading + sonar_relative_heading;
  double sonar_obs_x = sonar_x + sonar.range() * std::cos(sonar_heading);
  double sonar_obs_y = sonar_y + sonar.range() * std::cos(sonar_heading);
  double half_width = 0.2;  // TODO(kechxu) refactor
  double length = 0.2;  // TODO(kechxu) refactor
  double alpha = sonar_heading - M_PI / 2.0;
  std::vector<std::pair<double, double>> vertices;
  double near_left_x = sonar_obs_x - half_width * half_width * std::cos(alpha);
  double near_left_y = sonar_obs_y - half_width * half_width * std::sin(alpha);
  double near_right_x = sonar_obs_x + half_width * half_width * std::cos(alpha);
  double near_right_y = sonar_obs_y + half_width * half_width * std::sin(alpha);
  vertices.emplace_back(near_left_x, near_left_y);
  vertices.emplace_back(near_right_x, near_right_y);
  vertices.emplace_back(
      near_right_x + length * std::cos(sonar_heading),
      near_right_y + length * std::sin(sonar_heading));
  vertices.emplace_back(
      near_left_x + length * std::cos(sonar_heading),
      near_left_y + length * std::sin(sonar_heading));

  auto& polygon = object_ptr->polygon;
  polygon.resize(vertices.size());
  for (std::size_t i = 0; i < vertices.size(); ++i) {
    polygon.points[i].x = vertices[i].first;
    polygon.points[i].y = vertices[i].second;
    polygon.points[i].z = sonar_z;
  }
  CHECK_GT(polygon.points.size(), 0);
  object_ptr->theta = sonar_heading;
  Eigen::Vector3d direction(std::cos(sonar_heading),
                            std::sin(sonar_heading), 0.0);
  object_ptr->direction = direction;
  object_ptr->length = length;
  object_ptr->width = 2.0 * half_width;
  object_ptr->height = sonar_z;
  double anchor_x = 0.0;
  double anchor_y = 0.0;
  for (size_t i = 0; i < polygon.points.size(); ++i) {
    anchor_x += polygon.points[i].x;
    anchor_y += polygon.points[i].y;
  }
  anchor_x /= static_cast<double>(polygon.points.size());
  anchor_y /= static_cast<double>(polygon.points.size());
  double anchor_z = 0.5 * sonar_z;
  Eigen::Vector3d anchor_point(anchor_x, anchor_y, anchor_z);
  object_ptr->anchor_point = anchor_point;
  // TODO(kechxu) object_ptr->score_type
}

void UltrasonicObstacleSubnode::BuildAllObjects(
    const apollo::canbus::Surround& surround,
    std::shared_ptr<SensorObjects> sensor_objects) {
  for (const auto& sonar : surround.sonar()) {
    std::shared_ptr<Object> object_ptr(new Object);
    BuildSingleObject(sonar, object_ptr);
    sensor_objects->objects.push_back(std::move(object_ptr));
  }
}

}  // namespace perception
}  // namespace apollo
<|endoftext|>


<commit_before>#include "Util/Log.hpp"
#include "MainWindow.hpp"
#include "Manager/Managers.hpp"
#include "Manager/RenderManager.hpp"
#include <GL/glew.h>
#include <GLFW/glfw3.h>

MainWindow* MainWindow::instance = nullptr;
void window_size_callback(GLFWwindow* window, int width, int height);

MainWindow::MainWindow(int width, int height, bool fullscreen, bool borderless, const char* title, bool debugContext) {
    glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);

    if (borderless)
        glfwWindowHint(GLFW_DECORATED, GL_FALSE);

    this->debugContext = debugContext;
    if (debugContext)
        glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);

    GLFWmonitor* monitor = fullscreen ? glfwGetPrimaryMonitor() : nullptr;

    window = glfwCreateWindow(width, height, title, monitor, nullptr);

    if (!window) {
        glfwTerminate();
        /// @todo Print error to log.
    }

    glfwMakeContextCurrent(window);

    // Setup error callbacks.
    glfwSetErrorCallback(ErrorCallback);

    input = new InputHandler(window);
    input->Update();
    input->SetActive();

    size = glm::vec2(width, height);
    instance = this;

    glfwSetWindowSizeCallback(window, WindowSizeCallback);

}

MainWindow::~MainWindow() {
    glfwDestroyWindow(window);
    delete input;
}

MainWindow* MainWindow::GetInstance() {
    return instance;
}

void MainWindow::Init(bool showNotifications) {
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_PROGRAM_POINT_SIZE);

    if (debugContext)
        glDebugMessageCallback(showNotifications ? DebugMessageCallback : DebugMessageCallbackIgnoreNotifications, nullptr);
}

void MainWindow::SetVsync(bool vsync) {
    glfwSwapInterval(vsync ? 1 : 0);
}

void MainWindow::Update() {
    input->Update();
    input->SetActive();

    if (glfwWindowShouldClose(window) != GL_FALSE)
        shouldClose = true;
}

const glm::vec2& MainWindow::GetSize() const {
    return size;
}

void MainWindow::SetSize(int width, int height){
    size.x = width;
    size.y = height;
}

void MainWindow::SetTitle(const char *title) {
    glfwSetWindowTitle(window, title);
}

bool MainWindow::ShouldClose() const {
    return shouldClose;
}

void MainWindow::Close() {
    shouldClose = true;
}

void MainWindow::SwapBuffers() {
    glfwSwapBuffers(window);
}

GLFWwindow* MainWindow::GetGLFWWindow() const {
    return window;
}

void WindowSizeCallback(GLFWwindow* window, int width, int height)
{

    MainWindow::GetInstance()->SetSize(width, height);
    Managers().renderManager->UpdateBufferSize();

}<commit_msg>Fixed wrongly named forward declaration<commit_after>#include "Util/Log.hpp"
#include "MainWindow.hpp"
#include "Manager/Managers.hpp"
#include "Manager/RenderManager.hpp"
#include <GL/glew.h>
#include <GLFW/glfw3.h>

MainWindow* MainWindow::instance = nullptr;
void WindowSizeCallback(GLFWwindow* window, int width, int height);

MainWindow::MainWindow(int width, int height, bool fullscreen, bool borderless, const char* title, bool debugContext) {
    glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);

    if (borderless)
        glfwWindowHint(GLFW_DECORATED, GL_FALSE);

    this->debugContext = debugContext;
    if (debugContext)
        glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);

    GLFWmonitor* monitor = fullscreen ? glfwGetPrimaryMonitor() : nullptr;

    window = glfwCreateWindow(width, height, title, monitor, nullptr);

    if (!window) {
        glfwTerminate();
        /// @todo Print error to log.
    }

    glfwMakeContextCurrent(window);

    // Setup error callbacks.
    glfwSetErrorCallback(ErrorCallback);

    input = new InputHandler(window);
    input->Update();
    input->SetActive();

    size = glm::vec2(width, height);
    instance = this;

    glfwSetWindowSizeCallback(window, WindowSizeCallback);

}

MainWindow::~MainWindow() {
    glfwDestroyWindow(window);
    delete input;
}

MainWindow* MainWindow::GetInstance() {
    return instance;
}

void MainWindow::Init(bool showNotifications) {
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_PROGRAM_POINT_SIZE);

    if (debugContext)
        glDebugMessageCallback(showNotifications ? DebugMessageCallback : DebugMessageCallbackIgnoreNotifications, nullptr);
}

void MainWindow::SetVsync(bool vsync) {
    glfwSwapInterval(vsync ? 1 : 0);
}

void MainWindow::Update() {
    input->Update();
    input->SetActive();

    if (glfwWindowShouldClose(window) != GL_FALSE)
        shouldClose = true;
}

const glm::vec2& MainWindow::GetSize() const {
    return size;
}

void MainWindow::SetSize(int width, int height){
    size.x = width;
    size.y = height;
}

void MainWindow::SetTitle(const char *title) {
    glfwSetWindowTitle(window, title);
}

bool MainWindow::ShouldClose() const {
    return shouldClose;
}

void MainWindow::Close() {
    shouldClose = true;
}

void MainWindow::SwapBuffers() {
    glfwSwapBuffers(window);
}

GLFWwindow* MainWindow::GetGLFWWindow() const {
    return window;
}

void WindowSizeCallback(GLFWwindow* window, int width, int height)
{

    MainWindow::GetInstance()->SetSize(width, height);
    Managers().renderManager->UpdateBufferSize();

}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_pm_pstate_gpe_init.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_pm_pstate_gpe_init.C
/// @brief  Stop, reset and initalize/start the Pstate GPE
///
// *HWP HWP Owner:          Greg Still <stillgs@us.ibm.com>
// *HWP BackupHWP Owner:    Amit Kumar <akumar3@us.ibm.com>
// *HWP FW Owner:           Sangeetha T S <sangeet2@in.ibm.com>
// *HWP Team: PM
// *HWP Level: 2
// *HWP Consumed by: FSP:HS

// -----------------------------------------------------------------------------
//  Includes
// -----------------------------------------------------------------------------
#include <p9_pm_pstate_gpe_init.H>

// -----------------------------------------------------------------------------
// Constants
// -----------------------------------------------------------------------------
// @todo RTC 148540 Refine this values for the lab
// Following constants hold an approximate value.
static const uint32_t PGPE_TIMEOUT_MS       = 500;
static const uint32_t PGPE_TIMEOUT_MCYCLES  = 20;
static const uint32_t PGPE_POLLTIME_MS      = 20;
static const uint32_t PGPE_POLLTIME_MCYCLES = 2;
static const uint32_t TIMEOUT_COUNT = PGPE_TIMEOUT_MS / PGPE_POLLTIME_MS;

// -----------------------------------------------------------------------------
//  Function definitions
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
//  Pstate GPE Initialization Function
// -----------------------------------------------------------------------------

/// @brief Initializes the Pstate GPE and related Pstate functions on a chip
///
/// @param [in] i_target Chip target
///
/// @retval FAPI_RC_SUCCESS else ERROR defined in xml

fapi2::ReturnCode pstate_gpe_init(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    fapi2::buffer<uint64_t> l_data64;
    fapi2::buffer<uint64_t> l_occ_scratch2;
    fapi2::buffer<uint64_t> l_xcr;
    fapi2::buffer<uint64_t> l_xsr;
    fapi2::buffer<uint64_t> l_ivpr;
    uint32_t                l_ivpr_offset = 0;
    uint32_t                l_xsr_halt_condition = 0;
    uint32_t                l_timeout_counter = TIMEOUT_COUNT;

    FAPI_IMP(">> pstate_gpe_init......");

    FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_PSTATEGPE_BOOT_COPIER_IVPR_OFFSET,
                            i_target,
                            l_ivpr_offset),
              "Error getting ATTR_PSTATEGPE_BOOT_COPIER_IVPR_OFFSET");

    // Program PGPE IVPR
    l_ivpr.flush<0>().insertFromRight<0, 32>(l_ivpr_offset);
    FAPI_INF("   Writing IVPR with 0x%16llX", l_ivpr);
    FAPI_TRY(putScom(i_target, PU_GPE2_GPEIVPR_SCOM, l_ivpr));

    // Clear the PGPE active bit before attempting the boot
    FAPI_TRY(getScom(i_target, PU_OCB_OCI_OCCS2_SCOM, l_occ_scratch2));
    FAPI_INF("   Clear PGPE_ACTIVE in OCC Scratch 2 Register...");
    l_occ_scratch2.clearBit<p9hcd::PGPE_ACTIVE>();
    FAPI_TRY(putScom(i_target, PU_OCB_OCI_OCCS2_SCOM, l_occ_scratch2));

    // Program XCR to ACTIVATE PGPE
    // @todo RTC 146665 Operations to PPEs should use a p9ppe namespace
    FAPI_INF("   Starting the PGPE...");
    l_xcr.flush<0>().insertFromRight(p9hcd::HARD_RESET, 1, 3);
    FAPI_TRY(putScom(i_target, PU_GPE2_PPE_XIXCR, l_xcr));
    l_xcr.flush<0>().insertFromRight(p9hcd::TOGGLE_XSR_TRH, 1 , 3);
    FAPI_TRY(putScom(i_target, PU_GPE2_PPE_XIXCR, l_xcr));
    l_xcr.flush<0>().insertFromRight(p9hcd::RESUME, 1, 3);
    FAPI_TRY(putScom(i_target, PU_GPE2_PPE_XIXCR, l_xcr));

    // Now wait for PGPE to boot
    FAPI_DBG("   Poll for PGPE Active for %d ms", PGPE_TIMEOUT_MS);
    l_occ_scratch2.flush<0>();
    l_xsr.flush<0>();

    do
    {
        FAPI_TRY(getScom(i_target, PU_OCB_OCI_OCCS2_SCOM, l_occ_scratch2));
        FAPI_TRY(getScom(i_target, PU_GPE2_GPEXIXSR_SCOM, l_xsr));
        FAPI_DBG("OCC Scratch2: 0x%016lx; XSR: 0x%016lx Timeout: %d",
                 l_occ_scratch2, l_xsr, l_timeout_counter);
        fapi2::delay(PGPE_POLLTIME_MS * 1000, PGPE_POLLTIME_MCYCLES * 1000 * 1000);
    }
    while((l_occ_scratch2.getBit<p9hcd::PGPE_ACTIVE>() != 1) &&
          (l_xsr.getBit<p9hcd::HALTED_STATE>() != 1) &&
          (--l_timeout_counter != 0));

    // Extract the halt condition
    l_xsr.extractToRight<uint32_t>(l_xsr_halt_condition,
                                   p9hcd::HALT_CONDITION_START,
                                   p9hcd::HALT_CONDITION_LEN);
    FAPI_DBG("halt state: XSR: 0x%016lx condition: %d",
             l_xsr, l_xsr_halt_condition);

    // Check for a debug halt condition
    FAPI_ASSERT(!((l_xsr.getBit<p9hcd::HALTED_STATE>() == 1) &&
                  ((l_xsr_halt_condition == p9hcd::DEBUG_HALT ||
                    l_xsr_halt_condition == p9hcd::DBCR_HALT)   )),
                fapi2::PSTATE_GPE_INIT_DEBUG_HALT()
                .set_CHIP(i_target),
                "Pstate GPE Debug Halt detected");

    // @todo 146665 Need to collect PGPE state. Operations to PPEs should
    // use a p9ppe namespace class when created

    // When PGPE fails to boot, assert out
    FAPI_ASSERT((l_timeout_counter != 0 &&
                 l_occ_scratch2.getBit<p9hcd::PGPE_ACTIVE>() == 1 &&
                 l_xsr.getBit<p9hcd::HALTED_STATE>() != 1),
                fapi2::PSTATE_GPE_INIT_TIMEOUT()
                .set_CHIP(i_target),
                "Pstate GPE Init timeout");

    if(( 1 == l_occ_scratch2.getBit<p9hcd::PGPE_ACTIVE>() ))
    {
        FAPI_INF("  PGPE was activated successfully!!!!");
    }

fapi_try_exit:
    FAPI_IMP("<< pstate_gpe_init......");
    return fapi2::current_err;
}

// -----------------------------------------------------------------------------
//  Pstate GPE Reset Function
// -----------------------------------------------------------------------------

/// @brief Stops the Pstate GPE
///
/// @param [in] i_target Chip target
///
/// @retval FAPI_RC_SUCCESS else ERROR defined in xml

fapi2::ReturnCode pstate_gpe_reset(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{

    fapi2::buffer<uint64_t> l_data64;
    uint32_t                l_timeout_in_MS = 100;

    FAPI_IMP(">> pstate_gpe_reset...");

    // Program XCR to HALT PGPE
    // @todo This should be replaced by a call to a common PPE service class
    // ppe<PPE_TYPE_GPE>GPE2(3);
    // GPE2.hard_reset();
    FAPI_INF("   Send HALT command via XCR...");
    l_data64.flush<0>().insertFromRight(p9hcd::HALT, 1, 3);
    FAPI_TRY(putScom(i_target, PU_GPE2_PPE_XIXCR, l_data64));

    // Now wait for PGPE to be halted.
    // @todo This loop should be replace by a call to a common PPE service class
    // FAPI_TRY(GPE2.is_halted(&b_halted_state,
    //                         timeout_value_ns,
    //                         timeout_value_simcycles));
    FAPI_INF("   Poll for HALT State via XSR...");

    do
    {
        FAPI_TRY(getScom(i_target, PU_GPE2_GPEXIXSR_SCOM, l_data64));
        fapi2::delay(PGPE_POLLTIME_MS * 1000, PGPE_POLLTIME_MCYCLES * 1000 * 1000);
    }
    while((l_data64.getBit<p9hcd::HALTED_STATE>() == 0) &&
          (--l_timeout_in_MS != 0));

    // When PGPE fails to halt, then assert ot
    FAPI_ASSERT((l_timeout_in_MS != 0),
                fapi2::PSTATE_GPE_RESET_TIMEOUT()
                .set_CHIP(i_target),
                "PSTATE GPE Init timeout");

    FAPI_TRY(getScom(i_target, PU_OCB_OCI_OCCS2_SCOM, l_data64));
    FAPI_INF("   Clear PGPE_ACTIVE in OCC Flag Register...");
    l_data64.flush<0>().clearBit<p9hcd::PGPE_ACTIVE>();
    FAPI_TRY(putScom(i_target, PU_OCB_OCI_OCCS2_SCOM, l_data64));

fapi_try_exit:
    FAPI_IMP("<< pstate_gpe_reset...");
    return fapi2::current_err;

}

// -----------------------------------------------------------------------------
//  p9_pm_pstate_gpe_init Function
// -----------------------------------------------------------------------------
fapi2::ReturnCode p9_pm_pstate_gpe_init(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const p9pm::PM_FLOW_MODE i_mode)
{
    FAPI_IMP("> p9_pm_pstate_gpe_init");

    const char* PM_MODE_NAME_VAR; //Defines storage for PM_MODE_NAME
    FAPI_INF("Executing p9_pstate_gpe_init in mode %s", PM_MODE_NAME(i_mode));

    // Boot the PSTATE GPE
    if (i_mode == p9pm::PM_INIT)
    {
        FAPI_TRY(pstate_gpe_init(i_target),
                 "ERROR: failed to initialize Pstate GPE");

        // Setup the PBA channels for run-time operation (eg when the PPC405 and its GPEs are active).
        FAPI_EXEC_HWP(fapi2::current_err,
                      p9_pm_pba_init,
                      i_target,
                      p9pm::PM_INIT);

        FAPI_ASSERT(fapi2::current_err == fapi2::FAPI2_RC_SUCCESS,
                    fapi2::PSTATE_GPE_PBA_INIT_FAILED()
                    .set_CHIP(i_target)
                    .set_MODE(p9pm::PM_INIT),
                    "PBA setup failed");
    }

    // Reset the PSTATE GPE
    else if (i_mode == p9pm::PM_RESET)
    {
        FAPI_TRY(pstate_gpe_reset(i_target), "ERROR:failed to reset Pstate GPE");
    }

    // Unsupported Mode
    else
    {
        FAPI_ERR("Unknown mode %x passed to p9_pstate_gpe_init.", i_mode);
        FAPI_ASSERT(false,
                    fapi2::PSTATE_GPE_BAD_MODE()
                    .set_BADMODE(i_mode),
                    "ERROR; Unknown mode passed to pstate_gpe_init. Mode %x",
                    i_mode);
    }

fapi_try_exit:
    FAPI_IMP("< p9_pm_pstate_gpe_init");
    return fapi2::current_err;
}
<commit_msg>Correct PState and Stop GPE polling period to 500ms vs 500us<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_pm_pstate_gpe_init.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_pm_pstate_gpe_init.C
/// @brief  Stop, reset and initalize/start the Pstate GPE
///
// *HWP HWP Owner:          Greg Still <stillgs@us.ibm.com>
// *HWP BackupHWP Owner:    Amit Kumar <akumar3@us.ibm.com>
// *HWP FW Owner:           Sangeetha T S <sangeet2@in.ibm.com>
// *HWP Team: PM
// *HWP Level: 2
// *HWP Consumed by: FSP:HS

// -----------------------------------------------------------------------------
//  Includes
// -----------------------------------------------------------------------------
#include <p9_pm_pstate_gpe_init.H>

// -----------------------------------------------------------------------------
// Constants
// -----------------------------------------------------------------------------
// @todo RTC 148540 Refine this values for the lab
// Following constants hold an approximate value.
static const uint32_t PGPE_TIMEOUT_MS       = 500;
static const uint32_t PGPE_TIMEOUT_MCYCLES  = 20;
static const uint32_t PGPE_POLLTIME_MS      = 20;
static const uint32_t PGPE_POLLTIME_MCYCLES = 2;
static const uint32_t TIMEOUT_COUNT = PGPE_TIMEOUT_MS / PGPE_POLLTIME_MS;

// -----------------------------------------------------------------------------
//  Function definitions
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
//  Pstate GPE Initialization Function
// -----------------------------------------------------------------------------

/// @brief Initializes the Pstate GPE and related Pstate functions on a chip
///
/// @param [in] i_target Chip target
///
/// @retval FAPI_RC_SUCCESS else ERROR defined in xml

fapi2::ReturnCode pstate_gpe_init(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    fapi2::buffer<uint64_t> l_data64;
    fapi2::buffer<uint64_t> l_occ_scratch2;
    fapi2::buffer<uint64_t> l_xcr;
    fapi2::buffer<uint64_t> l_xsr;
    fapi2::buffer<uint64_t> l_ivpr;
    uint32_t                l_ivpr_offset = 0;
    uint32_t                l_xsr_halt_condition = 0;
    uint32_t                l_timeout_counter = TIMEOUT_COUNT;

    FAPI_IMP(">> pstate_gpe_init......");

    FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_PSTATEGPE_BOOT_COPIER_IVPR_OFFSET,
                            i_target,
                            l_ivpr_offset),
              "Error getting ATTR_PSTATEGPE_BOOT_COPIER_IVPR_OFFSET");

    // Program PGPE IVPR
    l_ivpr.flush<0>().insertFromRight<0, 32>(l_ivpr_offset);
    FAPI_INF("   Writing IVPR with 0x%16llX", l_ivpr);
    FAPI_TRY(putScom(i_target, PU_GPE2_GPEIVPR_SCOM, l_ivpr));

    // Clear the PGPE active bit before attempting the boot
    FAPI_TRY(getScom(i_target, PU_OCB_OCI_OCCS2_SCOM, l_occ_scratch2));
    FAPI_INF("   Clear PGPE_ACTIVE in OCC Scratch 2 Register...");
    l_occ_scratch2.clearBit<p9hcd::PGPE_ACTIVE>();
    FAPI_TRY(putScom(i_target, PU_OCB_OCI_OCCS2_SCOM, l_occ_scratch2));

    // Program XCR to ACTIVATE PGPE
    // @todo RTC 146665 Operations to PPEs should use a p9ppe namespace
    FAPI_INF("   Starting the PGPE...");
    l_xcr.flush<0>().insertFromRight(p9hcd::HARD_RESET, 1, 3);
    FAPI_TRY(putScom(i_target, PU_GPE2_PPE_XIXCR, l_xcr));
    l_xcr.flush<0>().insertFromRight(p9hcd::TOGGLE_XSR_TRH, 1 , 3);
    FAPI_TRY(putScom(i_target, PU_GPE2_PPE_XIXCR, l_xcr));
    l_xcr.flush<0>().insertFromRight(p9hcd::RESUME, 1, 3);
    FAPI_TRY(putScom(i_target, PU_GPE2_PPE_XIXCR, l_xcr));

    // Now wait for PGPE to boot
    FAPI_DBG("   Poll for PGPE Active for %d ms", PGPE_TIMEOUT_MS);
    l_occ_scratch2.flush<0>();
    l_xsr.flush<0>();

    do
    {
        FAPI_TRY(getScom(i_target, PU_OCB_OCI_OCCS2_SCOM, l_occ_scratch2));
        FAPI_TRY(getScom(i_target, PU_GPE2_GPEXIXSR_SCOM, l_xsr));
        FAPI_DBG("OCC Scratch2: 0x%016lx; XSR: 0x%016lx Timeout: %d",
                 l_occ_scratch2, l_xsr, l_timeout_counter);
        // fapi2::delay takes ns as the arg
        fapi2::delay(PGPE_POLLTIME_MS * 1000 * 1000, PGPE_POLLTIME_MCYCLES * 1000 * 1000);
    }
    while((l_occ_scratch2.getBit<p9hcd::PGPE_ACTIVE>() != 1) &&
          (l_xsr.getBit<p9hcd::HALTED_STATE>() != 1) &&
          (--l_timeout_counter != 0));

    // Extract the halt condition
    l_xsr.extractToRight<uint32_t>(l_xsr_halt_condition,
                                   p9hcd::HALT_CONDITION_START,
                                   p9hcd::HALT_CONDITION_LEN);
    FAPI_DBG("halt state: XSR: 0x%016lx condition: %d",
             l_xsr, l_xsr_halt_condition);

    // Check for a debug halt condition
    FAPI_ASSERT(!((l_xsr.getBit<p9hcd::HALTED_STATE>() == 1) &&
                  ((l_xsr_halt_condition == p9hcd::DEBUG_HALT ||
                    l_xsr_halt_condition == p9hcd::DBCR_HALT)   )),
                fapi2::PSTATE_GPE_INIT_DEBUG_HALT()
                .set_CHIP(i_target),
                "Pstate GPE Debug Halt detected");

    // @todo 146665 Need to collect PGPE state. Operations to PPEs should
    // use a p9ppe namespace class when created

    // When PGPE fails to boot, assert out
    FAPI_ASSERT((l_timeout_counter != 0 &&
                 l_occ_scratch2.getBit<p9hcd::PGPE_ACTIVE>() == 1 &&
                 l_xsr.getBit<p9hcd::HALTED_STATE>() != 1),
                fapi2::PSTATE_GPE_INIT_TIMEOUT()
                .set_CHIP(i_target),
                "Pstate GPE Init timeout");

    if(( 1 == l_occ_scratch2.getBit<p9hcd::PGPE_ACTIVE>() ))
    {
        FAPI_INF("  PGPE was activated successfully!!!!");
    }

fapi_try_exit:
    FAPI_IMP("<< pstate_gpe_init......");
    return fapi2::current_err;
}

// -----------------------------------------------------------------------------
//  Pstate GPE Reset Function
// -----------------------------------------------------------------------------

/// @brief Stops the Pstate GPE
///
/// @param [in] i_target Chip target
///
/// @retval FAPI_RC_SUCCESS else ERROR defined in xml

fapi2::ReturnCode pstate_gpe_reset(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{

    fapi2::buffer<uint64_t> l_data64;
    uint32_t                l_timeout_in_MS = 100;

    FAPI_IMP(">> pstate_gpe_reset...");

    // Program XCR to HALT PGPE
    // @todo This should be replaced by a call to a common PPE service class
    // ppe<PPE_TYPE_GPE>GPE2(3);
    // GPE2.hard_reset();
    FAPI_INF("   Send HALT command via XCR...");
    l_data64.flush<0>().insertFromRight(p9hcd::HALT, 1, 3);
    FAPI_TRY(putScom(i_target, PU_GPE2_PPE_XIXCR, l_data64));

    // Now wait for PGPE to be halted.
    // @todo This loop should be replace by a call to a common PPE service class
    // FAPI_TRY(GPE2.is_halted(&b_halted_state,
    //                         timeout_value_ns,
    //                         timeout_value_simcycles));
    FAPI_INF("   Poll for HALT State via XSR...");

    do
    {
        FAPI_TRY(getScom(i_target, PU_GPE2_GPEXIXSR_SCOM, l_data64));
        fapi2::delay(PGPE_POLLTIME_MS * 1000 * 1000, PGPE_POLLTIME_MCYCLES * 1000 * 1000);
    }
    while((l_data64.getBit<p9hcd::HALTED_STATE>() == 0) &&
          (--l_timeout_in_MS != 0));

    // When PGPE fails to halt, then assert ot
    FAPI_ASSERT((l_timeout_in_MS != 0),
                fapi2::PSTATE_GPE_RESET_TIMEOUT()
                .set_CHIP(i_target),
                "PSTATE GPE Init timeout");

    FAPI_TRY(getScom(i_target, PU_OCB_OCI_OCCS2_SCOM, l_data64));
    FAPI_INF("   Clear PGPE_ACTIVE in OCC Flag Register...");
    l_data64.flush<0>().clearBit<p9hcd::PGPE_ACTIVE>();
    FAPI_TRY(putScom(i_target, PU_OCB_OCI_OCCS2_SCOM, l_data64));

fapi_try_exit:
    FAPI_IMP("<< pstate_gpe_reset...");
    return fapi2::current_err;

}

// -----------------------------------------------------------------------------
//  p9_pm_pstate_gpe_init Function
// -----------------------------------------------------------------------------
fapi2::ReturnCode p9_pm_pstate_gpe_init(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const p9pm::PM_FLOW_MODE i_mode)
{
    FAPI_IMP("> p9_pm_pstate_gpe_init");

    const char* PM_MODE_NAME_VAR; //Defines storage for PM_MODE_NAME
    FAPI_INF("Executing p9_pstate_gpe_init in mode %s", PM_MODE_NAME(i_mode));

    // Boot the PSTATE GPE
    if (i_mode == p9pm::PM_INIT)
    {
        FAPI_TRY(pstate_gpe_init(i_target),
                 "ERROR: failed to initialize Pstate GPE");

        // Setup the PBA channels for run-time operation (eg when the PPC405 and its GPEs are active).
        FAPI_EXEC_HWP(fapi2::current_err,
                      p9_pm_pba_init,
                      i_target,
                      p9pm::PM_INIT);

        FAPI_ASSERT(fapi2::current_err == fapi2::FAPI2_RC_SUCCESS,
                    fapi2::PSTATE_GPE_PBA_INIT_FAILED()
                    .set_CHIP(i_target)
                    .set_MODE(p9pm::PM_INIT),
                    "PBA setup failed");
    }

    // Reset the PSTATE GPE
    else if (i_mode == p9pm::PM_RESET)
    {
        FAPI_TRY(pstate_gpe_reset(i_target), "ERROR:failed to reset Pstate GPE");
    }

    // Unsupported Mode
    else
    {
        FAPI_ERR("Unknown mode %x passed to p9_pstate_gpe_init.", i_mode);
        FAPI_ASSERT(false,
                    fapi2::PSTATE_GPE_BAD_MODE()
                    .set_BADMODE(i_mode),
                    "ERROR; Unknown mode passed to pstate_gpe_init. Mode %x",
                    i_mode);
    }

fapi_try_exit:
    FAPI_IMP("< p9_pm_pstate_gpe_init");
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>#pragma once

#include <string>
#include <vector>

struct GLFWwindow;

/// Class that handles input.
class InputHandler {
    public:
        /// Button codes.
        enum Button {
            CLICK = 0, ///< Clicking in the editor.
            BACK, ///< Erase previous character.
            ERASE, ///< Erase next character.
            LEFT, ///< Move text input marker left.
            RIGHT, ///< Move text input marker right.
            HOME, ///< Move text input marker to beginning of text field.
            END, ///< Move text input marker to end of text field.
            PLAYTEST, ///< Start/stop playtesting the game.
            BUTTONS, ///< Total number of inputs
        };

        /// Input device codes
        enum Device {
            KEYBOARD = 0, ///< Keyboard input
            MOUSE, ///< Mouse buttons
            INPUT_DEVICES, ///< Number of input devices
        };

        /// Create new input handler.
        /**
         * @param window %Window to get input for.
         */
        InputHandler(GLFWwindow* window);

        /// Get currently active input handler.
        /**
         * @return The currently active input handler or nullptr.
         */
        static InputHandler* GetActiveInstance();

        /// Set as currently active input handler.
        void SetActive();

        /// Update input state.
        void Update();

        /// Get cursor's horizontal position.
        /**
         * @return X-position of the cursor
         */
        double CursorX() const;

        /// Get cursor's vertical position.
        /**
         * @return Y-position of the cursor
         */
        double CursorY() const;

        /// Get whether user has moved scroll wheel up.
        /**
         * @return Whether user has scrolled up
         */
        bool ScrollUp() const;

        /// Get whether user has moved scroll wheel down.
        /**
         * @return Whether user has scrolled down
         */
        bool ScrollDown() const;

        /// Assign a button binding.
        /**
         * See GLFW keyboard documentation for indices for keys.
         * For mouse buttons, either GLFW_MOUSE_BUTTON_LEFT, GLFW_MOUSE_BUTTON_RIGHT or GLFW_MOUSE_BUTTON_MIDDLE.
         * @param button Which button to bind.
         * @param device Which device (KEYBOARD or MOUSE).
         * @param index Index of the key.
         */
        void AssignButton(Button button, Device device, int index);

        /// Gets whether a button is currently down.
        /**
         * @param button The button to check.
         * @return Whether the button is down
         */
        bool Pressed(Button button);

        /// Gets whether a button was just pressed.
        /**
         * Checks whether a button was pressed between the last two calls to update().
         * @param button The button to check.
         * @return Whether the button was pressed
         */
        bool Triggered(Button button);

        /// Gets whether a button was just released.
        /**
         * Checks whether a button was released between the last two calls to update().
         * @param button The button to check.
         * @return Whether the button was released
         */
        bool Released(Button button);

        /// Get text input since last frame.
        /**
         * @return Text input since last frame.
         */
        const std::string& Text() const;

        /// GLFW character callback.
        /**
         * @param codePoint Unicode code point.
         */
        void CharacterCallback(unsigned int codePoint);

        /// GLFW scrolling callback.
        /**
         * @param yoffset Offset along the Y-axis.
         */
        void ScrollCallback(double yOffset);

    private:
        static InputHandler* activeInstance;

        GLFWwindow* window;

        // Bindings
        struct Binding {
            Button button;
            Device device;
            int index;
        };
        std::vector<Binding> bindings;

        // Data
        struct ButtonData {
            bool down = false;
            bool released = false;
            bool triggered = false;
        };

        // Button data.
        ButtonData buttonData[BUTTONS];

        double cursorX, cursorY;
        double lastScroll = 0.0;
        double scroll = 0.0;

        std::string text = "", tempText = "";
};

/// Get currently active input handler.
/**
 * @return The currently active input handler or nullptr.
 */
InputHandler* Input();
<commit_msg>Fix Input documentation.<commit_after>#pragma once

#include <string>
#include <vector>

struct GLFWwindow;

/// Class that handles input.
class InputHandler {
    public:
        /// Button codes.
        enum Button {
            CLICK = 0, ///< Clicking in the editor.
            BACK, ///< Erase previous character.
            ERASE, ///< Erase next character.
            LEFT, ///< Move text input marker left.
            RIGHT, ///< Move text input marker right.
            HOME, ///< Move text input marker to beginning of text field.
            END, ///< Move text input marker to end of text field.
            PLAYTEST, ///< Start/stop playtesting the game.
            BUTTONS, ///< Total number of inputs
        };

        /// Input device codes
        enum Device {
            KEYBOARD = 0, ///< Keyboard input
            MOUSE, ///< Mouse buttons
            INPUT_DEVICES, ///< Number of input devices
        };

        /// Create new input handler.
        /**
         * @param window %Window to get input for.
         */
        InputHandler(GLFWwindow* window);

        /// Get currently active input handler.
        /**
         * @return The currently active input handler or nullptr.
         */
        static InputHandler* GetActiveInstance();

        /// Set as currently active input handler.
        void SetActive();

        /// Update input state.
        void Update();

        /// Get cursor's horizontal position.
        /**
         * @return X-position of the cursor
         */
        double CursorX() const;

        /// Get cursor's vertical position.
        /**
         * @return Y-position of the cursor
         */
        double CursorY() const;

        /// Get whether user has moved scroll wheel up.
        /**
         * @return Whether user has scrolled up
         */
        bool ScrollUp() const;

        /// Get whether user has moved scroll wheel down.
        /**
         * @return Whether user has scrolled down
         */
        bool ScrollDown() const;

        /// Assign a button binding.
        /**
         * See GLFW keyboard documentation for indices for keys.
         * For mouse buttons, either GLFW_MOUSE_BUTTON_LEFT, GLFW_MOUSE_BUTTON_RIGHT or GLFW_MOUSE_BUTTON_MIDDLE.
         * @param button Which button to bind.
         * @param device Which device (KEYBOARD or MOUSE).
         * @param index Index of the key.
         */
        void AssignButton(Button button, Device device, int index);

        /// Gets whether a button is currently down.
        /**
         * @param button The button to check.
         * @return Whether the button is down
         */
        bool Pressed(Button button);

        /// Gets whether a button was just pressed.
        /**
         * Checks whether a button was pressed between the last two calls to update().
         * @param button The button to check.
         * @return Whether the button was pressed
         */
        bool Triggered(Button button);

        /// Gets whether a button was just released.
        /**
         * Checks whether a button was released between the last two calls to update().
         * @param button The button to check.
         * @return Whether the button was released
         */
        bool Released(Button button);

        /// Get text input since last frame.
        /**
         * @return Text input since last frame.
         */
        const std::string& Text() const;

        /// GLFW character callback.
        /**
         * @param codePoint Unicode code point.
         */
        void CharacterCallback(unsigned int codePoint);

        /// GLFW scrolling callback.
        /**
         * @param yOffset Offset along the Y-axis.
         */
        void ScrollCallback(double yOffset);

    private:
        static InputHandler* activeInstance;

        GLFWwindow* window;

        // Bindings
        struct Binding {
            Button button;
            Device device;
            int index;
        };
        std::vector<Binding> bindings;

        // Data
        struct ButtonData {
            bool down = false;
            bool released = false;
            bool triggered = false;
        };

        // Button data.
        ButtonData buttonData[BUTTONS];

        double cursorX, cursorY;
        double lastScroll = 0.0;
        double scroll = 0.0;

        std::string text = "", tempText = "";
};

/// Get currently active input handler.
/**
 * @return The currently active input handler or nullptr.
 */
InputHandler* Input();
<|endoftext|>


<commit_before>#include "VTKImageExporter.hpp"

#include <vtkObjectFactory.h>
#include <vtkStreamingDemandDrivenPipeline.h>
#include <vtkInformationVector.h>
#include <vtkInformation.h>
#include <vtkDataObject.h>

#include <vtkSmartPointer.h>
#include <vtkImageData.h>

using namespace fast;

vtkStandardNewMacro(VTKImageExporter);

void VTKImageExporter::SetInput(Image2D::pointer image) {
    mInput = image;
}

VTKImageExporter::VTKImageExporter() {
    // VTK stuff
    this->SetNumberOfOutputPorts(1);
    this->SetNumberOfInputPorts(0);
}

int VTKImageExporter::RequestData(
        vtkInformation* vtkNotUsed(request),
        vtkInformationVector** inputVector,
        vtkInformationVector* outputVector) {

    vtkInformation *outInfo = outputVector->GetInformationObject(0);

    vtkImageData *output = vtkImageData::SafeDownCast(
            outInfo->Get(vtkDataObject::DATA_OBJECT()));

    vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New();
    //image->SetDimensions(2,3,1);
    image->SetExtent(0, mInput->getWidth(), 0, mInput->getHeight(), 0, 0);
    image->SetScalarType(VTK_FLOAT);

    // Transfer data from mInput to image
    // TODO support different data types
    //float * vtkPixelData = (float *)image->GetScalarPointer();

    mInput->update(); // Make sure input is up to date
    ImageAccess2D access = mInput->getImageAccess(ACCESS_READ);
    float * fastPixelData = (float *)access.get();
    for(unsigned int x = 0; x < mInput->getWidth(); x++) {
    for(unsigned int y = 0; y < mInput->getHeight(); y++) {
        float * pixel = static_cast<float*>(image->GetScalarPointer(x,mInput->getHeight()-y,0));
        pixel[0] = fastPixelData[x+y*mInput->getWidth()];
    }}

    output->ShallowCopy(image);

    // Without these lines, the output will appear real but will not work as the input to any other filters
    output->SetExtent(image->GetExtent());
    output->SetUpdateExtent(output->GetExtent());
    output->SetWholeExtent(output->GetExtent());

    return 1;
}
<commit_msg>moved update call in VTK exporter<commit_after>#include "VTKImageExporter.hpp"

#include <vtkObjectFactory.h>
#include <vtkStreamingDemandDrivenPipeline.h>
#include <vtkInformationVector.h>
#include <vtkInformation.h>
#include <vtkDataObject.h>

#include <vtkSmartPointer.h>
#include <vtkImageData.h>

using namespace fast;

vtkStandardNewMacro(VTKImageExporter);

void VTKImageExporter::SetInput(Image2D::pointer image) {
    mInput = image;
}

VTKImageExporter::VTKImageExporter() {
    // VTK stuff
    this->SetNumberOfOutputPorts(1);
    this->SetNumberOfInputPorts(0);
}

int VTKImageExporter::RequestData(
        vtkInformation* vtkNotUsed(request),
        vtkInformationVector** inputVector,
        vtkInformationVector* outputVector) {

    mInput->update(); // Make sure input is up to date
    vtkInformation *outInfo = outputVector->GetInformationObject(0);

    vtkImageData *output = vtkImageData::SafeDownCast(
            outInfo->Get(vtkDataObject::DATA_OBJECT()));

    vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New();
    //image->SetDimensions(2,3,1);
    image->SetExtent(0, mInput->getWidth(), 0, mInput->getHeight(), 0, 0);
    image->SetScalarType(VTK_FLOAT);

    // Transfer data from mInput to image
    // TODO support different data types
    //float * vtkPixelData = (float *)image->GetScalarPointer();

    ImageAccess2D access = mInput->getImageAccess(ACCESS_READ);
    float * fastPixelData = (float *)access.get();
    for(unsigned int x = 0; x < mInput->getWidth(); x++) {
    for(unsigned int y = 0; y < mInput->getHeight(); y++) {
        float * pixel = static_cast<float*>(image->GetScalarPointer(x,mInput->getHeight()-y,0));
        pixel[0] = fastPixelData[x+y*mInput->getWidth()];
    }}

    output->ShallowCopy(image);

    // Without these lines, the output will appear real but will not work as the input to any other filters
    output->SetExtent(image->GetExtent());
    output->SetUpdateExtent(output->GetExtent());
    output->SetWholeExtent(output->GetExtent());

    return 1;
}
<|endoftext|>


<commit_before>#include "MrboomHelper.hpp"
#include "BotTree.hpp"

class ConditionNode : public bt::Leaf
{
public:
ConditionNode(std::function<bool ()> f) : Leaf(),  f(f) {
}
void Initialize() override
{
}
Status Update() override
{
	if (f()) {
		return Node::Status::Success;
	} else {
		return Node::Status::Failure;
	}
}
private:
std::function<bool ()> f;
};

class MoveToNode : public bt::Leaf
{
public:
MoveToNode(Bot * Bot,std::function<int ()> f) : Leaf(), Bot(Bot), f(f) {
}
void Initialize() override
{
}
Status Update() override
{
	int cell=f();
	if (cell==-1) {
		return Node::Status::Failure;
	} else {
		if (Bot->getCurrentCell()!=cell) {
			if (Bot->walkToCell(cell)) {
				return Node::Status::Running;
			} else {
				return Node::Status::Failure;
			}
		} else {
			return Node::Status::Success;
		}
	}

}
private:
Bot * Bot;
std::function<int ()> f;
};

static bool traceLeaves = false;

BotTree::BotTree(int playerIndex) : Bot(playerIndex) {
	tree = new bt::BehaviorTree();

	auto gotoBonus = std::make_shared<MoveToNode>(this, [this]() {
		// leaf: "move to the best bonus cell"
		int bestCell=this->bestBonusCell();
		if (traceLeaves) log_debug("%d/%d:gotoBonus:%d current=%d\n",frameNumber(),this->_playerIndex,bestCell,this->getCurrentCell());
		return bestCell;
	});

	auto bombSeq = bt::MakeSequence();
	auto bombLeft = std::make_shared<ConditionNode>([this]() {
		// condition "i have more bombs"
		int howManyBombs=this->howManyBombsLeft();
		if (traceLeaves) log_debug("%d/%d:bombLeft:%d\n",frameNumber(),this->_playerIndex,howManyBombs);
		return (howManyBombs);
	});
	bombSeq->AddChild(bombLeft);
	auto gotoBestBombCell = std::make_shared<MoveToNode>(this, [this]() {
		// leaf: "move to the best place to Drop a bomb"
		int bestCell=this->bestCellToDropABomb();
		if (traceLeaves) log_debug("%d/%d:goBestBombCell:%d current=%d\n",frameNumber(),this->_playerIndex,bestCell,this->getCurrentCell());
		return bestCell;
	});
	bombSeq->AddChild(gotoBestBombCell);
	auto dropBomb = std::make_shared<ConditionNode>([this]() {
		if (isSomewhatInTheMiddleOfCell()) { // done to avoid to drop another bomb when leaving the cell.
		        this->startPushingBombDropButton();
		}
		if (traceLeaves) log_debug("%d/%d:dropBomb\n",frameNumber(),this->_playerIndex);
		return true;
	});
	bombSeq->AddChild(dropBomb);

	auto gotoSafePlace = std::make_shared<MoveToNode>(this, [this]() {
		int bestCell=this->bestSafeCell();
		if (traceLeaves) log_debug("%d/%d l22: goto bestSafeCell:%d current=%d\n",frameNumber(),this->_playerIndex,bestCell,this->getCurrentCell());
		return bestCell;
	});

	auto rootNode = std::make_shared<bt::Selector>();
	rootNode->AddChild(gotoBonus);
	rootNode->AddChild(bombSeq);
	rootNode->AddChild(gotoSafePlace);
	tree->SetRoot(rootNode);
}

void BotTree::Update() {
	updateFlameAndDangerGrids(_playerIndex,flameGrid,dangerGrid);
	updateTravelGrid(_playerIndex,travelCostGrid,flameGrid);
	updateBestExplosionGrid(_playerIndex,bestExplosionsGrid,travelCostGrid,flameGrid,dangerGrid);
	stopPushingRemoteButton();
	stopPushingBombDropButton();
	if (isInMiddleOfCell()) {
		stopWalking();
	}
	tree->Update();
	if (amISafe() && (pushingDropBombButton==false) && isSomewhatInTheMiddleOfCell()) {
		this->startPushingRemoteButton();
	}

}
<commit_msg>More linux fixing<commit_after>#include "MrboomHelper.hpp"
#include "Bot.hpp"
#include "BotTree.hpp"
class ConditionNode : public bt::Leaf
{
public:
ConditionNode(std::function<bool ()> f) : Leaf(),  f(f) {
}
void Initialize() override
{
}
Status Update() override
{
	if (f()) {
		return Node::Status::Success;
	} else {
		return Node::Status::Failure;
	}
}
private:
std::function<bool ()> f;
};

class MoveToNode : public bt::Leaf
{
public:
MoveToNode(Bot * bot,std::function<int ()> f) : Leaf(), bot(bot), f(f) {
}
void Initialize() override
{
}
Status Update() override
{
	int cell=f();
	if (cell==-1) {
		return Node::Status::Failure;
	} else {
		if (bot->getCurrentCell()!=cell) {
			if (bot->walkToCell(cell)) {
				return Node::Status::Running;
			} else {
				return Node::Status::Failure;
			}
		} else {
			return Node::Status::Success;
		}
	}

}
private:
Bot * bot;
std::function<int ()> f;
};

static bool traceLeaves = false;

BotTree::BotTree(int playerIndex) : Bot(playerIndex) {
	tree = new bt::BehaviorTree();

	auto gotoBonus = std::make_shared<MoveToNode>(this, [this]() {
		// leaf: "move to the best bonus cell"
		int bestCell=this->bestBonusCell();
		if (traceLeaves) log_debug("%d/%d:gotoBonus:%d current=%d\n",frameNumber(),this->_playerIndex,bestCell,this->getCurrentCell());
		return bestCell;
	});

	auto bombSeq = bt::MakeSequence();
	auto bombLeft = std::make_shared<ConditionNode>([this]() {
		// condition "i have more bombs"
		int howManyBombs=this->howManyBombsLeft();
		if (traceLeaves) log_debug("%d/%d:bombLeft:%d\n",frameNumber(),this->_playerIndex,howManyBombs);
		return (howManyBombs);
	});
	bombSeq->AddChild(bombLeft);
	auto gotoBestBombCell = std::make_shared<MoveToNode>(this, [this]() {
		// leaf: "move to the best place to Drop a bomb"
		int bestCell=this->bestCellToDropABomb();
		if (traceLeaves) log_debug("%d/%d:goBestBombCell:%d current=%d\n",frameNumber(),this->_playerIndex,bestCell,this->getCurrentCell());
		return bestCell;
	});
	bombSeq->AddChild(gotoBestBombCell);
	auto dropBomb = std::make_shared<ConditionNode>([this]() {
		if (isSomewhatInTheMiddleOfCell()) { // done to avoid to drop another bomb when leaving the cell.
		        this->startPushingBombDropButton();
		}
		if (traceLeaves) log_debug("%d/%d:dropBomb\n",frameNumber(),this->_playerIndex);
		return true;
	});
	bombSeq->AddChild(dropBomb);

	auto gotoSafePlace = std::make_shared<MoveToNode>(this, [this]() {
		int bestCell=this->bestSafeCell();
		if (traceLeaves) log_debug("%d/%d l22: goto bestSafeCell:%d current=%d\n",frameNumber(),this->_playerIndex,bestCell,this->getCurrentCell());
		return bestCell;
	});

	auto rootNode = std::make_shared<bt::Selector>();
	rootNode->AddChild(gotoBonus);
	rootNode->AddChild(bombSeq);
	rootNode->AddChild(gotoSafePlace);
	tree->SetRoot(rootNode);
}

void BotTree::Update() {
	updateFlameAndDangerGrids(_playerIndex,flameGrid,dangerGrid);
	updateTravelGrid(_playerIndex,travelCostGrid,flameGrid);
	updateBestExplosionGrid(_playerIndex,bestExplosionsGrid,travelCostGrid,flameGrid,dangerGrid);
	stopPushingRemoteButton();
	stopPushingBombDropButton();
	if (isInMiddleOfCell()) {
		stopWalking();
	}
	tree->Update();
	if (amISafe() && (pushingDropBombButton==false) && isSomewhatInTheMiddleOfCell()) {
		this->startPushingRemoteButton();
	}

}
<|endoftext|>


<commit_before>#include <algorithm> // sort
#include <chrono>
#include <ostream>
#include <unordered_map>
#include <utility>  //pair
#include <vector>

#include <sdd/values/bitset.hh>

#include "mc/units/concurrent_units.hh"

namespace pnmc { namespace mc { namespace units {

/*------------------------------------------------------------------------------------------------*/

namespace /* anonymous */{

struct active
{
  bool i;
  bool j;

  active(bool i, bool j)
    : i(i), j(j)
  {}

  bool
  operator==(const active& other)
  const
  {
    return i == other.i and j == other.j;
  }

  bool
  all()
  const
  {
    return i and j;
  }
};

template <typename InputIterator>
struct query_visitor
{
  using result_type = active;

  const sdd::values::flat_set<unsigned int>& inactive_unit;

  const InputIterator i_units_end;
  const InputIterator j_units_end;

  mutable std::unordered_map<const sdd::flat_node<sdd_conf>*, active> cache;

  query_visitor( const sdd::values::flat_set<unsigned int>& empty
               , InputIterator i_units_end, InputIterator j_units_end)
    : inactive_unit(empty)
    , i_units_end(i_units_end), j_units_end(j_units_end)
    , cache()
  {}

  result_type
  operator()( const sdd::zero_terminal<sdd_conf>&, const order&
            , InputIterator, InputIterator, bool, bool)
  const noexcept
  {
    assert(false && "|0|");
    __builtin_unreachable();
  }

  result_type
  operator()( const sdd::one_terminal<sdd_conf>&, const order&
            , InputIterator, InputIterator, bool, bool)
  const noexcept
  {
    return active(false, false);
  }

  result_type
  operator()( const sdd::hierarchical_node<sdd_conf>&, const order&
            , InputIterator, InputIterator, bool, bool)
  const noexcept
  {
    assert(false && "Hierarchy");
    __builtin_unreachable();
  }

  result_type
  operator()( const sdd::flat_node<sdd_conf>& node, const order& o
            , InputIterator i_units_cit, InputIterator j_units_cit, bool i_active, bool j_active)
  const
  {
    assert(i_active ? not j_active : true);
    assert(j_active ? not i_active : true);
    const auto insertion = cache.emplace(&node, active(false, false));
    auto& cache_result = insertion.first->second;
    if (insertion.second) // It's the first time that we see this node.
    {
      if (i_active) // only i or its subunits are active
      {
        assert(i_units_cit == i_units_end);
        if (on(j_units_cit, j_units_end, o)) // on j or its subunits
        {
          for (const auto& arc : node)
          {
            if (arc.valuation() != inactive_unit) // j is active
            {
              return active(true, true);
            }
            else // j is not active at this level
            {
              const auto res = visit( *this, arc.successor(), o.next()
                                    , i_units_end, ++j_units_cit, true, false);
              if (res.all())
              {
                return res;
              }
            }
          }
        }
        else // not on j or its subunits
        {
          for (const auto& arc : node)
          {
            const auto res = visit( *this, arc.successor(), o.next()
                                  , i_units_end, j_units_cit, true, false);
            if (res.all())
            {
              return res;
            }
          }
        }
        // If we come here, then i (or its subunits) is active, but not j (or its subunits).
        cache_result = active(true, false);
      }
      else if (j_active)  // only j or its subunits are active
      {
        assert(j_units_cit == j_units_end);
        if (on(i_units_cit, i_units_end, o)) // on i or its subunits
        {
          for (const auto& arc : node)
          {
            if (arc.valuation() != inactive_unit) // j is active
            {
              return active(true, true);
            }
            else // i is not active at this level
            {
              const auto res = visit( *this, arc.successor(), o.next()
                                     , ++i_units_cit, j_units_end, false, true);
              if (res.all())
              {
                return res;
              }
            }
          }
        }
        else // not on i or its subunits
        {
          for (const auto& arc : node)
          {
            const auto res = visit( *this, arc.successor(), o.next()
                                   , i_units_cit, j_units_end, false, true);
            if (res.all())
            {
              return res;
            }
          }
        }
        // If we come here, then j (or its subunits) is active, but not i (or its subunits).
        cache_result = active(false, true);
      }
      else // neither i (or its subunits) nor j (or its subunits) are active
      {
        if (on(i_units_cit, i_units_end, o)) // on i or its subunits
        {
          for (const auto& arc : node)
          {
            if (arc.valuation() != inactive_unit) // i is active
            {
              const auto res = visit( *this, arc.successor(), o.next()
                                    , i_units_end, j_units_cit, true, false);
              if (res.all())
              {
                return res;
              }
              cache_result = active(true, false);
            }
            else // i is not active at this level
            {
              const auto res = visit( *this, arc.successor(), o.next()
                                     , ++i_units_cit, j_units_cit, false, false);
              if (res.all())
              {
                return res;
              }
              cache_result = active(res.i, res.j);
            }
          }
        }
        else if (on(j_units_cit, j_units_end, o))
        {
          for (const auto& arc : node)
          {
            if (arc.valuation() != inactive_unit) // j is active
            {
              const auto res = visit( *this, arc.successor(), o.next()
                                    , i_units_cit, j_units_end, false, true);
              if (res.all())
              {
                return res;
              }
              cache_result = active(false, true);
            }
            else // j is not active at this level
            {
              const auto res = visit( *this, arc.successor(), o.next()
                                    , i_units_cit, ++j_units_cit, false, false);
              if (res.all())
              {
                return res;
              }
              cache_result = active(res.i, res.j);
            }
          }
        }
        else // neither on i (or its subunits) nor j (or its subunits)
        {
          for (const auto& arc : node)
          {
            const auto res = visit( *this, arc.successor(), o.next()
                                  , i_units_cit, j_units_cit, false, false);
            if (res.all())
            {
              return res;
            }
            cache_result = active(res.i, res.j);
          }
        }
      }
    }
    // Cache hit or not, the result is now in the cache.
    return cache_result;
  }

  static
  bool
  on(InputIterator cit, InputIterator end, const order& o)
  {
    return std::find(cit, end, o.identifier().user()) != end;
  }
};

bool
query(const pn::net& net, SDD states, const order& o, unsigned int i, unsigned int j)
{
  const sdd::values::flat_set<unsigned int> empty_unit = {0};

  const auto i_search = net.units().find(i);
  const auto j_search = net.units().find(j);
  assert(i_search != net.units().end());
  assert(j_search != net.units().end());
  const auto& i_unit = i_search->second;
  const auto& j_unit = j_search->second;

  std::vector<unsigned int> i_units(i_unit.subunits.cbegin(), i_unit.subunits.cend());
  i_units.push_back(i);
  std::vector<unsigned int> j_units(j_unit.subunits.cbegin(), j_unit.subunits.cend());
  j_units.push_back(j);

  const auto comp = [&o](unsigned int lhs, unsigned int rhs){return o.node(lhs) < o.node(rhs);};
  std::sort(i_units.begin(), i_units.end(), comp);
  std::sort(j_units.begin(), j_units.end(), comp);

  const auto res
    = visit( query_visitor<std::vector<unsigned int>::const_iterator>
               (empty_unit, i_units.cend(), j_units.cend())
           , states, o, i_units.cbegin(), j_units.cbegin(), false, false);

  return res.i and res.j;
}

} // namespace anonymous

/*------------------------------------------------------------------------------------------------*/

void
compute_concurrent_units( const conf::pnmc_configuration& conf, const pn::net& net
                        , const sdd::order<sdd_conf>& o, SDD states)
{
  namespace chrono = std::chrono;
  chrono::time_point<chrono::system_clock> start = chrono::system_clock::now();

  const auto nb_units = net.units().size();
  unsigned int j_end = 1;
  for (unsigned int i = 0; i < nb_units; ++i, ++j_end)
  {
    for (unsigned int j = 0; j < j_end; ++j)
    {
      if ( i == j or net.places_of_unit(i).empty() or net.places_of_unit(j).empty()
          or net.units_are_related(i, j))
      {
        std::cout << "0 ";
      }
      else
      {
        std::cout << (query(net, states, o, i, j) ? "1 " : "0 ");
      }
    }
    std::cout << std::endl;
  }

  chrono::time_point<chrono::system_clock> end = chrono::system_clock::now();
  const std::size_t elapsed = chrono::duration_cast<chrono::seconds>(end-start).count();
  if (conf.show_time)
  {
    std::cout << "Concurrent units computation time: " << elapsed << "s\n";
  }
}

/*------------------------------------------------------------------------------------------------*/

}}} // namespace pnmc::mc::units
<commit_msg>Avoid useless temporary variable.<commit_after>#include <algorithm> // sort
#include <chrono>
#include <ostream>
#include <unordered_map>
#include <utility>  //pair
#include <vector>

#include <sdd/values/bitset.hh>

#include "mc/units/concurrent_units.hh"

namespace pnmc { namespace mc { namespace units {

/*------------------------------------------------------------------------------------------------*/

namespace /* anonymous */{

struct active
{
  bool i;
  bool j;

  active(bool i, bool j)
    : i(i), j(j)
  {}

  bool
  operator==(const active& other)
  const
  {
    return i == other.i and j == other.j;
  }

  bool
  all()
  const
  {
    return i and j;
  }
};

template <typename InputIterator>
struct query_visitor
{
  using result_type = active;

  const sdd::values::flat_set<unsigned int>& inactive_unit;

  const InputIterator i_units_end;
  const InputIterator j_units_end;

  mutable std::unordered_map<const sdd::flat_node<sdd_conf>*, active> cache;

  query_visitor( const sdd::values::flat_set<unsigned int>& empty
               , InputIterator i_units_end, InputIterator j_units_end)
    : inactive_unit(empty)
    , i_units_end(i_units_end), j_units_end(j_units_end)
    , cache()
  {}

  result_type
  operator()( const sdd::zero_terminal<sdd_conf>&, const order&
            , InputIterator, InputIterator, bool, bool)
  const noexcept
  {
    assert(false && "|0|");
    __builtin_unreachable();
  }

  result_type
  operator()( const sdd::one_terminal<sdd_conf>&, const order&
            , InputIterator, InputIterator, bool, bool)
  const noexcept
  {
    return active(false, false);
  }

  result_type
  operator()( const sdd::hierarchical_node<sdd_conf>&, const order&
            , InputIterator, InputIterator, bool, bool)
  const noexcept
  {
    assert(false && "Hierarchy");
    __builtin_unreachable();
  }

  result_type
  operator()( const sdd::flat_node<sdd_conf>& node, const order& o
            , InputIterator i_units_cit, InputIterator j_units_cit, bool i_active, bool j_active)
  const
  {
    assert((i_active ? not j_active : true) and (j_active ? not i_active : true));

    const auto insertion = cache.emplace(&node, active(false, false));
    auto& cache_result = insertion.first->second;

    if (insertion.second) // It's the first time that we see this node.
    {
      if (i_active) // only i or its subunits are active
      {
        assert(i_units_cit == i_units_end);
        if (on(j_units_cit, j_units_end, o)) // on j or its subunits
        {
          for (const auto& arc : node)
          {
            if (arc.valuation() != inactive_unit) // j is active
            {
              return active(true, true);
            }
            else // j is not active at this level
            {
              cache_result = visit( *this, arc.successor(), o.next()
                                  , i_units_end, ++j_units_cit, true, false);
              if (cache_result.all())
              {
                return cache_result;
              }
            }
          }
        }
        else // not on j or its subunits
        {
          for (const auto& arc : node)
          {
            cache_result = visit( *this, arc.successor(), o.next()
                                , i_units_end, j_units_cit, true, false);
            if (cache_result.all())
            {
              return cache_result;
            }
          }
        }
      }
      /* --------------- */
      else if (j_active)  // only j or its subunits are active
      {
        assert(j_units_cit == j_units_end);
        if (on(i_units_cit, i_units_end, o)) // on i or its subunits
        {
          for (const auto& arc : node)
          {
            if (arc.valuation() != inactive_unit) // j is active
            {
              return active(true, true);
            }
            else // i is not active at this level
            {
              cache_result = visit( *this, arc.successor(), o.next()
                                  , ++i_units_cit, j_units_end, false, true);
              if (cache_result.all())
              {
                return cache_result;
              }
            }
          }
        }
        else // not on i or its subunits
        {
          for (const auto& arc : node)
          {
            cache_result = visit( *this, arc.successor(), o.next()
                                , i_units_cit, j_units_end, false, true);
            if (cache_result.all())
            {
              return cache_result;
            }
          }
        }
      }
      /* --------------- */
      else // neither i (or its subunits) nor j (or its subunits) are active
      {
        if (on(i_units_cit, i_units_end, o)) // on i or its subunits
        {
          for (const auto& arc : node)
          {
            if (arc.valuation() != inactive_unit) // i is active
            {
              cache_result = visit( *this, arc.successor(), o.next()
                                  , i_units_end, j_units_cit, true, false);
              if (cache_result.all())
              {
                return cache_result;
              }
            }
            else // i is not active at this level
            {
              cache_result = visit( *this, arc.successor(), o.next()
                                  , ++i_units_cit, j_units_cit, false, false);
              if (cache_result.all())
              {
                return cache_result;
              }
            }
          }
        }
        else if (on(j_units_cit, j_units_end, o))
        {
          for (const auto& arc : node)
          {
            if (arc.valuation() != inactive_unit) // j is active
            {
              cache_result = visit( *this, arc.successor(), o.next()
                                  , i_units_cit, j_units_end, false, true);
              if (cache_result.all())
              {
                return cache_result;
              }
            }
            else // j is not active at this level
            {
              cache_result = visit( *this, arc.successor(), o.next()
                                  , i_units_cit, ++j_units_cit, false, false);
              if (cache_result.all())
              {
                return cache_result;
              }
            }
          }
        }
        else // neither on i (or its subunits) nor j (or its subunits)
        {
          for (const auto& arc : node)
          {
            cache_result = visit( *this, arc.successor(), o.next()
                                , i_units_cit, j_units_cit, false, false);
            if (cache_result.all())
            {
              return cache_result;
            }
          }
        }
      }
    }
    // Cache hit or not, the result is now in the cache.
    return cache_result;
  }

  static
  bool
  on(InputIterator cit, InputIterator end, const order& o)
  {
    return std::find(cit, end, o.identifier().user()) != end;
  }
};

bool
query(const pn::net& net, SDD states, const order& o, unsigned int i, unsigned int j)
{
  const sdd::values::flat_set<unsigned int> empty_unit = {0};

  const auto i_search = net.units().find(i);
  const auto j_search = net.units().find(j);
  assert(i_search != net.units().end());
  assert(j_search != net.units().end());
  const auto& i_unit = i_search->second;
  const auto& j_unit = j_search->second;

  std::vector<unsigned int> i_units(i_unit.subunits.cbegin(), i_unit.subunits.cend());
  i_units.push_back(i);
  std::vector<unsigned int> j_units(j_unit.subunits.cbegin(), j_unit.subunits.cend());
  j_units.push_back(j);

  const auto comp = [&o](unsigned int lhs, unsigned int rhs){return o.node(lhs) < o.node(rhs);};
  std::sort(i_units.begin(), i_units.end(), comp);
  std::sort(j_units.begin(), j_units.end(), comp);

  const auto res
    = visit( query_visitor<std::vector<unsigned int>::const_iterator>
               (empty_unit, i_units.cend(), j_units.cend())
           , states, o, i_units.cbegin(), j_units.cbegin(), false, false);

  return res.i and res.j;
}

} // namespace anonymous

/*------------------------------------------------------------------------------------------------*/

void
compute_concurrent_units( const conf::pnmc_configuration& conf, const pn::net& net
                        , const sdd::order<sdd_conf>& o, SDD states)
{
  namespace chrono = std::chrono;
  chrono::time_point<chrono::system_clock> start = chrono::system_clock::now();

  const auto nb_units = net.units().size();
  unsigned int j_end = 1;
  for (unsigned int i = 0; i < nb_units; ++i, ++j_end)
  {
    for (unsigned int j = 0; j < j_end; ++j)
    {
      if ( i == j or net.places_of_unit(i).empty() or net.places_of_unit(j).empty()
          or net.units_are_related(i, j))
      {
        std::cout << "0 ";
      }
      else
      {
        std::cout << (query(net, states, o, i, j) ? "1 " : "0 ");
      }
    }
    std::cout << std::endl;
  }

  chrono::time_point<chrono::system_clock> end = chrono::system_clock::now();
  const std::size_t elapsed = chrono::duration_cast<chrono::seconds>(end-start).count();
  if (conf.show_time)
  {
    std::cout << "Concurrent units computation time: " << elapsed << "s\n";
  }
}

/*------------------------------------------------------------------------------------------------*/

}}} // namespace pnmc::mc::units
<|endoftext|>


<commit_before>//===-- CombineBranch.cpp -------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Combine branches
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/CFG.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/Function.h"
#include "llvm/Pass.h"

namespace llvm {

namespace {
  struct CombineBranches : public FunctionPass {
  private:
    /// Possible colors that a vertex can have during depth-first search for
    /// back-edges.
    ///
    enum Color { WHITE, GREY, BLACK };

    void getBackEdgesVisit(BasicBlock *u,
			   std::map<BasicBlock *, Color > &color,
			   std::map<BasicBlock *, int > &d,
			   int &time,
			   std::map<BasicBlock *, BasicBlock *> &be);
    void removeRedundant(std::map<BasicBlock *, BasicBlock *> &be);
  public:
    bool runOnFunction(Function &F);
  };

  RegisterOpt<CombineBranches>
  X("branch-combine", "Multiple backedges going to same target are merged");
}

/// getBackEdgesVisit - Get the back-edges of the control-flow graph for this
/// function.  We proceed recursively using depth-first search.  We get
/// back-edges by associating a time and a color with each vertex.  The time of a
/// vertex is the time when it was first visited.  The color of a vertex is
/// initially WHITE, changes to GREY when it is first visited, and changes to
/// BLACK when ALL its neighbors have been visited.  So we have a back edge when
/// we meet a successor of a node with smaller time, and GREY color.
///
void CombineBranches::getBackEdgesVisit(BasicBlock *u,
                       std::map<BasicBlock *, Color > &color,
                       std::map<BasicBlock *, int > &d,
                       int &time,
		       std::map<BasicBlock *, BasicBlock *> &be) {

  color[u]=GREY;
  time++;
  d[u]=time;

  for (succ_iterator vl = succ_begin(u), ve = succ_end(u); vl != ve; ++vl){
    BasicBlock *BB = *vl;

    if(color[BB]!=GREY && color[BB]!=BLACK)
      getBackEdgesVisit(BB, color, d, time, be);

    //now checking for d and f vals
    else if(color[BB]==GREY){
      //so v is ancestor of u if time of u > time of v
      if(d[u] >= d[BB]) // u->BB is a backedge
	be[u] = BB;
    }
  }
  color[u]=BLACK;//done with visiting the node and its neighbors
}

/// removeRedundant - Remove all back-edges that are dominated by other
/// back-edges in the set.
///
void CombineBranches::removeRedundant(std::map<BasicBlock *, BasicBlock *> &be){
  std::vector<BasicBlock *> toDelete;
  std::map<BasicBlock *, int> seenBB;

  for(std::map<BasicBlock *, BasicBlock *>::iterator MI = be.begin(),
	ME = be.end(); MI != ME; ++MI){

    if(seenBB[MI->second])
      continue;

    seenBB[MI->second] = 1;

    std::vector<BasicBlock *> sameTarget;
    sameTarget.clear();

    for(std::map<BasicBlock *, BasicBlock *>::iterator MMI = be.begin(),
	  MME = be.end(); MMI != MME; ++MMI){

      if(MMI->first == MI->first)
	continue;

      if(MMI->second == MI->second)
	sameTarget.push_back(MMI->first);

    }

    //so more than one branch to same target
    if(sameTarget.size()){

      sameTarget.push_back(MI->first);

      BasicBlock *newBB = new BasicBlock("newCommon", MI->first->getParent());
      BranchInst *newBranch = new BranchInst(MI->second, 0, 0, newBB);

      std::map<PHINode *, std::vector<unsigned int> > phiMap;

      for(std::vector<BasicBlock *>::iterator VBI = sameTarget.begin(),
	    VBE = sameTarget.end(); VBI != VBE; ++VBI){

	BranchInst *ti = cast<BranchInst>((*VBI)->getTerminator());
	unsigned char index = 1;
	if(ti->getSuccessor(0) == MI->second)
	  index = 0;

	ti->setSuccessor(index, newBB);

	for(BasicBlock::iterator BB2Inst = MI->second->begin(),
	      BBend = MI->second->end(); BB2Inst != BBend; ++BB2Inst){

	  if (PHINode *phiInst = dyn_cast<PHINode>(BB2Inst)){
	    int bbIndex;
	    bbIndex = phiInst->getBasicBlockIndex(*VBI);
	    if(bbIndex>=0)
	      phiMap[phiInst].push_back(bbIndex);
	  }
	}
      }

      for(std::map<PHINode *, std::vector<unsigned int> >::iterator
	    PI = phiMap.begin(), PE = phiMap.end(); PI != PE; ++PI){

	PHINode *phiNode = new PHINode(PI->first->getType(), "phi", newBranch);
	for(std::vector<unsigned int>::iterator II = PI->second.begin(),
	      IE = PI->second.end(); II != IE; ++II){
	  phiNode->addIncoming(PI->first->getIncomingValue(*II),
			       PI->first->getIncomingBlock(*II));
	}

	std::vector<BasicBlock *> tempBB;
	for(std::vector<unsigned int>::iterator II = PI->second.begin(),
	      IE = PI->second.end(); II != IE; ++II){
	  tempBB.push_back(PI->first->getIncomingBlock(*II));
	}

	for(std::vector<BasicBlock *>::iterator II = tempBB.begin(),
	      IE = tempBB.end(); II != IE; ++II){
	  PI->first->removeIncomingValue(*II);
	}

	PI->first->addIncoming(phiNode, newBB);
      }
    }
  }
}

/// runOnFunction - Per function pass for combining branches.
///
bool CombineBranches::runOnFunction(Function &F){
  if (F.isExternal ())
    return false;

  // Find and remove "redundant" back-edges.
  std::map<BasicBlock *, Color> color;
  std::map<BasicBlock *, int> d;
  std::map<BasicBlock *, BasicBlock *> be;
  int time = 0;
  getBackEdgesVisit (F.begin (), color, d, time, be);
  removeRedundant (be);

  return true; // FIXME: assumes a modification was always made.
}

} // End llvm namespace
<commit_msg>Use new form of unconditional branch constructor.<commit_after>//===-- CombineBranch.cpp -------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Combine branches
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/CFG.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/Function.h"
#include "llvm/Pass.h"

namespace llvm {

namespace {
  struct CombineBranches : public FunctionPass {
  private:
    /// Possible colors that a vertex can have during depth-first search for
    /// back-edges.
    ///
    enum Color { WHITE, GREY, BLACK };

    void getBackEdgesVisit(BasicBlock *u,
			   std::map<BasicBlock *, Color > &color,
			   std::map<BasicBlock *, int > &d,
			   int &time,
			   std::map<BasicBlock *, BasicBlock *> &be);
    void removeRedundant(std::map<BasicBlock *, BasicBlock *> &be);
  public:
    bool runOnFunction(Function &F);
  };

  RegisterOpt<CombineBranches>
  X("branch-combine", "Multiple backedges going to same target are merged");
}

/// getBackEdgesVisit - Get the back-edges of the control-flow graph for this
/// function.  We proceed recursively using depth-first search.  We get
/// back-edges by associating a time and a color with each vertex.  The time of a
/// vertex is the time when it was first visited.  The color of a vertex is
/// initially WHITE, changes to GREY when it is first visited, and changes to
/// BLACK when ALL its neighbors have been visited.  So we have a back edge when
/// we meet a successor of a node with smaller time, and GREY color.
///
void CombineBranches::getBackEdgesVisit(BasicBlock *u,
                       std::map<BasicBlock *, Color > &color,
                       std::map<BasicBlock *, int > &d,
                       int &time,
		       std::map<BasicBlock *, BasicBlock *> &be) {

  color[u]=GREY;
  time++;
  d[u]=time;

  for (succ_iterator vl = succ_begin(u), ve = succ_end(u); vl != ve; ++vl){
    BasicBlock *BB = *vl;

    if(color[BB]!=GREY && color[BB]!=BLACK)
      getBackEdgesVisit(BB, color, d, time, be);

    //now checking for d and f vals
    else if(color[BB]==GREY){
      //so v is ancestor of u if time of u > time of v
      if(d[u] >= d[BB]) // u->BB is a backedge
	be[u] = BB;
    }
  }
  color[u]=BLACK;//done with visiting the node and its neighbors
}

/// removeRedundant - Remove all back-edges that are dominated by other
/// back-edges in the set.
///
void CombineBranches::removeRedundant(std::map<BasicBlock *, BasicBlock *> &be){
  std::vector<BasicBlock *> toDelete;
  std::map<BasicBlock *, int> seenBB;

  for(std::map<BasicBlock *, BasicBlock *>::iterator MI = be.begin(),
	ME = be.end(); MI != ME; ++MI){

    if(seenBB[MI->second])
      continue;

    seenBB[MI->second] = 1;

    std::vector<BasicBlock *> sameTarget;
    sameTarget.clear();

    for(std::map<BasicBlock *, BasicBlock *>::iterator MMI = be.begin(),
	  MME = be.end(); MMI != MME; ++MMI){

      if(MMI->first == MI->first)
	continue;

      if(MMI->second == MI->second)
	sameTarget.push_back(MMI->first);

    }

    //so more than one branch to same target
    if(sameTarget.size()){

      sameTarget.push_back(MI->first);

      BasicBlock *newBB = new BasicBlock("newCommon", MI->first->getParent());
      BranchInst *newBranch = new BranchInst(MI->second, newBB);

      std::map<PHINode *, std::vector<unsigned int> > phiMap;

      for(std::vector<BasicBlock *>::iterator VBI = sameTarget.begin(),
	    VBE = sameTarget.end(); VBI != VBE; ++VBI){

	BranchInst *ti = cast<BranchInst>((*VBI)->getTerminator());
	unsigned char index = 1;
	if(ti->getSuccessor(0) == MI->second)
	  index = 0;

	ti->setSuccessor(index, newBB);

	for(BasicBlock::iterator BB2Inst = MI->second->begin(),
	      BBend = MI->second->end(); BB2Inst != BBend; ++BB2Inst){

	  if (PHINode *phiInst = dyn_cast<PHINode>(BB2Inst)){
	    int bbIndex;
	    bbIndex = phiInst->getBasicBlockIndex(*VBI);
	    if(bbIndex>=0)
	      phiMap[phiInst].push_back(bbIndex);
	  }
	}
      }

      for(std::map<PHINode *, std::vector<unsigned int> >::iterator
	    PI = phiMap.begin(), PE = phiMap.end(); PI != PE; ++PI){

	PHINode *phiNode = new PHINode(PI->first->getType(), "phi", newBranch);
	for(std::vector<unsigned int>::iterator II = PI->second.begin(),
	      IE = PI->second.end(); II != IE; ++II){
	  phiNode->addIncoming(PI->first->getIncomingValue(*II),
			       PI->first->getIncomingBlock(*II));
	}

	std::vector<BasicBlock *> tempBB;
	for(std::vector<unsigned int>::iterator II = PI->second.begin(),
	      IE = PI->second.end(); II != IE; ++II){
	  tempBB.push_back(PI->first->getIncomingBlock(*II));
	}

	for(std::vector<BasicBlock *>::iterator II = tempBB.begin(),
	      IE = tempBB.end(); II != IE; ++II){
	  PI->first->removeIncomingValue(*II);
	}

	PI->first->addIncoming(phiNode, newBB);
      }
    }
  }
}

/// runOnFunction - Per function pass for combining branches.
///
bool CombineBranches::runOnFunction(Function &F){
  if (F.isExternal ())
    return false;

  // Find and remove "redundant" back-edges.
  std::map<BasicBlock *, Color> color;
  std::map<BasicBlock *, int> d;
  std::map<BasicBlock *, BasicBlock *> be;
  int time = 0;
  getBackEdgesVisit (F.begin (), color, d, time, be);
  removeRedundant (be);

  return true; // FIXME: assumes a modification was always made.
}

} // End llvm namespace
<|endoftext|>


<commit_before><commit_msg>FEM: Fix typo in filter function tooltip<commit_after><|endoftext|>