<commit_before>#ifndef ACTIVATION_H
#define ACTIVATION_H

#include <cmath>      // exp

double sign(double a) { return (a == 0) ? 0 : (a < 0 ? -1 : 1); }

class ActivationFunction {
    public:
        virtual double operator()(double v) const = 0;
        virtual double derivative(double v) const = 0;
};

class LogisticFunction : public ActivationFunction {
    private:
        double slope = 1.0;

    public:
        LogisticFunction(double slope) : slope(slope) {};

        virtual double operator()(double v) const {
            return 1.0/(1.0 + exp(-slope*v));
        }

        virtual double derivative(double v) const {
            double y = (*this)(v);
            return slope * y * (1 - y);
        }
};

class AutoDiffFunction : public ActivationFunction {
    private:
        function<double(double)> f;
        double dx;
    public:
        AutoDiffFunction(function<double(double)> f, double dx=1e-3) :
            f(f), dx(dx) {}

        virtual double operator()(double v) const {
            return f(v);
        }

        virtual double derivative(double v) const {
            return (f(v+dx) - f(v-dx))/(2.0*dx);
        }
};

AutoDiffFunction signumFunction(sign);

#endif /* ACTIVATION_H */
<commit_msg>add TanhFunction activation function<commit_after>#ifndef ACTIVATION_H
#define ACTIVATION_H

#include <cmath>      // exp

double sign(double a) { return (a == 0) ? 0 : (a < 0 ? -1 : 1); }

class ActivationFunction {
    public:
        virtual double operator()(double v) const = 0;
        virtual double derivative(double v) const = 0;
};

/// phi(v) = 1/(1 + exp(-slope*v)); Chapter 4, page 135
class LogisticFunction : public ActivationFunction {
    private:
        double slope = 1.0;

    public:
        LogisticFunction(double slope) : slope(slope) {};

        virtual double operator()(double v) const {
            return 1.0/(1.0 + exp(-slope*v));
        }

        virtual double derivative(double v) const {
            double y = (*this)(v);
            return slope * y * (1 - y);
        }
};

/// phi(v) = a * tanh(b * v); Chapter 4, page 136
class TanhFunction : public ActivationFunction {
    private:
        double a = 1.0;
        double b = 1.0;
    public:
        TanhFunction(double a=1.0, double b=1.0) : a(a), b(b) {}

        virtual double operator()(double v) const {
            return a*tanh(b*v);
        }

        virtual double derivative(double v) const {
            double y = tanh(b*v);
            return a*b*(1.0 - y*y);
        }
};

/// calculate derivative with numeric differentiation
class AutoDiffFunction : public ActivationFunction {
    private:
        function<double(double)> f;
        double dx;
    public:
        AutoDiffFunction(function<double(double)> f, double dx=1e-3) :
            f(f), dx(dx) {}

        virtual double operator()(double v) const {
            return f(v);
        }

        virtual double derivative(double v) const {
            return (f(v+dx) - f(v-dx))/(2.0*dx);
        }
};

AutoDiffFunction signumFunction(sign);

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


<commit_before>//
// open horizon -- undefined_darkness@outlook.com
//

#include "poc.h"
#include <assert.h>

//------------------------------------------------------------

bool poc_file::open(const char *name)
{
    return open(nya_resources::get_resources_provider().access(name));
}

//------------------------------------------------------------

bool poc_file::open(nya_resources::resource_data *data)
{
    close();
    m_data = data;
    if (!m_data)
        return false;

    uint32_t count = 0;
    if (!m_data->read_chunk(&count, sizeof(uint32_t)))
    {
        close();
        return false;
    }

    std::vector<uint32_t> offsets(count);
    if (!m_data->read_chunk(offsets.data(), count * sizeof(uint32_t), sizeof(uint32_t)))
    {
        close();
        return false;
    }

    return init((uint32_t *)m_raw_data + 1, count, (uint32_t)m_data->get_size());
}

//------------------------------------------------------------

bool poc_file::open(const void *data, size_t size)
{
    close();
    m_raw_data = (char *)data;
    if (!m_raw_data || size < 4)
        return false;

    uint32_t count = *(uint32_t *)m_raw_data;
    if ((count + 1) * sizeof(uint32_t) > size)
    {
        m_raw_data = 0;
        return false;
    }

    return init((uint32_t *)m_raw_data + 1, count, (uint32_t)size);
}

//------------------------------------------------------------

bool poc_file::init(const uint32_t *offsets, uint32_t count, uint32_t size)
{
    m_entries.resize(count);
    for (size_t i = 0; i < m_entries.size(); ++i)
    {
        auto &e = m_entries[i];
        e.offset = offsets[i];
        if (i > 0)
            m_entries[i - 1].size = e.offset - m_entries[i - 1].offset;

        assert(e.offset <= size);
    }

    if (!m_entries.empty())
        m_entries.back().size = size - m_entries.back().offset;

    int idx = 0;
    for (auto &e: m_entries)
    {
        e.type = 0;
        if (e.size >= sizeof(uint32_t))
            read_chunk_data(idx++, &e.type, sizeof(uint32_t));
    }

    return true;
}

//------------------------------------------------------------

void poc_file::close()
{
    if (m_data)
        m_data->release();
    m_entries.clear();
    m_data = 0;
    m_raw_data = 0;
}

//------------------------------------------------------------

uint32_t poc_file::get_chunk_type(int idx) const
{
    if (idx < 0 || idx >= get_chunks_count())
        return 0;

    return m_entries[idx].type;
}

//------------------------------------------------------------

uint32_t poc_file::get_chunk_size(int idx) const
{
    if (idx < 0 || idx >= get_chunks_count())
        return 0;

    return m_entries[idx].size;
}

//------------------------------------------------------------

uint32_t poc_file::get_chunk_offset(int idx) const
{
    if (idx < 0 || idx >= get_chunks_count())
        return 0;

    return m_entries[idx].size;
}

//------------------------------------------------------------

bool poc_file::read_chunk_data(int idx, void *data) const
{
    return read_chunk_data(idx, data, get_chunk_size(idx));
}

//------------------------------------------------------------

bool poc_file::read_chunk_data(int idx, void *data, uint32_t size, uint32_t offset) const
{
    if (idx < 0 || idx >= get_chunks_count() || !data)
        return false;

    const auto &e = m_entries[idx];
    if (offset + size > e.size)
        return false;

    if (m_data)
        return m_data->read_chunk(data, size, e.offset + offset);

    return memcpy(data, m_raw_data + e.offset + offset, size);
}

//------------------------------------------------------------
<commit_msg>resources research<commit_after>//
// open horizon -- undefined_darkness@outlook.com
//

#include "poc.h"
#include <assert.h>

//------------------------------------------------------------

bool poc_file::open(const char *name)
{
    return open(nya_resources::get_resources_provider().access(name));
}

//------------------------------------------------------------

bool poc_file::open(nya_resources::resource_data *data)
{
    close();
    m_data = data;
    if (!m_data)
        return false;

    uint32_t count = 0;
    if (!m_data->read_chunk(&count, sizeof(uint32_t)))
    {
        close();
        return false;
    }

    std::vector<uint32_t> offsets(count);
    if (!m_data->read_chunk(offsets.data(), count * sizeof(uint32_t), sizeof(uint32_t)))
    {
        close();
        return false;
    }

    return init((uint32_t *)m_raw_data + 1, count, (uint32_t)m_data->get_size());
}

//------------------------------------------------------------

bool poc_file::open(const void *data, size_t size)
{
    close();
    m_raw_data = (char *)data;
    if (!m_raw_data || size < 4)
        return false;

    uint32_t count = *(uint32_t *)m_raw_data;
    if ((count + 1) * sizeof(uint32_t) > size)
    {
        m_raw_data = 0;
        return false;
    }

    return init((uint32_t *)m_raw_data + 1, count, (uint32_t)size);
}

//------------------------------------------------------------

bool poc_file::init(const uint32_t *offsets, uint32_t count, uint32_t size)
{
    m_entries.resize(count);
    for (size_t i = 0; i < m_entries.size(); ++i)
    {
        auto &e = m_entries[i];
        e.offset = offsets[i];
        e.size = 0;
        if (!e.offset)
            continue;

        for (size_t j = i + 1; j < m_entries.size(); ++j)
        {
            if (!offsets[j])
                continue;

            e.size = offsets[j] - e.offset;
            break;
        }
    }

    if (!m_entries.empty())
        m_entries.back().size = size - m_entries.back().offset;

    int idx = 0;
    for (auto &e: m_entries)
    {
        e.type = 0;
        if (e.size >= sizeof(uint32_t))
            read_chunk_data(idx++, &e.type, sizeof(uint32_t));

        assert(e.offset + e.size <= size);
    }

    return true;
}

//------------------------------------------------------------

void poc_file::close()
{
    if (m_data)
        m_data->release();
    m_entries.clear();
    m_data = 0;
    m_raw_data = 0;
}

//------------------------------------------------------------

uint32_t poc_file::get_chunk_type(int idx) const
{
    if (idx < 0 || idx >= get_chunks_count())
        return 0;

    return m_entries[idx].type;
}

//------------------------------------------------------------

uint32_t poc_file::get_chunk_size(int idx) const
{
    if (idx < 0 || idx >= get_chunks_count())
        return 0;

    return m_entries[idx].size;
}

//------------------------------------------------------------

uint32_t poc_file::get_chunk_offset(int idx) const
{
    if (idx < 0 || idx >= get_chunks_count())
        return 0;

    return m_entries[idx].size;
}

//------------------------------------------------------------

bool poc_file::read_chunk_data(int idx, void *data) const
{
    return read_chunk_data(idx, data, get_chunk_size(idx));
}

//------------------------------------------------------------

bool poc_file::read_chunk_data(int idx, void *data, uint32_t size, uint32_t offset) const
{
    if (idx < 0 || idx >= get_chunks_count() || !data)
        return false;

    const auto &e = m_entries[idx];
    if (offset + size > e.size)
        return false;

    if (m_data)
        return m_data->read_chunk(data, size, e.offset + offset);

    return memcpy(data, m_raw_data + e.offset + offset, size);
}

//------------------------------------------------------------
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 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/dreamview/backend/hmi/hmi.h"

#include <string>
#include <vector>

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/util/json_util.h"
#include "modules/dreamview/backend/common/dreamview_gflags.h"
#include "modules/dreamview/backend/point_cloud/point_cloud_updater.h"

namespace apollo {
namespace dreamview {

using apollo::common::util::JsonUtil;
using Json = WebSocketHandler::Json;

HMI::HMI(WebSocketHandler* websocket, MapService* map_service)
    : hmi_worker_(new HMIWorker()),
      monitor_log_buffer_(apollo::common::monitor::MonitorMessageItem::HMI),
      websocket_(websocket),
      map_service_(map_service) {
  if (websocket_) {
    RegisterMessageHandlers();
  }
}

void HMI::Start() { hmi_worker_->Start(); }

void HMI::Stop() { hmi_worker_->Stop(); }

void HMI::RegisterMessageHandlers() {
  // Broadcast HMIStatus to clients when status changed.
  hmi_worker_->RegisterStatusUpdateHandler(
      [this](const bool status_changed, HMIStatus* status) {
        if (!status_changed) {
          // Status doesn't change, skip broadcasting.
          return;
        }
        websocket_->BroadcastData(
            JsonUtil::ProtoToTypedJson("HMIStatus", *status).dump());
        if (status->current_map().empty()) {
          monitor_log_buffer_.WARN("You haven't selected a map yet!");
        }
        if (status->current_vehicle().empty()) {
          monitor_log_buffer_.WARN("You haven't selected a vehicle yet!");
        }
      });

  // Send current status and vehicle param to newly joined client.
  websocket_->RegisterConnectionReadyHandler(
      [this](WebSocketHandler::Connection* conn) {
        const auto status_json =
            JsonUtil::ProtoToTypedJson("HMIStatus", hmi_worker_->GetStatus());
        websocket_->SendData(conn, status_json.dump());
        SendVehicleParam(conn);
      });

  websocket_->RegisterMessageHandler(
      "HMIAction",
      [this](const Json& json, WebSocketHandler::Connection* conn) {
        // Run HMIWorker::Trigger(action) if json is {action: "<action>"}
        // Run HMIWorker::Trigger(action, value) if "value" field is provided.
        std::string action;
        if (!JsonUtil::GetStringFromJson(json, "action", &action)) {
          AERROR << "Truncated HMIAction request.";
          return;
        }
        HMIAction hmi_action;
        if (!HMIAction_Parse(action, &hmi_action)) {
          AERROR << "Invalid HMIAction string: " << action;
        }
        std::string value;
        if (JsonUtil::GetStringFromJson(json, "value", &value)) {
          hmi_worker_->Trigger(hmi_action, value);
        } else {
          hmi_worker_->Trigger(hmi_action);
        }

        // Extra works for current Dreamview.
        if (hmi_action == HMIAction::CHANGE_MAP) {
          // Reload simulation map after changing map.
          CHECK(map_service_->ReloadMap(true))
              << "Failed to load new simulation map: " << value;
        } else if (hmi_action == HMIAction::CHANGE_VEHICLE) {
          // Reload lidar params for point cloud service.
          PointCloudUpdater::LoadLidarHeight(FLAGS_lidar_height_yaml);
          SendVehicleParam();
        }
      });

  // HMI client asks for adding new DriveEvent.
  websocket_->RegisterMessageHandler(
      "SubmitDriveEvent",
      [this](const Json& json, WebSocketHandler::Connection* conn) {
        // json should contain event_time_ms and event_msg.
        uint64_t event_time_ms;
        std::string event_msg;
        std::vector<std::string> event_types;
        bool is_reportable;
        if (JsonUtil::GetNumberFromJson(json, "event_time_ms",
                                        &event_time_ms) &&
            JsonUtil::GetStringFromJson(json, "event_msg", &event_msg) &&
            JsonUtil::GetStringVectorFromJson(json, "event_type",
                                              &event_types) &&
            JsonUtil::GetBooleanFromJson(json, "is_reportable",
                                         &is_reportable)) {
          hmi_worker_->SubmitDriveEvent(event_time_ms, event_msg, event_types,
                                        is_reportable);
          monitor_log_buffer_.INFO("Drive event added.");
        } else {
          AERROR << "Truncated SubmitDriveEvent request.";
          monitor_log_buffer_.WARN("Failed to submit a drive event.");
        }
      });
}

void HMI::SendVehicleParam(WebSocketHandler::Connection* conn) {
  if (websocket_ == nullptr) {
    return;
  }

  const auto& vehicle_param =
      apollo::common::VehicleConfigHelper::GetConfig().vehicle_param();
  const std::string json_str =
      JsonUtil::ProtoToTypedJson("VehicleParam", vehicle_param).dump();
  if (conn != nullptr) {
    websocket_->SendData(conn, json_str);
  } else {
    websocket_->BroadcastData(json_str);
  }
}

}  // namespace dreamview
}  // namespace apollo
<commit_msg>Dreamview: Trigger calibration monitor when changing mode.<commit_after>/******************************************************************************
 * Copyright 2017 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/dreamview/backend/hmi/hmi.h"

#include <string>
#include <vector>

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/util/json_util.h"
#include "modules/dreamview/backend/common/dreamview_gflags.h"
#include "modules/dreamview/backend/point_cloud/point_cloud_updater.h"

namespace apollo {
namespace dreamview {

using apollo::common::util::JsonUtil;
using Json = WebSocketHandler::Json;

HMI::HMI(WebSocketHandler* websocket, MapService* map_service)
    : hmi_worker_(new HMIWorker()),
      monitor_log_buffer_(apollo::common::monitor::MonitorMessageItem::HMI),
      websocket_(websocket),
      map_service_(map_service) {
  if (websocket_) {
    RegisterMessageHandlers();
  }
}

void HMI::Start() { hmi_worker_->Start(); }

void HMI::Stop() { hmi_worker_->Stop(); }

void HMI::RegisterMessageHandlers() {
  // Broadcast HMIStatus to clients when status changed.
  hmi_worker_->RegisterStatusUpdateHandler(
      [this](const bool status_changed, HMIStatus* status) {
        if (!status_changed) {
          // Status doesn't change, skip broadcasting.
          return;
        }
        websocket_->BroadcastData(
            JsonUtil::ProtoToTypedJson("HMIStatus", *status).dump());
        if (status->current_map().empty()) {
          monitor_log_buffer_.WARN("You haven't selected a map yet!");
        }
        if (status->current_vehicle().empty()) {
          monitor_log_buffer_.WARN("You haven't selected a vehicle yet!");
        }
      });

  // Send current status and vehicle param to newly joined client.
  websocket_->RegisterConnectionReadyHandler(
      [this](WebSocketHandler::Connection* conn) {
        const auto status_json =
            JsonUtil::ProtoToTypedJson("HMIStatus", hmi_worker_->GetStatus());
        websocket_->SendData(conn, status_json.dump());
        SendVehicleParam(conn);
      });

  websocket_->RegisterMessageHandler(
      "HMIAction",
      [this](const Json& json, WebSocketHandler::Connection* conn) {
        // Run HMIWorker::Trigger(action) if json is {action: "<action>"}
        // Run HMIWorker::Trigger(action, value) if "value" field is provided.
        std::string action;
        if (!JsonUtil::GetStringFromJson(json, "action", &action)) {
          AERROR << "Truncated HMIAction request.";
          return;
        }
        HMIAction hmi_action;
        if (!HMIAction_Parse(action, &hmi_action)) {
          AERROR << "Invalid HMIAction string: " << action;
        }
        std::string value;
        if (JsonUtil::GetStringFromJson(json, "value", &value)) {
          hmi_worker_->Trigger(hmi_action, value);
        } else {
          hmi_worker_->Trigger(hmi_action);
        }

        // Extra works for current Dreamview.
        if (hmi_action == HMIAction::CHANGE_MAP) {
          // Reload simulation map after changing map.
          CHECK(map_service_->ReloadMap(true))
              << "Failed to load new simulation map: " << value;
        } else if (hmi_action == HMIAction::CHANGE_VEHICLE) {
          // Reload lidar params for point cloud service.
          PointCloudUpdater::LoadLidarHeight(FLAGS_lidar_height_yaml);
          SendVehicleParam();
        } else if (hmi_action == HMIAction::CHANGE_MODE) {
          static constexpr char kCalibrationMode[] = "Mkz Calibration";
          if (value == kCalibrationMode) {
            // TODO(vivian): Finish.
            // calibration_mon->start();
          } else {
            // calibration_mon->stop();
          }
        }
      });

  // HMI client asks for adding new DriveEvent.
  websocket_->RegisterMessageHandler(
      "SubmitDriveEvent",
      [this](const Json& json, WebSocketHandler::Connection* conn) {
        // json should contain event_time_ms and event_msg.
        uint64_t event_time_ms;
        std::string event_msg;
        std::vector<std::string> event_types;
        bool is_reportable;
        if (JsonUtil::GetNumberFromJson(json, "event_time_ms",
                                        &event_time_ms) &&
            JsonUtil::GetStringFromJson(json, "event_msg", &event_msg) &&
            JsonUtil::GetStringVectorFromJson(json, "event_type",
                                              &event_types) &&
            JsonUtil::GetBooleanFromJson(json, "is_reportable",
                                         &is_reportable)) {
          hmi_worker_->SubmitDriveEvent(event_time_ms, event_msg, event_types,
                                        is_reportable);
          monitor_log_buffer_.INFO("Drive event added.");
        } else {
          AERROR << "Truncated SubmitDriveEvent request.";
          monitor_log_buffer_.WARN("Failed to submit a drive event.");
        }
      });
}

void HMI::SendVehicleParam(WebSocketHandler::Connection* conn) {
  if (websocket_ == nullptr) {
    return;
  }

  const auto& vehicle_param =
      apollo::common::VehicleConfigHelper::GetConfig().vehicle_param();
  const std::string json_str =
      JsonUtil::ProtoToTypedJson("VehicleParam", vehicle_param).dump();
  if (conn != nullptr) {
    websocket_->SendData(conn, json_str);
  } else {
    websocket_->BroadcastData(json_str);
  }
}

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


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, ELM Library Project
// 3-clause BSD License
//
//M*/
/** @file Implement greedy projection triangulation
 */
#include "elm/layers/triangulation.h"

#ifdef __WITH_PCL   // the layer is otherwise implemented as unsupported

#include <pcl/point_types.h>
#include <pcl/kdtree/kdtree_flann.h>
//#include <opencv2/core/eigen.hpp>   // for eigen2cv(), must be preceeded definitio of Eigen either PCL or #include <Eigen/Dense>

#include "elm/core/defs.h"          // ELM_PI2
#include "elm/core/exception.h"
#include "elm/core/featuredata.h"
#include "elm/core/graph/adjacency.h"
#include "elm/core/inputname.h"
#include "elm/core/layerconfig.h"
#include "elm/core/signal.h"
#include "elm/ts/layerattr_.h"

using namespace std;
using namespace cv;
using namespace pcl;
using namespace elm;

extern template class pcl::PointCloud<pcl::PointNormal >;

extern template class boost::shared_ptr<pcl::PointCloud<pcl::PointNormal > >;

// initialize paramter keys
const string Triangulation::PARAM_SEARCH_RADIUS        = "radius";
const string Triangulation::PARAM_MU                   = "mu";
const string Triangulation::PARAM_MAX_NN               = "max_nn";
const string Triangulation::PARAM_MAX_SURFACE_ANGLE    = "max_surface_angle";
const string Triangulation::PARAM_MIN_ANGLE            = "min_angle";
const string Triangulation::PARAM_MAX_ANGLE            = "max_angle";
const string Triangulation::PARAM_IS_NORMAL_CONSISTENT = "normal_consistency";

// initialize default float paramter values
const float Triangulation::DEFAULT_SEARCH_RADIUS            = 0.025f;
const float Triangulation::DEFAULT_MU                       = 2.5f;
const float Triangulation::DEFAULT_MAX_SURFACE_ANGLE        = ELM_PI2 / 2.f;
const float Triangulation::DEFAULT_MIN_ANGLE                = CV_PI / 18.f;
const float Triangulation::DEFAULT_MAX_ANGLE                = 2 * CV_PI / 3.f;
const int   Triangulation::DEFAULT_MAX_NN                   = 100;  ///< maximum neighrest neighbors
const bool  Triangulation::DEFAULT_IS_NORMAL_CONSISTENCY    = false;

// initialize I/O names
const string Triangulation::KEY_INPUT_CLOUD_POINT_NORMAL    = "cloud";
const string Triangulation::KEY_OUTPUT_VERTICES             = "vertices";
const string Triangulation::KEY_OUTPUT_OPT_ADJACENCY        = "adjacency";

#include <boost/assign/list_of.hpp>
template <>
elm::MapIONames LayerAttr_<Triangulation>::io_pairs = boost::assign::map_list_of
        ELM_ADD_INPUT_PAIR(Triangulation::KEY_INPUT_CLOUD_POINT_NORMAL)
        ELM_ADD_OUTPUT_PAIR(Triangulation::KEY_OUTPUT_VERTICES)
        ;

Triangulation::Triangulation()
    : base_Layer()
{
}

void Triangulation::Clear()
{
    gp3 = pcl::GreedyProjectionTriangulation<pcl::PointNormal>();
}

void Triangulation::Reconfigure(const LayerConfig &cfg)
{
    PTree p = cfg.Params();

    float search_radius     = p.get<float>(PARAM_SEARCH_RADIUS, DEFAULT_SEARCH_RADIUS);

    float mu                = p.get<float>( PARAM_MU,     DEFAULT_MU);
    int max_nn              = p.get<int>(   PARAM_MAX_NN, DEFAULT_MAX_NN);
    float max_surface_angle = p.get<float>( PARAM_MAX_SURFACE_ANGLE, DEFAULT_MAX_SURFACE_ANGLE);
    float min_angle         = p.get<float>( PARAM_MIN_ANGLE, DEFAULT_MIN_ANGLE);
    float max_angle         = p.get<float>( PARAM_MAX_ANGLE, DEFAULT_MAX_ANGLE);
    bool is_normal_consistency = p.get<bool>(PARAM_IS_NORMAL_CONSISTENT, DEFAULT_IS_NORMAL_CONSISTENCY);

    // Set the maximum distance between connected points (maximum edge length)
    gp3.setSearchRadius(search_radius);

    // Set typical values for the parameters
    gp3.setMu(mu);
    gp3.setMaximumNearestNeighbors(max_nn);
    gp3.setMaximumSurfaceAngle(max_surface_angle);
    gp3.setMinimumAngle(min_angle);
    gp3.setMaximumAngle(max_angle);
    gp3.setNormalConsistency(is_normal_consistency);
}

void Triangulation::InputNames(const LayerInputNames &io)
{
    name_src_cloud_ = io.Input(KEY_INPUT_CLOUD_POINT_NORMAL);
}

void Triangulation::OutputNames(const LayerOutputNames &io)
{
    name_vertices_  = io.Output(KEY_OUTPUT_VERTICES);
    name_opt_adj_   = io.OutputOpt(KEY_OUTPUT_OPT_ADJACENCY);
}

void Triangulation::Activate(const Signal &signal)
{
    CloudPtNrmlPtr in = signal.MostRecent(name_src_cloud_).get<CloudPtNrmlPtr>();
    if(in->empty()) {

        ELM_THROW_BAD_DIMS("Cannot Activate Triangulation layer with empty input point cloud.");
    }

    // Create search tree*
    search::KdTree<PointNormal>::Ptr tree2(new search::KdTree<PointNormal>);
    tree2->setInputCloud(in);

    gp3.setInputCloud(in);
    gp3.setSearchMethod(tree2);

    // Get result
    Triangles vertices;
    gp3.reconstruct(vertices);

    vertices_ = VecVertices2Mat(vertices, false);

    if(name_opt_adj_) {

        CloudXYZPtr cld_xyz(new CloudXYZ);
        copyPointCloud(*in, *cld_xyz);

        TriangulatedCloudToAdjacency(cld_xyz, vertices, adj_);
    }
}

void Triangulation::Response(Signal &signal)
{
    // Additional vertex information
//    vector<int> parts = gp3.getPartIDs();
//    vector<int> states = gp3.getPointStates();

    signal.Append(name_vertices_, vertices_);

    if(name_opt_adj_) {

        signal.Append(name_opt_adj_.get(), adj_);
    }
}

#endif // __WITH_PCL
<commit_msg>add extern template instantiation<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, ELM Library Project
// 3-clause BSD License
//
//M*/
/** @file Implement greedy projection triangulation
 */
#include "elm/layers/triangulation.h"

#ifdef __WITH_PCL   // the layer is otherwise implemented as unsupported

#include <pcl/point_types.h>
#include <pcl/kdtree/kdtree_flann.h>
//#include <opencv2/core/eigen.hpp>   // for eigen2cv(), must be preceeded definitio of Eigen either PCL or #include <Eigen/Dense>

#include "elm/core/defs.h"          // ELM_PI2
#include "elm/core/exception.h"
#include "elm/core/featuredata.h"
#include "elm/core/graph/adjacency.h"
#include "elm/core/inputname.h"
#include "elm/core/layerconfig.h"
#include "elm/core/signal.h"
#include "elm/ts/layerattr_.h"

using namespace std;
using namespace cv;
using namespace pcl;
using namespace elm;

extern template class pcl::PointCloud<pcl::PointXYZ >;
extern template class pcl::PointCloud<pcl::PointNormal >;

extern template class boost::shared_ptr<pcl::PointCloud<pcl::PointXYZ > >;
extern template class boost::shared_ptr<pcl::PointCloud<pcl::PointNormal > >;

// initialize paramter keys
const string Triangulation::PARAM_SEARCH_RADIUS        = "radius";
const string Triangulation::PARAM_MU                   = "mu";
const string Triangulation::PARAM_MAX_NN               = "max_nn";
const string Triangulation::PARAM_MAX_SURFACE_ANGLE    = "max_surface_angle";
const string Triangulation::PARAM_MIN_ANGLE            = "min_angle";
const string Triangulation::PARAM_MAX_ANGLE            = "max_angle";
const string Triangulation::PARAM_IS_NORMAL_CONSISTENT = "normal_consistency";

// initialize default float paramter values
const float Triangulation::DEFAULT_SEARCH_RADIUS            = 0.025f;
const float Triangulation::DEFAULT_MU                       = 2.5f;
const float Triangulation::DEFAULT_MAX_SURFACE_ANGLE        = ELM_PI2 / 2.f;
const float Triangulation::DEFAULT_MIN_ANGLE                = CV_PI / 18.f;
const float Triangulation::DEFAULT_MAX_ANGLE                = 2 * CV_PI / 3.f;
const int   Triangulation::DEFAULT_MAX_NN                   = 100;  ///< maximum neighrest neighbors
const bool  Triangulation::DEFAULT_IS_NORMAL_CONSISTENCY    = false;

// initialize I/O names
const string Triangulation::KEY_INPUT_CLOUD_POINT_NORMAL    = "cloud";
const string Triangulation::KEY_OUTPUT_VERTICES             = "vertices";
const string Triangulation::KEY_OUTPUT_OPT_ADJACENCY        = "adjacency";

#include <boost/assign/list_of.hpp>
template <>
elm::MapIONames LayerAttr_<Triangulation>::io_pairs = boost::assign::map_list_of
        ELM_ADD_INPUT_PAIR(Triangulation::KEY_INPUT_CLOUD_POINT_NORMAL)
        ELM_ADD_OUTPUT_PAIR(Triangulation::KEY_OUTPUT_VERTICES)
        ;

Triangulation::Triangulation()
    : base_Layer()
{
}

void Triangulation::Clear()
{
    gp3 = pcl::GreedyProjectionTriangulation<pcl::PointNormal>();
}

void Triangulation::Reconfigure(const LayerConfig &cfg)
{
    PTree p = cfg.Params();

    float search_radius     = p.get<float>(PARAM_SEARCH_RADIUS, DEFAULT_SEARCH_RADIUS);

    float mu                = p.get<float>( PARAM_MU,     DEFAULT_MU);
    int max_nn              = p.get<int>(   PARAM_MAX_NN, DEFAULT_MAX_NN);
    float max_surface_angle = p.get<float>( PARAM_MAX_SURFACE_ANGLE, DEFAULT_MAX_SURFACE_ANGLE);
    float min_angle         = p.get<float>( PARAM_MIN_ANGLE, DEFAULT_MIN_ANGLE);
    float max_angle         = p.get<float>( PARAM_MAX_ANGLE, DEFAULT_MAX_ANGLE);
    bool is_normal_consistency = p.get<bool>(PARAM_IS_NORMAL_CONSISTENT, DEFAULT_IS_NORMAL_CONSISTENCY);

    // Set the maximum distance between connected points (maximum edge length)
    gp3.setSearchRadius(search_radius);

    // Set typical values for the parameters
    gp3.setMu(mu);
    gp3.setMaximumNearestNeighbors(max_nn);
    gp3.setMaximumSurfaceAngle(max_surface_angle);
    gp3.setMinimumAngle(min_angle);
    gp3.setMaximumAngle(max_angle);
    gp3.setNormalConsistency(is_normal_consistency);
}

void Triangulation::InputNames(const LayerInputNames &io)
{
    name_src_cloud_ = io.Input(KEY_INPUT_CLOUD_POINT_NORMAL);
}

void Triangulation::OutputNames(const LayerOutputNames &io)
{
    name_vertices_  = io.Output(KEY_OUTPUT_VERTICES);
    name_opt_adj_   = io.OutputOpt(KEY_OUTPUT_OPT_ADJACENCY);
}

void Triangulation::Activate(const Signal &signal)
{
    CloudPtNrmlPtr in = signal.MostRecent(name_src_cloud_).get<CloudPtNrmlPtr>();
    if(in->empty()) {

        ELM_THROW_BAD_DIMS("Cannot Activate Triangulation layer with empty input point cloud.");
    }

    // Create search tree*
    search::KdTree<PointNormal>::Ptr tree2(new search::KdTree<PointNormal>);
    tree2->setInputCloud(in);

    gp3.setInputCloud(in);
    gp3.setSearchMethod(tree2);

    // Get result
    Triangles vertices;
    gp3.reconstruct(vertices);

    vertices_ = VecVertices2Mat(vertices, false);

    if(name_opt_adj_) {

        CloudXYZPtr cld_xyz(new CloudXYZ);
        copyPointCloud(*in, *cld_xyz);

        TriangulatedCloudToAdjacency(cld_xyz, vertices, adj_);
    }
}

void Triangulation::Response(Signal &signal)
{
    // Additional vertex information
//    vector<int> parts = gp3.getPartIDs();
//    vector<int> states = gp3.getPointStates();

    signal.Append(name_vertices_, vertices_);

    if(name_opt_adj_) {

        signal.Append(name_opt_adj_.get(), adj_);
    }
}

#endif // __WITH_PCL
<|endoftext|>


<commit_before>/*
* Copyright (c) 2018 Airbus Defence and Space and RISC Software GmbH
*
* 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 "CCPACSPressureBulkheadAssemblyPosition.h"

#include <gp_Pln.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <TopExp.hxx>
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
#include <gp_Ax3.hxx>
#include <TopTools_IndexedMapOfShape.hxx>

#include "CCPACSFuselage.h"
#include "CCPACSFrame.h"
#include "CCPACSPressureBulkhead.h"
#include "CCPACSFuselageStringerFramePosition.h"
#include "CTiglUIDManager.h"
#include "tiglcommonfunctions.h"

namespace tigl
{
CCPACSPressureBulkheadAssemblyPosition::CCPACSPressureBulkheadAssemblyPosition(CCPACSPressureBulkheadAssembly* parent,
                                                                               CTiglUIDManager* uidMgr)
    : generated::CPACSPressureBulkheadAssemblyPosition(parent, uidMgr)
    , invalidated(true)
{
}

void CCPACSPressureBulkheadAssemblyPosition::SetFrameUID(const std::string& value)
{
    generated::CPACSPressureBulkheadAssemblyPosition::SetFrameUID(value);
    Invalidate();
}

void CCPACSPressureBulkheadAssemblyPosition::SetPressureBulkheadElementUID(const std::string& value)
{
    generated::CPACSPressureBulkheadAssemblyPosition::SetPressureBulkheadElementUID(value);
    Invalidate();
}

void CCPACSPressureBulkheadAssemblyPosition::Invalidate()
{
    m_geometry      = boost::none;
}

TopoDS_Shape CCPACSPressureBulkheadAssemblyPosition::GetGeometry()
{
    if (!m_geometry)
        BuildGeometry();
    return m_geometry.value();
}

void CCPACSPressureBulkheadAssemblyPosition::BuildGeometry()
{
    CCPACSFrame& frame = m_uidMgr->ResolveObject<CCPACSFrame>(m_frameUID);

    if (frame.GetFramePositions().size() == 1) {
        TopTools_IndexedMapOfShape edgeMap;
        TopExp::MapShapes(frame.GetGeometry(true), TopAbs_EDGE, edgeMap);

        if (edgeMap.Extent() != 1) {
            throw CTiglError("1D frame geometry should have exactly one edge");
        }

        TopoDS_Edge edge = TopoDS::Edge(edgeMap(1));
        m_geometry       = BRepBuilderAPI_MakeFace(BRepBuilderAPI_MakeWire(edge));

    } else if (frame.GetFramePositions().size() >= 2) {
        CCPACSFuselage& fuselage = *m_parent->GetParent()->GetParent();

        std::vector<TopoDS_Edge> edges;
        std::vector<gp_Pnt> refPoints;
        for (int i = 0; i < frame.GetFramePositions().size(); i++) {
            const CCPACSFuselageStringerFramePosition& framePosition = *frame.GetFramePositions()[i];
            const gp_Pnt refPoint = framePosition.GetRefPoint();
            const gp_Pnt intersectionPoint = fuselage.Intersection(framePosition).Location();

            const TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(refPoint, intersectionPoint);

            edges.push_back(edge);
            refPoints.push_back(refPoint);
        }

        // we have to make the wires in the order of construction (clockwise)
        BRepBuilderAPI_MakeWire wireMaker;
        wireMaker.Add(edges[0]); // first edge

        // create all the edges of the frame
        TopTools_IndexedMapOfShape edgeMap;
        TopExp::MapShapes(frame.GetGeometry(true), TopAbs_EDGE, edgeMap);
        for (int i = 1; i <= edgeMap.Extent(); i++)
            wireMaker.Add(TopoDS::Edge(edgeMap(i)));

        wireMaker.Add(edges[edges.size() - 1]); // last edge

        // check if X coords of all ref points are the same
        for (int i = 0; i < refPoints.size() - 1; i++) {
            if (refPoints[i].X() != refPoints[i + 1].X()) {
                throw CTiglError("X coordinates of reference points are different (which is not available)");
            }
        }

        const double precision = 1e-6;

        // generate edges between non-equal points
        std::vector<TopoDS_Edge> edgesRef;
        for (int i = 0; i < refPoints.size() - 1; i++) {
            if (!refPoints[i].IsEqual(refPoints[i + 1], precision)) {
                edgesRef.push_back(BRepBuilderAPI_MakeEdge(refPoints[i + 1], refPoints[i]));
            }
        }

        // add edges to wire in reverse order
        for (int i = 0; i < edgesRef.size(); i++) {
            wireMaker.Add(edgesRef[edgesRef.size() - 1 - i]);
        }

        if (!wireMaker.IsDone()) {
            throw CTiglError("Wire generation failed");
        }

        m_geometry = BRepBuilderAPI_MakeFace(wireMaker.Wire());
    }
}
} // namespace tigl
<commit_msg>Minor changes (style and types)<commit_after>/*
* Copyright (c) 2018 Airbus Defence and Space and RISC Software GmbH
*
* 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 "CCPACSPressureBulkheadAssemblyPosition.h"

#include <gp_Pln.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <TopExp.hxx>
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
#include <gp_Ax3.hxx>
#include <TopTools_IndexedMapOfShape.hxx>

#include "CCPACSFuselage.h"
#include "CCPACSFrame.h"
#include "CCPACSPressureBulkhead.h"
#include "CCPACSFuselageStringerFramePosition.h"
#include "CTiglUIDManager.h"
#include "tiglcommonfunctions.h"

namespace tigl
{
CCPACSPressureBulkheadAssemblyPosition::CCPACSPressureBulkheadAssemblyPosition(CCPACSPressureBulkheadAssembly* parent,
                                                                               CTiglUIDManager* uidMgr)
    : generated::CPACSPressureBulkheadAssemblyPosition(parent, uidMgr)
    , invalidated(true)
{
}

void CCPACSPressureBulkheadAssemblyPosition::SetFrameUID(const std::string& value)
{
    generated::CPACSPressureBulkheadAssemblyPosition::SetFrameUID(value);
    Invalidate();
}

void CCPACSPressureBulkheadAssemblyPosition::SetPressureBulkheadElementUID(const std::string& value)
{
    generated::CPACSPressureBulkheadAssemblyPosition::SetPressureBulkheadElementUID(value);
    Invalidate();
}

void CCPACSPressureBulkheadAssemblyPosition::Invalidate()
{
    m_geometry = boost::none;
}

TopoDS_Shape CCPACSPressureBulkheadAssemblyPosition::GetGeometry()
{
    if (!m_geometry) {
        BuildGeometry();
    }
    return m_geometry.value();
}

void CCPACSPressureBulkheadAssemblyPosition::BuildGeometry()
{
    CCPACSFrame& frame = m_uidMgr->ResolveObject<CCPACSFrame>(m_frameUID);

    if (frame.GetFramePositions().size() == 1) {
        TopTools_IndexedMapOfShape edgeMap;
        TopExp::MapShapes(frame.GetGeometry(true), TopAbs_EDGE, edgeMap);

        if (edgeMap.Extent() != 1) {
            throw CTiglError("1D frame geometry should have exactly one edge");
        }

        TopoDS_Edge edge = TopoDS::Edge(edgeMap(1));
        m_geometry       = BRepBuilderAPI_MakeFace(BRepBuilderAPI_MakeWire(edge));

    }
    else if (frame.GetFramePositions().size() >= 2) {
        CCPACSFuselage& fuselage = *m_parent->GetParent()->GetParent();

        std::vector<TopoDS_Edge> edges;
        std::vector<gp_Pnt> refPoints;
        for (size_t i = 0; i < frame.GetFramePositions().size(); i++) {
            const CCPACSFuselageStringerFramePosition& framePosition = *frame.GetFramePositions()[i];
            const gp_Pnt refPoint = framePosition.GetRefPoint();
            const gp_Pnt intersectionPoint = fuselage.Intersection(framePosition).Location();

            const TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(refPoint, intersectionPoint);

            edges.push_back(edge);
            refPoints.push_back(refPoint);
        }

        // we have to make the wires in the order of construction (clockwise)
        BRepBuilderAPI_MakeWire wireMaker;
        wireMaker.Add(edges[0]); // first edge

        // create all the edges of the frame
        TopTools_IndexedMapOfShape edgeMap;
        TopExp::MapShapes(frame.GetGeometry(true), TopAbs_EDGE, edgeMap);
        for (int i = 1; i <= edgeMap.Extent(); i++) {
            wireMaker.Add(TopoDS::Edge(edgeMap(i)));
        }

        wireMaker.Add(edges[edges.size() - 1]); // last edge

        // check if X coords of all ref points are the same
        for (size_t i = 0; i < refPoints.size() - 1; i++) {
            if (refPoints[i].X() != refPoints[i + 1].X()) {
                throw CTiglError("X coordinates of reference points are different (which is not available)");
            }
        }

        const double precision = 1e-6;

        // generate edges between non-equal points
        std::vector<TopoDS_Edge> edgesRef;
        for (size_t i = 0; i < refPoints.size() - 1; i++) {
            if (!refPoints[i].IsEqual(refPoints[i + 1], precision)) {
                edgesRef.push_back(BRepBuilderAPI_MakeEdge(refPoints[i + 1], refPoints[i]));
            }
        }

        // add edges to wire in reverse order
        for (size_t i = 0; i < edgesRef.size(); i++) {
            wireMaker.Add(edgesRef[edgesRef.size() - 1 - i]);
        }

        if (!wireMaker.IsDone()) {
            throw CTiglError("Wire generation failed");
        }

        m_geometry = BRepBuilderAPI_MakeFace(wireMaker.Wire());
    }
}
} // namespace tigl
<|endoftext|>


<commit_before>#include "physics/forkable.hpp"

#include "geometry/named_quantities.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/si.hpp"

namespace principia {

using geometry::Instant;
using si::Second;
using ::testing::ElementsAre;

namespace physics {

class FakeTrajectory : public Forkable<FakeTrajectory,
                                       std::vector<Instant>::const_iterator> {
 public:
  FakeTrajectory();

  void push_back(Instant const& time);

 protected:
  not_null<FakeTrajectory*> that() override;
  not_null<FakeTrajectory const*> that() const override;

  TimelineConstIterator timeline_begin() const override;
  TimelineConstIterator timeline_end() const override;
  TimelineConstIterator timeline_find(Instant const& time) const override;
  void timeline_insert(TimelineConstIterator begin,
                       TimelineConstIterator end) override;
  bool timeline_empty() const override;

 private:
  std::vector<Instant> timeline_;

  template<typename Tr4jectory, typename TimelineConstIterator_>
  friend class Forkable;
  template<typename Tr4jectory, typename TimelineConstIterator_>
  friend class Forkable<Tr4jectory, TimelineConstIterator_>::Iterator;
};

FakeTrajectory::FakeTrajectory()
    : Forkable<FakeTrajectory,
               std::vector<Instant>::const_iterator>() {}

void FakeTrajectory::push_back(Instant const& time) {
  timeline_.push_back(time);
}

not_null<FakeTrajectory*> FakeTrajectory::that() {
  return this;
}

not_null<FakeTrajectory const*> FakeTrajectory::that() const {
  return this;
}

FakeTrajectory::TimelineConstIterator FakeTrajectory::timeline_begin() const {
  return timeline_.begin();
}

FakeTrajectory::TimelineConstIterator FakeTrajectory::timeline_end() const {
  return timeline_.end();
}

FakeTrajectory::TimelineConstIterator FakeTrajectory::timeline_find(
    Instant const & time) const {
  // Stupid O(N) search.
  for (auto it = timeline_.begin(); it != timeline_.end(); ++it) {
    if (*it == time) {
      return it;
    }
  }
  return timeline_.end();
}

void FakeTrajectory::timeline_insert(TimelineConstIterator begin,
                                     TimelineConstIterator end) {
  CHECK(timeline_empty());
  timeline_.insert(timeline_.end(), begin, end);
}

bool FakeTrajectory::timeline_empty() const {
  return timeline_.empty();
}

class ForkableTest : public testing::Test {
 protected:
  ForkableTest() :
    t0_(),
    t1_(t0_ + 7 * Second),
    t2_(t0_ + 17 * Second),
    t3_(t0_ + 27 * Second),
    t4_(t0_ + 37 * Second) {}

  static std::vector<Instant> After(
      not_null<FakeTrajectory const*> const trajectory,
      Instant const& time) {
    std::vector<Instant> after;
    FakeTrajectory::Iterator it = trajectory->Find(time);
    for (; it != trajectory->End(); ++it) {
      after.push_back(*it.current());
    }
    return after;
  }

  static Instant const& LastTime(
      not_null<FakeTrajectory const*> const trajectory) {
    FakeTrajectory::Iterator it = trajectory->End();
    --it;
    return *it.current();
  }

  static std::vector<Instant> Times(
      not_null<FakeTrajectory const*> const trajectory) {
    std::vector<Instant> times;
    FakeTrajectory::Iterator it = trajectory->Begin();
    for (; it != trajectory->End(); ++it) {
      times.push_back(*it.current());
    }
    return times;
  }

  FakeTrajectory trajectory_;
  Instant t0_, t1_, t2_, t3_, t4_;
};

using ForkableDeathTest = ForkableTest;

TEST_F(ForkableDeathTest, ForkError) {
  EXPECT_DEATH({
    trajectory_.push_back(t1_);
    trajectory_.push_back(t3_);
    trajectory_.NewFork(t2_);
  }, "nonexistent time");
}

TEST_F(ForkableDeathTest, ForkSuccess) {
  trajectory_.push_back(t1_);
  trajectory_.push_back(t2_);
  trajectory_.push_back(t3_);
  not_null<FakeTrajectory*> const fork = trajectory_.NewFork(t2_);
  fork->push_back(t4_);
  auto times = Times(&trajectory_);
  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_));
  times = Times(fork);
  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_, t4_));
}

TEST_F(ForkableTest, ForkAtLast) {
  trajectory_.push_back(t1_);
  trajectory_.push_back(t2_);
  trajectory_.push_back(t3_);
  not_null<FakeTrajectory*> const fork1 = trajectory_.NewFork(t3_);
  not_null<FakeTrajectory*> const fork2 = fork1->NewFork(LastTime(fork1));
  not_null<FakeTrajectory*> const fork3 = fork2->NewFork(LastTime(fork1));
  EXPECT_EQ(t3_, LastTime(&trajectory_));
  EXPECT_EQ(t3_, LastTime(fork1));

  auto times = Times(fork2);
  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_));
  EXPECT_EQ(t3_, LastTime(fork2));
  EXPECT_EQ(t3_, *fork2->ForkTime());

  auto after = After(fork3, t3_);
  EXPECT_THAT(after, ElementsAre(t3_));

  after = After(fork2, t3_);
  EXPECT_THAT(after, ElementsAre(t3_));

  fork1->push_back(t4_);
  times = Times(fork2);
  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_));

  after = After(fork1, t3_);
  EXPECT_THAT(after, ElementsAre(t3_, t4_));

  times = Times(fork3);
  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_));

  fork2->push_back(t4_);
  after = After(fork2, t3_);
  EXPECT_THAT(after, ElementsAre(t3_, t4_));

  fork3->push_back(t4_);
  after = After(fork3, t3_);
  EXPECT_THAT(after, ElementsAre(t3_, t4_));

  after = After(fork3, t2_);
  EXPECT_THAT(after, ElementsAre(t2_, t3_, t4_));
}

TEST_F(ForkableDeathTest, DeleteForkError) {
  EXPECT_DEATH({
    trajectory_.push_back(t1_);
    FakeTrajectory* root = &trajectory_;
    trajectory_.DeleteFork(&root);
  }, "'fork_time'.* non NULL");
  EXPECT_DEATH({
    trajectory_.push_back(t1_);
    FakeTrajectory* fork1 = trajectory_.NewFork(t1_);
    fork1->push_back(t2_);
    FakeTrajectory* fork2 = fork1->NewFork(t2_);
    trajectory_.DeleteFork(&fork2);
  }, "not a child");
}

//TEST_F(ForkableDeathTest, DeleteForkSuccess) {
//  trajectory_.push_back(t1_);
//  trajectory_.push_back(t2_);
//  trajectory_.push_back(t3_);
//  not_null<FakeTrajectory*> const fork1 = trajectory_.NewFork(t2_);
//  FakeTrajectory* fork2 = trajectory_.NewFork(t2_);
//  fork1.push_back(t4_);
//  trajectory_.DeleteFork(&fork2);
//  EXPECT_EQ(nullptr, fork2);
//  std::map<Instant, Position<World>> positions =
//      trajectory_.Positions();
//  std::map<Instant, Velocity<World>> velocities =
//      trajectory_.Velocities();
//  std::list<Instant> times = trajectory_.Times();
//  EXPECT_THAT(positions, ElementsAre(testing::Pair(t1_, q1_),
//                                     testing::Pair(t2_, q2_),
//                                     testing::Pair(t3_, q3_)));
//  EXPECT_THAT(velocities, ElementsAre(testing::Pair(t1_, p1_),
//                                      testing::Pair(t2_, p2_),
//                                      testing::Pair(t3_, p3_)));
//  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_));
//  EXPECT_THAT(fork1->body<MassiveBody>(), Eq(&massive_body_));
//  positions = fork1->Positions();
//  velocities = fork1->Velocities();
//  times = fork1->Times();
//  EXPECT_THAT(positions, ElementsAre(testing::Pair(t1_, q1_),
//                                     testing::Pair(t2_, q2_),
//                                     testing::Pair(t3_, q3_),
//                                     testing::Pair(t4_, q4_)));
//  EXPECT_THAT(velocities, ElementsAre(testing::Pair(t1_, p1_),
//                                      testing::Pair(t2_, p2_),
//                                      testing::Pair(t3_, p3_),
//                                      testing::Pair(t4_, p4_)));
//  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_, t4_));
//  EXPECT_THAT(fork1->body<MassiveBody>(), Eq(&massive_body_));
//  trajectory_.reset();
//}
//
//TEST_F(TrajectoryDeathTest, LastError) {
//  EXPECT_DEATH({
//    trajectory_.last();
//  }, "Empty trajectory");
//}
//
//TEST_F(ForkableDeathTest, LastSuccess) {
//  trajectory_.push_back(t1_);
//  trajectory_.push_back(t2_);
//  trajectory_.push_back(t3_);
//  EXPECT_EQ(q3_, trajectory_.last().degrees_of_freedom().position());
//  EXPECT_EQ(p3_, trajectory_.last().degrees_of_freedom().velocity());
//  EXPECT_EQ(t3_, trajectory_.last().time());
//}
//
//TEST_F(ForkableDeathTest, Root) {
//  trajectory_.push_back(t1_);
//  trajectory_.push_back(t2_);
//  trajectory_.push_back(t3_);
//  not_null<FakeTrajectory*> const fork = trajectory_.NewFork(t2_);
//  EXPECT_TRUE(trajectory_.is_root());
//  EXPECT_FALSE(fork->is_root());
//  EXPECT_EQ(trajectory_.get(), trajectory_.root());
//  EXPECT_EQ(trajectory_.get(), fork->root());
//  EXPECT_EQ(nullptr, trajectory_.fork_time());
//  EXPECT_EQ(t2_, *fork->fork_time());
//}
//
//TEST_F(TrajectoryDeathTest, NativeIteratorError) {
//  EXPECT_DEATH({
//    FakeTrajectory::NativeIterator it = trajectory_.last();
//  }, "Empty trajectory");
//  EXPECT_DEATH({
//    FakeTrajectory::NativeIterator it = trajectory_.first();
//    ++it;
//  }, "beyond end");
//}
//
//TEST_F(ForkableDeathTest, NativeIteratorSuccess) {
//  FakeTrajectory::NativeIterator it = trajectory_.first();
//  EXPECT_TRUE(it.at_end());
//
//  massless_trajectory_.push_back(t1_);
//  massless_trajectory_.push_back(t2_);
//  massless_trajectory_.push_back(t3_);
//
//  it = massless_trajectory_.first();
//  EXPECT_FALSE(it.at_end());
//  EXPECT_EQ(t1_, it.time());
//  EXPECT_EQ(d1_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_EQ(t2_, it.time());
//  EXPECT_EQ(d2_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_EQ(t3_, it.time());
//  EXPECT_EQ(d3_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_TRUE(it.at_end());
//
//  not_null<FakeTrajectory*> const fork = massless_trajectory_.NewFork(t2_);
//  fork.push_back(t4_);
//
//  it = fork->first();
//  EXPECT_FALSE(it.at_end());
//  EXPECT_EQ(t1_, it.time());
//  EXPECT_EQ(d1_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_EQ(t2_, it.time());
//  EXPECT_EQ(d2_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_EQ(t3_, it.time());
//  EXPECT_EQ(d3_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_EQ(t4_, it.time());
//  EXPECT_EQ(d4_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_TRUE(it.at_end());
//}
//
//TEST_F(ForkableDeathTest, NativeIteratorOnOrAfterSuccess) {
//  FakeTrajectory::NativeIterator it = trajectory_.on_or_after(t0_);
//  EXPECT_TRUE(it.at_end());
//
//  massless_trajectory_.push_back(t1_);
//  massless_trajectory_.push_back(t2_);
//  massless_trajectory_.push_back(t3_);
//
//  it = massless_trajectory_.on_or_after(t0_);
//  EXPECT_FALSE(it.at_end());
//  EXPECT_EQ(t1_, it.time());
//  EXPECT_EQ(d1_, it.degrees_of_freedom());
//  it = massless_trajectory_.on_or_after(t2_);
//  EXPECT_EQ(t2_, it.time());
//  EXPECT_EQ(d2_, it.degrees_of_freedom());
//  it = massless_trajectory_.on_or_after(t4_);
//  EXPECT_TRUE(it.at_end());
//
//  not_null<FakeTrajectory*> const fork = massless_trajectory_.NewFork(t2_);
//  fork.push_back(t4_);
//
//  it = fork->on_or_after(t0_);
//  EXPECT_FALSE(it.at_end());
//  EXPECT_EQ(t1_, it.time());
//  EXPECT_EQ(d1_, it.degrees_of_freedom());
//  it = fork->on_or_after(t2_);
//  EXPECT_EQ(t2_, it.time());
//  EXPECT_EQ(d2_, it.degrees_of_freedom());
//  it = fork->on_or_after(t4_);
//  EXPECT_EQ(t4_, it.time());
//  EXPECT_EQ(d4_, it.degrees_of_freedom());
//  it = fork->on_or_after(t4_ + 1 * Second);
//  EXPECT_TRUE(it.at_end());
//}

}  // namespace physics
}  // namespace principia
<commit_msg>Test cleanup.<commit_after>#include "physics/forkable.hpp"

#include "geometry/named_quantities.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/si.hpp"

namespace principia {

using geometry::Instant;
using si::Second;
using ::testing::ElementsAre;

namespace physics {

class FakeTrajectory : public Forkable<FakeTrajectory,
                                       std::vector<Instant>::const_iterator> {
 public:
  FakeTrajectory();

  void push_back(Instant const& time);

 protected:
  not_null<FakeTrajectory*> that() override;
  not_null<FakeTrajectory const*> that() const override;

  TimelineConstIterator timeline_begin() const override;
  TimelineConstIterator timeline_end() const override;
  TimelineConstIterator timeline_find(Instant const& time) const override;
  void timeline_insert(TimelineConstIterator begin,
                       TimelineConstIterator end) override;
  bool timeline_empty() const override;

 private:
  std::vector<Instant> timeline_;

  template<typename Tr4jectory, typename TimelineConstIterator_>
  friend class Forkable;
  template<typename Tr4jectory, typename TimelineConstIterator_>
  friend class Forkable<Tr4jectory, TimelineConstIterator_>::Iterator;
};

FakeTrajectory::FakeTrajectory()
    : Forkable<FakeTrajectory,
               std::vector<Instant>::const_iterator>() {}

void FakeTrajectory::push_back(Instant const& time) {
  timeline_.push_back(time);
}

not_null<FakeTrajectory*> FakeTrajectory::that() {
  return this;
}

not_null<FakeTrajectory const*> FakeTrajectory::that() const {
  return this;
}

FakeTrajectory::TimelineConstIterator FakeTrajectory::timeline_begin() const {
  return timeline_.begin();
}

FakeTrajectory::TimelineConstIterator FakeTrajectory::timeline_end() const {
  return timeline_.end();
}

FakeTrajectory::TimelineConstIterator FakeTrajectory::timeline_find(
    Instant const & time) const {
  // Stupid O(N) search.
  for (auto it = timeline_.begin(); it != timeline_.end(); ++it) {
    if (*it == time) {
      return it;
    }
  }
  return timeline_.end();
}

void FakeTrajectory::timeline_insert(TimelineConstIterator begin,
                                     TimelineConstIterator end) {
  CHECK(timeline_empty());
  timeline_.insert(timeline_.end(), begin, end);
}

bool FakeTrajectory::timeline_empty() const {
  return timeline_.empty();
}

class ForkableTest : public testing::Test {
 protected:
  ForkableTest() :
    t0_(),
    t1_(t0_ + 7 * Second),
    t2_(t0_ + 17 * Second),
    t3_(t0_ + 27 * Second),
    t4_(t0_ + 37 * Second) {}

  static std::vector<Instant> After(
      not_null<FakeTrajectory const*> const trajectory,
      Instant const& time) {
    std::vector<Instant> after;
    for (FakeTrajectory::Iterator it = trajectory->Find(time);
         it != trajectory->End();
         ++it) {
      after.push_back(*it.current());
    }
    return after;
  }

  static Instant const& LastTime(
      not_null<FakeTrajectory const*> const trajectory) {
    FakeTrajectory::Iterator it = trajectory->End();
    --it;
    return *it.current();
  }

  static std::vector<Instant> Times(
      not_null<FakeTrajectory const*> const trajectory) {
    std::vector<Instant> times;
    for (FakeTrajectory::Iterator it = trajectory->Begin();
         it != trajectory->End();
         ++it) {
      times.push_back(*it.current());
    }
    return times;
  }

  FakeTrajectory trajectory_;
  Instant t0_, t1_, t2_, t3_, t4_;
};

using ForkableDeathTest = ForkableTest;

TEST_F(ForkableDeathTest, ForkError) {
  EXPECT_DEATH({
    trajectory_.push_back(t1_);
    trajectory_.push_back(t3_);
    trajectory_.NewFork(t2_);
  }, "nonexistent time");
}

TEST_F(ForkableDeathTest, ForkSuccess) {
  trajectory_.push_back(t1_);
  trajectory_.push_back(t2_);
  trajectory_.push_back(t3_);
  not_null<FakeTrajectory*> const fork = trajectory_.NewFork(t2_);
  fork->push_back(t4_);
  auto times = Times(&trajectory_);
  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_));
  times = Times(fork);
  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_, t4_));
}

TEST_F(ForkableTest, ForkAtLast) {
  trajectory_.push_back(t1_);
  trajectory_.push_back(t2_);
  trajectory_.push_back(t3_);
  not_null<FakeTrajectory*> const fork1 = trajectory_.NewFork(t3_);
  not_null<FakeTrajectory*> const fork2 = fork1->NewFork(LastTime(fork1));
  not_null<FakeTrajectory*> const fork3 = fork2->NewFork(LastTime(fork1));
  EXPECT_EQ(t3_, LastTime(&trajectory_));
  EXPECT_EQ(t3_, LastTime(fork1));

  auto times = Times(fork2);
  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_));
  EXPECT_EQ(t3_, LastTime(fork2));
  EXPECT_EQ(t3_, *fork2->ForkTime());

  auto after = After(fork3, t3_);
  EXPECT_THAT(after, ElementsAre(t3_));

  after = After(fork2, t3_);
  EXPECT_THAT(after, ElementsAre(t3_));

  fork1->push_back(t4_);
  times = Times(fork2);
  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_));

  after = After(fork1, t3_);
  EXPECT_THAT(after, ElementsAre(t3_, t4_));

  times = Times(fork3);
  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_));

  fork2->push_back(t4_);
  after = After(fork2, t3_);
  EXPECT_THAT(after, ElementsAre(t3_, t4_));

  fork3->push_back(t4_);
  after = After(fork3, t3_);
  EXPECT_THAT(after, ElementsAre(t3_, t4_));

  after = After(fork3, t2_);
  EXPECT_THAT(after, ElementsAre(t2_, t3_, t4_));
}

TEST_F(ForkableDeathTest, DeleteForkError) {
  EXPECT_DEATH({
    trajectory_.push_back(t1_);
    FakeTrajectory* root = &trajectory_;
    trajectory_.DeleteFork(&root);
  }, "'fork_time'.* non NULL");
  EXPECT_DEATH({
    trajectory_.push_back(t1_);
    FakeTrajectory* fork1 = trajectory_.NewFork(t1_);
    fork1->push_back(t2_);
    FakeTrajectory* fork2 = fork1->NewFork(t2_);
    trajectory_.DeleteFork(&fork2);
  }, "not a child");
}

//TEST_F(ForkableDeathTest, DeleteForkSuccess) {
//  trajectory_.push_back(t1_);
//  trajectory_.push_back(t2_);
//  trajectory_.push_back(t3_);
//  not_null<FakeTrajectory*> const fork1 = trajectory_.NewFork(t2_);
//  FakeTrajectory* fork2 = trajectory_.NewFork(t2_);
//  fork1.push_back(t4_);
//  trajectory_.DeleteFork(&fork2);
//  EXPECT_EQ(nullptr, fork2);
//  std::map<Instant, Position<World>> positions =
//      trajectory_.Positions();
//  std::map<Instant, Velocity<World>> velocities =
//      trajectory_.Velocities();
//  std::list<Instant> times = trajectory_.Times();
//  EXPECT_THAT(positions, ElementsAre(testing::Pair(t1_, q1_),
//                                     testing::Pair(t2_, q2_),
//                                     testing::Pair(t3_, q3_)));
//  EXPECT_THAT(velocities, ElementsAre(testing::Pair(t1_, p1_),
//                                      testing::Pair(t2_, p2_),
//                                      testing::Pair(t3_, p3_)));
//  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_));
//  EXPECT_THAT(fork1->body<MassiveBody>(), Eq(&massive_body_));
//  positions = fork1->Positions();
//  velocities = fork1->Velocities();
//  times = fork1->Times();
//  EXPECT_THAT(positions, ElementsAre(testing::Pair(t1_, q1_),
//                                     testing::Pair(t2_, q2_),
//                                     testing::Pair(t3_, q3_),
//                                     testing::Pair(t4_, q4_)));
//  EXPECT_THAT(velocities, ElementsAre(testing::Pair(t1_, p1_),
//                                      testing::Pair(t2_, p2_),
//                                      testing::Pair(t3_, p3_),
//                                      testing::Pair(t4_, p4_)));
//  EXPECT_THAT(times, ElementsAre(t1_, t2_, t3_, t4_));
//  EXPECT_THAT(fork1->body<MassiveBody>(), Eq(&massive_body_));
//  trajectory_.reset();
//}
//
//TEST_F(TrajectoryDeathTest, LastError) {
//  EXPECT_DEATH({
//    trajectory_.last();
//  }, "Empty trajectory");
//}
//
//TEST_F(ForkableDeathTest, LastSuccess) {
//  trajectory_.push_back(t1_);
//  trajectory_.push_back(t2_);
//  trajectory_.push_back(t3_);
//  EXPECT_EQ(q3_, trajectory_.last().degrees_of_freedom().position());
//  EXPECT_EQ(p3_, trajectory_.last().degrees_of_freedom().velocity());
//  EXPECT_EQ(t3_, trajectory_.last().time());
//}
//
//TEST_F(ForkableDeathTest, Root) {
//  trajectory_.push_back(t1_);
//  trajectory_.push_back(t2_);
//  trajectory_.push_back(t3_);
//  not_null<FakeTrajectory*> const fork = trajectory_.NewFork(t2_);
//  EXPECT_TRUE(trajectory_.is_root());
//  EXPECT_FALSE(fork->is_root());
//  EXPECT_EQ(trajectory_.get(), trajectory_.root());
//  EXPECT_EQ(trajectory_.get(), fork->root());
//  EXPECT_EQ(nullptr, trajectory_.fork_time());
//  EXPECT_EQ(t2_, *fork->fork_time());
//}
//
//TEST_F(TrajectoryDeathTest, NativeIteratorError) {
//  EXPECT_DEATH({
//    FakeTrajectory::NativeIterator it = trajectory_.last();
//  }, "Empty trajectory");
//  EXPECT_DEATH({
//    FakeTrajectory::NativeIterator it = trajectory_.first();
//    ++it;
//  }, "beyond end");
//}
//
//TEST_F(ForkableDeathTest, NativeIteratorSuccess) {
//  FakeTrajectory::NativeIterator it = trajectory_.first();
//  EXPECT_TRUE(it.at_end());
//
//  massless_trajectory_.push_back(t1_);
//  massless_trajectory_.push_back(t2_);
//  massless_trajectory_.push_back(t3_);
//
//  it = massless_trajectory_.first();
//  EXPECT_FALSE(it.at_end());
//  EXPECT_EQ(t1_, it.time());
//  EXPECT_EQ(d1_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_EQ(t2_, it.time());
//  EXPECT_EQ(d2_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_EQ(t3_, it.time());
//  EXPECT_EQ(d3_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_TRUE(it.at_end());
//
//  not_null<FakeTrajectory*> const fork = massless_trajectory_.NewFork(t2_);
//  fork.push_back(t4_);
//
//  it = fork->first();
//  EXPECT_FALSE(it.at_end());
//  EXPECT_EQ(t1_, it.time());
//  EXPECT_EQ(d1_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_EQ(t2_, it.time());
//  EXPECT_EQ(d2_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_EQ(t3_, it.time());
//  EXPECT_EQ(d3_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_EQ(t4_, it.time());
//  EXPECT_EQ(d4_, it.degrees_of_freedom());
//  ++it;
//  EXPECT_TRUE(it.at_end());
//}
//
//TEST_F(ForkableDeathTest, NativeIteratorOnOrAfterSuccess) {
//  FakeTrajectory::NativeIterator it = trajectory_.on_or_after(t0_);
//  EXPECT_TRUE(it.at_end());
//
//  massless_trajectory_.push_back(t1_);
//  massless_trajectory_.push_back(t2_);
//  massless_trajectory_.push_back(t3_);
//
//  it = massless_trajectory_.on_or_after(t0_);
//  EXPECT_FALSE(it.at_end());
//  EXPECT_EQ(t1_, it.time());
//  EXPECT_EQ(d1_, it.degrees_of_freedom());
//  it = massless_trajectory_.on_or_after(t2_);
//  EXPECT_EQ(t2_, it.time());
//  EXPECT_EQ(d2_, it.degrees_of_freedom());
//  it = massless_trajectory_.on_or_after(t4_);
//  EXPECT_TRUE(it.at_end());
//
//  not_null<FakeTrajectory*> const fork = massless_trajectory_.NewFork(t2_);
//  fork.push_back(t4_);
//
//  it = fork->on_or_after(t0_);
//  EXPECT_FALSE(it.at_end());
//  EXPECT_EQ(t1_, it.time());
//  EXPECT_EQ(d1_, it.degrees_of_freedom());
//  it = fork->on_or_after(t2_);
//  EXPECT_EQ(t2_, it.time());
//  EXPECT_EQ(d2_, it.degrees_of_freedom());
//  it = fork->on_or_after(t4_);
//  EXPECT_EQ(t4_, it.time());
//  EXPECT_EQ(d4_, it.degrees_of_freedom());
//  it = fork->on_or_after(t4_ + 1 * Second);
//  EXPECT_TRUE(it.at_end());
//}

}  // namespace physics
}  // namespace principia
<|endoftext|>


<commit_before>/*************************************************************************
*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: RangeEdit.cxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "RangeEdit.hxx"

namespace chart
{

//============================================================================
// class RangeEdit
//----------------------------------------------------------------------------
RangeEdit::RangeEdit( Window* pParent, const ResId& rResId):
    Edit( pParent , rResId )
{
}

RangeEdit::~RangeEdit()
{
}

void RangeEdit::SetKeyInputHdl( const Link& rKeyInputLink )
{
    m_aKeyInputLink = rKeyInputLink;
}

void RangeEdit::KeyInput( const KeyEvent& rKEvt )
{
    const KeyCode& rKeyCode = rKEvt.GetKeyCode();
    if( !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_F2 )
    {
        if ( m_aKeyInputLink.IsSet() )
        {
            m_aKeyInputLink.Call( NULL );
        }
    }
    else
       Edit::KeyInput( rKEvt );
}

//.............................................................................
} //namespace chart
//.............................................................................
<commit_msg>INTEGRATION: CWS chart29 (1.3.40); FILE MERGED 2008/07/08 07:54:51 iha 1.3.40.1: #i88825# use update timer for range changes<commit_after>/*************************************************************************
*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: RangeEdit.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "RangeEdit.hxx"

namespace chart
{

//============================================================================
// class RangeEdit
//----------------------------------------------------------------------------
RangeEdit::RangeEdit( Window* pParent, const ResId& rResId):
    Edit( pParent , rResId )
{
    EnableUpdateData( 1000 );
}

RangeEdit::~RangeEdit()
{
}

void RangeEdit::SetKeyInputHdl( const Link& rKeyInputLink )
{
    m_aKeyInputLink = rKeyInputLink;
}

void RangeEdit::KeyInput( const KeyEvent& rKEvt )
{
    const KeyCode& rKeyCode = rKEvt.GetKeyCode();
    if( !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_F2 )
    {
        if ( m_aKeyInputLink.IsSet() )
        {
            m_aKeyInputLink.Call( NULL );
        }
    }
    else
       Edit::KeyInput( rKEvt );
}

//.............................................................................
} //namespace chart
//.............................................................................
<|endoftext|>


<commit_before>/*
  * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. 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.
  * A copy of the License is located at
  *
  *  http://aws.amazon.com/apache2.0
  *
  * or in the "license" file accompanying this file. This file 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 <aws/core/http/curl/CurlHandleContainer.h>
#include <aws/core/utils/logging/LogMacros.h>

#undef min

#include <algorithm>

using namespace Aws::Utils::Logging;
using namespace Aws::Http;

static const char* CURL_HANDLE_CONTAINER_TAG = "CurlHandleContainer";

CurlHandleContainer::CurlHandleContainer(unsigned maxSize, long requestTimeout, long connectTimeout) :
                m_maxPoolSize(maxSize), m_requestTimeout(requestTimeout), m_connectTimeout(connectTimeout),
                m_poolSize(0)
{
    AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Initializing CurlHandleContainer with size " << maxSize);
}

CurlHandleContainer::~CurlHandleContainer()
{
    AWS_LOG_INFO(CURL_HANDLE_CONTAINER_TAG, "Cleaning up CurlHandleContainer.");
    for (CURL* handle : m_handleContainer.ShutdownAndWait(m_poolSize))
    {
        AWS_LOG_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Cleaning up %p.", handle);
        curl_easy_cleanup(handle);
    }
}

CURL* CurlHandleContainer::AcquireCurlHandle()
{
    AWS_LOG_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Attempting to acquire curl connection.");

    if(!m_handleContainer.HasResourcesAvailable())
    {
        AWS_LOG_DEBUG(CURL_HANDLE_CONTAINER_TAG, "No current connections available in pool. Attempting to create new connections.");
        CheckAndGrowPool();
    }

    CURL* handle = m_handleContainer.Acquire();
    AWS_LOG_INFO(CURL_HANDLE_CONTAINER_TAG, "Connection has been released. Continuing.");
    AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Returning connection handle " << handle);
    return handle;
}

void CurlHandleContainer::ReleaseCurlHandle(CURL* handle)
{
    if (handle)
    {
        curl_easy_reset(handle);
        SetDefaultOptionsOnHandle(handle);
        AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Releasing curl handle " << handle);
        m_handleContainer.Release(handle);
        AWS_LOG_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Notified waiting threads.");
    }
}

bool CurlHandleContainer::CheckAndGrowPool()
{
    if (m_poolSize < m_maxPoolSize)
    {
        unsigned multiplier = m_poolSize > 0 ? m_poolSize : 1;
        unsigned amountToAdd = std::min(multiplier * 2, m_maxPoolSize - m_poolSize);
        AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "attempting to grow pool size by " << amountToAdd);

        unsigned actuallyAdded = 0;
        for (unsigned i = 0; i < amountToAdd; ++i)
        {
            CURL* curlHandle = curl_easy_init();

            if (curlHandle)
            {
                SetDefaultOptionsOnHandle(curlHandle);
                m_handleContainer.Release(curlHandle);
                ++actuallyAdded;
            }
            else
            {
                AWS_LOG_ERROR(CURL_HANDLE_CONTAINER_TAG, "curl_easy_init failed to allocate. Will continue retrying until amount to add has exhausted.");
            }
        }

        AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Pool successfully grown by " << actuallyAdded);
        m_poolSize += actuallyAdded;

        return actuallyAdded > 0;
    }

    AWS_LOG_INFO(CURL_HANDLE_CONTAINER_TAG, "Pool cannot be grown any further, already at max size.");

    return false;
}

void CurlHandleContainer::SetDefaultOptionsOnHandle(void* handle)
{
    //for timeouts to work in a multi-threaded context,
    //always turn signals off. This also forces dns queries to
    //not be included in the timeout calculations.
    curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1L);
    curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, m_requestTimeout);
    curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT_MS, m_connectTimeout);
}
<commit_msg>Made request timeout on curl based clients, behave more like a socket read timeout.<commit_after>/*
  * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. 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.
  * A copy of the License is located at
  *
  *  http://aws.amazon.com/apache2.0
  *
  * or in the "license" file accompanying this file. This file 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 <aws/core/http/curl/CurlHandleContainer.h>
#include <aws/core/utils/logging/LogMacros.h>

#undef min

#include <algorithm>

using namespace Aws::Utils::Logging;
using namespace Aws::Http;

static const char* CURL_HANDLE_CONTAINER_TAG = "CurlHandleContainer";

CurlHandleContainer::CurlHandleContainer(unsigned maxSize, long requestTimeout, long connectTimeout) :
                m_maxPoolSize(maxSize), m_requestTimeout(requestTimeout), m_connectTimeout(connectTimeout),
                m_poolSize(0)
{
    AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Initializing CurlHandleContainer with size " << maxSize);
}

CurlHandleContainer::~CurlHandleContainer()
{
    AWS_LOG_INFO(CURL_HANDLE_CONTAINER_TAG, "Cleaning up CurlHandleContainer.");
    for (CURL* handle : m_handleContainer.ShutdownAndWait(m_poolSize))
    {
        AWS_LOG_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Cleaning up %p.", handle);
        curl_easy_cleanup(handle);
    }
}

CURL* CurlHandleContainer::AcquireCurlHandle()
{
    AWS_LOG_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Attempting to acquire curl connection.");

    if(!m_handleContainer.HasResourcesAvailable())
    {
        AWS_LOG_DEBUG(CURL_HANDLE_CONTAINER_TAG, "No current connections available in pool. Attempting to create new connections.");
        CheckAndGrowPool();
    }

    CURL* handle = m_handleContainer.Acquire();
    AWS_LOG_INFO(CURL_HANDLE_CONTAINER_TAG, "Connection has been released. Continuing.");
    AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Returning connection handle " << handle);
    return handle;
}

void CurlHandleContainer::ReleaseCurlHandle(CURL* handle)
{
    if (handle)
    {
        curl_easy_reset(handle);
        SetDefaultOptionsOnHandle(handle);
        AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Releasing curl handle " << handle);
        m_handleContainer.Release(handle);
        AWS_LOG_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Notified waiting threads.");
    }
}

bool CurlHandleContainer::CheckAndGrowPool()
{
    if (m_poolSize < m_maxPoolSize)
    {
        unsigned multiplier = m_poolSize > 0 ? m_poolSize : 1;
        unsigned amountToAdd = std::min(multiplier * 2, m_maxPoolSize - m_poolSize);
        AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "attempting to grow pool size by " << amountToAdd);

        unsigned actuallyAdded = 0;
        for (unsigned i = 0; i < amountToAdd; ++i)
        {
            CURL* curlHandle = curl_easy_init();

            if (curlHandle)
            {
                SetDefaultOptionsOnHandle(curlHandle);
                m_handleContainer.Release(curlHandle);
                ++actuallyAdded;
            }
            else
            {
                AWS_LOG_ERROR(CURL_HANDLE_CONTAINER_TAG, "curl_easy_init failed to allocate. Will continue retrying until amount to add has exhausted.");
            }
        }

        AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Pool successfully grown by " << actuallyAdded);
        m_poolSize += actuallyAdded;

        return actuallyAdded > 0;
    }

    AWS_LOG_INFO(CURL_HANDLE_CONTAINER_TAG, "Pool cannot be grown any further, already at max size.");

    return false;
}

void CurlHandleContainer::SetDefaultOptionsOnHandle(void* handle)
{
    //for timeouts to work in a multi-threaded context,
    //always turn signals off. This also forces dns queries to
    //not be included in the timeout calculations.
    curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1L);
    curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, 0L);
    curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT_MS, m_connectTimeout);
    curl_easy_setopt(handle, CURLOPT_LOW_SPEED_LIMIT, 1L);
    curl_easy_setopt(handle, CURLOPT_LOW_SPEED_TIME, m_requestTimeout / 1000);
}
<|endoftext|>


<commit_before>#ifndef __RINALITE_CDAP_H__
#define __RINALITE_CDAP_H__

#include <string>
#include <set>

#include "rinalite/rinalite-common.h"
#include "CDAP.pb.h"

struct CDAPAuthValue {
    std::string name;
    std::string password;
    std::string other;

    bool empty() const { return name == std::string() &&
                         password == std::string() &&
                         other == std::string(); }
};

class CDAPConn {
    std::set<int> pending_invoke_ids;
    int invoke_id_next;
    int max_pending_ops;
    std::set<int> pending_invoke_ids_remote;

    enum {
        NONE = 1,
        AWAITCON,
        CONNECTED,
        AWAITCLOSE,
    } state;

    int __put_invoke_id(std::set<int> &pending, int invoke_id);
    int get_invoke_id();
    int put_invoke_id(int invoke_id);
    int get_invoke_id_remote(int invoke_id);
    int put_invoke_id_remote(int invoke_id);

    int conn_fsm_run(struct CDAPMessage *m, bool sender);

public:
    CDAPConn(int fd, long version);

    /* @invoke_id is not meaningful for request messages. */
    int msg_send(struct CDAPMessage *m, int invoke_id);
    int msg_ser(struct CDAPMessage *m, int invoke_id,
                char **buf, size_t *len);

    struct CDAPMessage * msg_recv();
    struct CDAPMessage * msg_deser(char *serbuf, size_t serlen);

    struct rina_name local_appl;
    struct rina_name remote_appl;
    int fd;
    long version;
};

/* Internal representation of a CDAP message. */
struct CDAPMessage {
    int                 abs_syntax;
    gpb::authTypes_t    auth_mech;
    CDAPAuthValue       auth_value;
    struct rina_name    src_appl;
    struct rina_name    dst_appl;
    std::string         filter;
    gpb::flagValues_t   flags;
    int                 invoke_id;
    std::string         obj_class;
    long                obj_inst;
    std::string         obj_name;
    gpb::opCode_t       op_code;
    int                 result;
    std::string         result_reason;
    int                 scope;
    long                version;

    enum obj_value_t {
        NONE,
        I32,
        I64,
        BYTES,
        FLOAT,
        DOUBLE,
        BOOL,
        STRING,
    };

    bool is(obj_value_t tt) const { return obj_value.ty == tt; }
    bool is_request() const { return !is_response(); }
    bool is_response() const { return op_code & 0x1; }

    void print() const;

    CDAPMessage();
    ~CDAPMessage();

    CDAPMessage(const gpb::CDAPMessage& gm);
    operator gpb::CDAPMessage() const;

    bool valid(bool check_invoke_id) const;

    void get_obj_value(int32_t& v)
    {
        v = 0;
        if (obj_value.ty == I32) {
            v = obj_value.u.i32;
        }
    }

    void set_obj_value(int32_t v)
    {
        obj_value.ty = I32;
        obj_value.u.i32 = v;
    }

    void get_obj_value(int64_t& v)
    {
        v = 0;
        if (obj_value.ty == I64) {
            v = obj_value.u.i64;
        }
    }

    void set_obj_value(int64_t v)
    {
        obj_value.ty = I64;
        obj_value.u.i64 = v;
    }

    void get_obj_value(float& v)
    {
        v = 0.0;
        if (obj_value.ty == FLOAT) {
            v = obj_value.u.fp_single;
        }
    }

    void set_obj_value(float v)
    {
        obj_value.ty = FLOAT;
        obj_value.u.fp_single = v;
    }

    void get_obj_value(double& v)
    {
        v = 0.0;
        if (obj_value.ty == DOUBLE) {
            v = obj_value.u.fp_double;
        }
    }

    void set_obj_value(double v)
    {
        obj_value.ty = DOUBLE;
        obj_value.u.fp_double = v;
    }

    void get_obj_value(bool& v)
    {
        v = false;
        if (obj_value.ty == BOOL) {
            v = obj_value.u.boolean;
        }
    }

    void set_obj_value(bool v)
    {
        obj_value.ty = BOOL;
        obj_value.u.boolean = v;
    }

    void get_obj_value(std::string& v)
    {
        v = std::string();
        if (obj_value.ty == STRING) {
            v = obj_value.str;
        }
    }

    void set_obj_value(const std::string& v)
    {
        obj_value.ty = STRING;
        obj_value.str = v;
    }

    void set_obj_value(const char *v)
    {
        obj_value.ty = STRING;
        obj_value.str = std::string(v);
    }

    void get_obj_value(const char *& p, size_t& l)
    {
        p = NULL;
        l = 0;
        if (obj_value.ty == BYTES) {
            p = obj_value.u.buf.ptr;
            l = obj_value.u.buf.len;
        }
    }

    void set_obj_value(const char *buf, size_t len)
    {
        obj_value.ty = BYTES;
        obj_value.u.buf.ptr = const_cast<char *>(buf);
        obj_value.u.buf.len = len;
        obj_value.u.buf.owned = false;
    }

    int m_connect(gpb::authTypes_t auth_mech,
                  const struct CDAPAuthValue *auth_value,
                  const struct rina_name *local_appl,
                  const struct rina_name *remote_appl);

    int m_connect_r(const struct CDAPMessage *req, int result,
                    const std::string& result_reason);

    int m_release(gpb::flagValues_t flags);

    int m_release_r(const struct CDAPMessage *req,
                    gpb::flagValues_t flags, int result,
                    const std::string& result_reason);

    int m_create(gpb::flagValues_t flags,
                 const std::string& obj_class,
                 const std::string& obj_name, long obj_inst,
                 int scope, const std::string& filter);

    int m_create_r(const struct CDAPMessage *req,
                   gpb::flagValues_t flags, const std::string& obj_class,
                   const std::string& obj_name, long obj_inst,
                   int result, const std::string& result_reason);

    int m_delete(gpb::flagValues_t flags,
                 const std::string& obj_class,
                 const std::string& obj_name, long obj_inst,
                 int scope, const std::string& filter);

    int m_delete_r(const struct CDAPMessage *req,
                   gpb::flagValues_t flags, const std::string& obj_class,
                   const std::string& obj_name, long obj_inst,
                   int result, const std::string& result_reason);

    int m_read(gpb::flagValues_t flags,
               const std::string& obj_class,
               const std::string& obj_name, long obj_inst,
               int scope, const std::string& filter);

    int m_read_r(const struct CDAPMessage *req,
                 gpb::flagValues_t flags, const std::string& obj_class,
                 const std::string& obj_name, long obj_inst,
                 int result, const std::string& result_reason);

    int m_write(gpb::flagValues_t flags,
                const std::string& obj_class,
                const std::string& obj_name, long obj_inst,
                int scope, const std::string& filter);

    int m_write_r(const struct CDAPMessage *req,
                  gpb::flagValues_t flags, int result,
                  const std::string& result_reason);

    int m_cancelread(gpb::flagValues_t flags);

    int m_cancelread_r(const struct CDAPMessage *req,
                       gpb::flagValues_t flags, int result,
                       const std::string& result_reason);

    int m_start(gpb::flagValues_t flags,
               const std::string& obj_class,
               const std::string& obj_name, long obj_inst,
               int scope, const std::string& filter);

    int m_start_r(const struct CDAPMessage *req,
                  gpb::flagValues_t flags, int result,
                  const std::string& result_reason);

    int m_stop(gpb::flagValues_t flags,
               const std::string& obj_class,
               const std::string& obj_name, long obj_inst,
               int scope, const std::string& filter);

    int m_stop_r(const struct CDAPMessage *req,
                 gpb::flagValues_t flags, int result,
                 const std::string& result_reason);

private:
    int m_common(gpb::flagValues_t flags,
                 const std::string& obj_class,
                 const std::string& obj_name, long obj_inst,
                 int scope, const std::string& filter,
                 gpb::opCode_t op_code);

    int m_common_r(const struct CDAPMessage *req,
                   gpb::flagValues_t flags,
                   const std::string& obj_class,
                   const std::string& obj_name, long obj_inst,
                   int result, const std::string& result_reason,
                   gpb::opCode_t op_code);

    int __m_write(gpb::flagValues_t flags,
                  const std::string& obj_class,
                  const std::string& obj_name, long obj_inst,
                  int scope, const std::string& filter);

    /* Representation of the object value. */
    struct {
        obj_value_t         ty;
        union {
            int32_t         i32; /* intval and sintval */
            int64_t         i64; /* int64val and sint64val */
            float           fp_single;
            double          fp_double;
            bool            boolean;
            struct {
                char *ptr;
                size_t len;
                bool owned;
            } buf; /* byteval */
        } u;
        std::string              str; /* strval */
    }                   obj_value;
};

#endif /* __RINALITE_CDAP_H__ */
<commit_msg>cdap: get_obj_value() are const<commit_after>#ifndef __RINALITE_CDAP_H__
#define __RINALITE_CDAP_H__

#include <string>
#include <set>

#include "rinalite/rinalite-common.h"
#include "CDAP.pb.h"

struct CDAPAuthValue {
    std::string name;
    std::string password;
    std::string other;

    bool empty() const { return name == std::string() &&
                         password == std::string() &&
                         other == std::string(); }
};

class CDAPConn {
    std::set<int> pending_invoke_ids;
    int invoke_id_next;
    int max_pending_ops;
    std::set<int> pending_invoke_ids_remote;

    enum {
        NONE = 1,
        AWAITCON,
        CONNECTED,
        AWAITCLOSE,
    } state;

    int __put_invoke_id(std::set<int> &pending, int invoke_id);
    int get_invoke_id();
    int put_invoke_id(int invoke_id);
    int get_invoke_id_remote(int invoke_id);
    int put_invoke_id_remote(int invoke_id);

    int conn_fsm_run(struct CDAPMessage *m, bool sender);

public:
    CDAPConn(int fd, long version);

    /* @invoke_id is not meaningful for request messages. */
    int msg_send(struct CDAPMessage *m, int invoke_id);
    int msg_ser(struct CDAPMessage *m, int invoke_id,
                char **buf, size_t *len);

    struct CDAPMessage * msg_recv();
    struct CDAPMessage * msg_deser(char *serbuf, size_t serlen);

    struct rina_name local_appl;
    struct rina_name remote_appl;
    int fd;
    long version;
};

/* Internal representation of a CDAP message. */
struct CDAPMessage {
    int                 abs_syntax;
    gpb::authTypes_t    auth_mech;
    CDAPAuthValue       auth_value;
    struct rina_name    src_appl;
    struct rina_name    dst_appl;
    std::string         filter;
    gpb::flagValues_t   flags;
    int                 invoke_id;
    std::string         obj_class;
    long                obj_inst;
    std::string         obj_name;
    gpb::opCode_t       op_code;
    int                 result;
    std::string         result_reason;
    int                 scope;
    long                version;

    enum obj_value_t {
        NONE,
        I32,
        I64,
        BYTES,
        FLOAT,
        DOUBLE,
        BOOL,
        STRING,
    };

    bool is(obj_value_t tt) const { return obj_value.ty == tt; }
    bool is_request() const { return !is_response(); }
    bool is_response() const { return op_code & 0x1; }

    void print() const;

    CDAPMessage();
    ~CDAPMessage();

    CDAPMessage(const gpb::CDAPMessage& gm);
    operator gpb::CDAPMessage() const;

    bool valid(bool check_invoke_id) const;

    void get_obj_value(int32_t& v) const
    {
        v = 0;
        if (obj_value.ty == I32) {
            v = obj_value.u.i32;
        }
    }

    void set_obj_value(int32_t v)
    {
        obj_value.ty = I32;
        obj_value.u.i32 = v;
    }

    void get_obj_value(int64_t& v) const
    {
        v = 0;
        if (obj_value.ty == I64) {
            v = obj_value.u.i64;
        }
    }

    void set_obj_value(int64_t v)
    {
        obj_value.ty = I64;
        obj_value.u.i64 = v;
    }

    void get_obj_value(float& v) const
    {
        v = 0.0;
        if (obj_value.ty == FLOAT) {
            v = obj_value.u.fp_single;
        }
    }

    void set_obj_value(float v)
    {
        obj_value.ty = FLOAT;
        obj_value.u.fp_single = v;
    }

    void get_obj_value(double& v) const
    {
        v = 0.0;
        if (obj_value.ty == DOUBLE) {
            v = obj_value.u.fp_double;
        }
    }

    void set_obj_value(double v)
    {
        obj_value.ty = DOUBLE;
        obj_value.u.fp_double = v;
    }

    void get_obj_value(bool& v) const
    {
        v = false;
        if (obj_value.ty == BOOL) {
            v = obj_value.u.boolean;
        }
    }

    void set_obj_value(bool v)
    {
        obj_value.ty = BOOL;
        obj_value.u.boolean = v;
    }

    void get_obj_value(std::string& v) const
    {
        v = std::string();
        if (obj_value.ty == STRING) {
            v = obj_value.str;
        }
    }

    void set_obj_value(const std::string& v)
    {
        obj_value.ty = STRING;
        obj_value.str = v;
    }

    void set_obj_value(const char *v)
    {
        obj_value.ty = STRING;
        obj_value.str = std::string(v);
    }

    void get_obj_value(const char *& p, size_t& l) const
    {
        p = NULL;
        l = 0;
        if (obj_value.ty == BYTES) {
            p = obj_value.u.buf.ptr;
            l = obj_value.u.buf.len;
        }
    }

    void set_obj_value(const char *buf, size_t len)
    {
        obj_value.ty = BYTES;
        obj_value.u.buf.ptr = const_cast<char *>(buf);
        obj_value.u.buf.len = len;
        obj_value.u.buf.owned = false;
    }

    int m_connect(gpb::authTypes_t auth_mech,
                  const struct CDAPAuthValue *auth_value,
                  const struct rina_name *local_appl,
                  const struct rina_name *remote_appl);

    int m_connect_r(const struct CDAPMessage *req, int result,
                    const std::string& result_reason);

    int m_release(gpb::flagValues_t flags);

    int m_release_r(const struct CDAPMessage *req,
                    gpb::flagValues_t flags, int result,
                    const std::string& result_reason);

    int m_create(gpb::flagValues_t flags,
                 const std::string& obj_class,
                 const std::string& obj_name, long obj_inst,
                 int scope, const std::string& filter);

    int m_create_r(const struct CDAPMessage *req,
                   gpb::flagValues_t flags, const std::string& obj_class,
                   const std::string& obj_name, long obj_inst,
                   int result, const std::string& result_reason);

    int m_delete(gpb::flagValues_t flags,
                 const std::string& obj_class,
                 const std::string& obj_name, long obj_inst,
                 int scope, const std::string& filter);

    int m_delete_r(const struct CDAPMessage *req,
                   gpb::flagValues_t flags, const std::string& obj_class,
                   const std::string& obj_name, long obj_inst,
                   int result, const std::string& result_reason);

    int m_read(gpb::flagValues_t flags,
               const std::string& obj_class,
               const std::string& obj_name, long obj_inst,
               int scope, const std::string& filter);

    int m_read_r(const struct CDAPMessage *req,
                 gpb::flagValues_t flags, const std::string& obj_class,
                 const std::string& obj_name, long obj_inst,
                 int result, const std::string& result_reason);

    int m_write(gpb::flagValues_t flags,
                const std::string& obj_class,
                const std::string& obj_name, long obj_inst,
                int scope, const std::string& filter);

    int m_write_r(const struct CDAPMessage *req,
                  gpb::flagValues_t flags, int result,
                  const std::string& result_reason);

    int m_cancelread(gpb::flagValues_t flags);

    int m_cancelread_r(const struct CDAPMessage *req,
                       gpb::flagValues_t flags, int result,
                       const std::string& result_reason);

    int m_start(gpb::flagValues_t flags,
               const std::string& obj_class,
               const std::string& obj_name, long obj_inst,
               int scope, const std::string& filter);

    int m_start_r(const struct CDAPMessage *req,
                  gpb::flagValues_t flags, int result,
                  const std::string& result_reason);

    int m_stop(gpb::flagValues_t flags,
               const std::string& obj_class,
               const std::string& obj_name, long obj_inst,
               int scope, const std::string& filter);

    int m_stop_r(const struct CDAPMessage *req,
                 gpb::flagValues_t flags, int result,
                 const std::string& result_reason);

private:
    int m_common(gpb::flagValues_t flags,
                 const std::string& obj_class,
                 const std::string& obj_name, long obj_inst,
                 int scope, const std::string& filter,
                 gpb::opCode_t op_code);

    int m_common_r(const struct CDAPMessage *req,
                   gpb::flagValues_t flags,
                   const std::string& obj_class,
                   const std::string& obj_name, long obj_inst,
                   int result, const std::string& result_reason,
                   gpb::opCode_t op_code);

    int __m_write(gpb::flagValues_t flags,
                  const std::string& obj_class,
                  const std::string& obj_name, long obj_inst,
                  int scope, const std::string& filter);

    /* Representation of the object value. */
    struct {
        obj_value_t         ty;
        union {
            int32_t         i32; /* intval and sintval */
            int64_t         i64; /* int64val and sint64val */
            float           fp_single;
            double          fp_double;
            bool            boolean;
            struct {
                char *ptr;
                size_t len;
                bool owned;
            } buf; /* byteval */
        } u;
        std::string              str; /* strval */
    }                   obj_value;
};

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