<commit_before>
#define TRACE_SYMPLECTIC_PARTITIONED_RUNGE_KUTTA_INTEGRATOR

#include "integrators/symplectic_partitioned_runge_kutta_integrator.hpp"

#include <algorithm>
#include <vector>
#include <string>

#include "geometry/sign.hpp"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/dimensionless.hpp"
#include "testing_utilities/numerics.hpp"
#include "testing_utilities/statistics.hpp"

using principia::testing_utilities::AbsoluteError;
using testing::AllOf;
using testing::Gt;
using testing::Lt;
using principia::testing_utilities::Slope;
using principia::testing_utilities::PearsonProductMomentCorrelationCoefficient;

namespace principia {
namespace integrators {

namespace {

using quantities::Dimensionless;

inline void compute_harmonic_oscillator_force(double const t,
                                              std::vector<double> const& q,
                                              std::vector<double>* result) {
  (*result)[0] = -q[0];
}

inline void compute_harmonic_oscillator_velocity(std::vector<double> const& p,
                                                  std::vector<double>* result) {
  (*result)[0] = p[0];
}

}  // namespace

class SPRKTest : public testing::Test {
 public:
  static void SetUpTestCase() {
    google::LogToStderr();
  }

 protected:
  void SetUp() override {}

  SPRKIntegrator             integrator_;
  SPRKIntegrator::Parameters parameters_;
  SPRKIntegrator::Solution   solution_;
};

TEST_F(SPRKTest, HarmonicOscillator) {
  parameters_.q0 = {1.0};
  parameters_.p0 = {0.0};
  parameters_.t0 = 0.0;
#ifdef _DEBUG
  parameters_.tmax = 100.0;
#else
  parameters_.tmax = 1000.0;
#endif
  parameters_.Δt = 1.0E-4;
  parameters_.coefficients = integrator_.Order5Optimal();
  parameters_.sampling_period = 1;
  integrator_.Solve(&compute_harmonic_oscillator_force,
                    &compute_harmonic_oscillator_velocity,
                    parameters_, &solution_);
  double q_error = 0;
  double p_error = 0;
  for (size_t i = 0; i < solution_.time.quantities.size(); ++i) {
    q_error = std::max(q_error,
                       std::abs(solution_.position[0].quantities[i] -
                                std::cos(solution_.time.quantities[i])));
    p_error = std::max(p_error,
                       std::abs(solution_.momentum[0].quantities[i] +
                                std::sin(solution_.time.quantities[i])));
  }
  LOG(INFO) << "q_error = " << q_error;
  LOG(INFO) << "p_error = " << p_error;
  EXPECT_THAT(q_error, Lt(2E-16 * parameters_.tmax));
  EXPECT_THAT(p_error, Lt(2E-16 * parameters_.tmax));
}

TEST_F(SPRKTest, Convergence) {
  parameters_.q0 = {1.0};
  parameters_.p0 = {0.0};
  parameters_.t0 = 0.0;
  parameters_.tmax = 100;
  parameters_.coefficients = integrator_.Order5Optimal();
  parameters_.sampling_period = 0;
  // For 1.1⁻²¹ < |Δt| < 0.2 , the correlation between step size and error is
  // very strong. It the step is small enough to converge and large enough to
  // stay clear of floating point inaccuracy.
  parameters_.Δt = 0.2;
  int const step_sizes = 22;
  double const step_reduction = 1.1;
  std::vector<Dimensionless> log_step_sizes(step_sizes);
  std::vector<Dimensionless> log_q_errors(step_sizes);
  std::vector<Dimensionless> log_p_errors(step_sizes);
  for (int i = 0; i < step_sizes; ++i, parameters_.Δt /= step_reduction) {
    solution_ = SPRKIntegrator::Solution();
    integrator_.Solve(&compute_harmonic_oscillator_force,
                      &compute_harmonic_oscillator_velocity,
                      parameters_, &solution_);
    log_step_sizes[i] = std::log10(parameters_.Δt);
    log_q_errors[i] = std::log10(
        std::abs(solution_.position[0].quantities[0] -
                 std::cos(solution_.time.quantities[0])));
    log_p_errors[i] = std::log10(
        std::abs(solution_.momentum[0].quantities[0] +
                 std::sin(solution_.time.quantities[0])));
  }
  std::string mathematica_out = "ToExpression[StringReplace[\"\n{";
  for (int i = 0; i < step_sizes; ++i) {
    mathematica_out += "{";
    mathematica_out += ToString(log_step_sizes[i]);
    mathematica_out += ",";
    mathematica_out += ToString(log_q_errors[i]);
    mathematica_out += "}";
    if (i + 1 < step_sizes) {
      mathematica_out += ",\n";
    }
  }
  mathematica_out += "}\",\n{\"e\"->\"*^\", \"\\n\"->\"\", \" \"->\"\"}]];";
  google::LogToStderr();
  Dimensionless const q_convergence_order = Slope(log_step_sizes, log_q_errors);
  Dimensionless const q_correlation =
      PearsonProductMomentCorrelationCoefficient(log_step_sizes, log_q_errors);
  LOG(INFO) << "Convergence order in q : " << q_convergence_order;
  LOG(INFO) << "Correlation            : " << q_correlation;
  LOG(INFO) << "Convergence data for q :\n" << mathematica_out;
  EXPECT_THAT(q_convergence_order, AllOf(Gt(4.9), Lt(5.1)));
  EXPECT_THAT(q_correlation, AllOf(Gt(0.999), Lt(1.01)));
  mathematica_out = "ToExpression[StringReplace[\"\n{";
  for (int i = 0; i < step_sizes; ++i) {
    mathematica_out += "{";
    mathematica_out += ToString(log_step_sizes[i]);
    mathematica_out += ",";
    mathematica_out += ToString(log_p_errors[i]);
    mathematica_out += "}";
    if (i + 1 < step_sizes) {
      mathematica_out += ",\n ";
    }
  }
  mathematica_out += "}\",\n{\"e\"->\"*^\", \"\\n\"->\"\", \" \"->\"\"}]];";
  Dimensionless const p_convergence_order = Slope(log_step_sizes, log_p_errors);
  Dimensionless const p_correlation =
      PearsonProductMomentCorrelationCoefficient(log_step_sizes, log_p_errors);
  LOG(INFO) << "Convergence order in p : " << p_convergence_order;
  LOG(INFO) << "Correlation            : " << p_correlation;
  LOG(INFO) << "Convergence data for p :\n" << mathematica_out;
  EXPECT_THAT(p_convergence_order, AllOf(Gt(5.9), Lt(6.1)));
  EXPECT_THAT(p_correlation, AllOf(Gt(0.999), Lt(1.01)));
}

}  // namespace integrators
}  // namespace principia
<commit_msg>Fix comment, two lines in a row ending at 80 characters. :-)<commit_after>
#define TRACE_SYMPLECTIC_PARTITIONED_RUNGE_KUTTA_INTEGRATOR

#include "integrators/symplectic_partitioned_runge_kutta_integrator.hpp"

#include <algorithm>
#include <vector>
#include <string>

#include "geometry/sign.hpp"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/dimensionless.hpp"
#include "testing_utilities/numerics.hpp"
#include "testing_utilities/statistics.hpp"

using principia::testing_utilities::AbsoluteError;
using testing::AllOf;
using testing::Gt;
using testing::Lt;
using principia::testing_utilities::Slope;
using principia::testing_utilities::PearsonProductMomentCorrelationCoefficient;

namespace principia {
namespace integrators {

namespace {

using quantities::Dimensionless;

inline void compute_harmonic_oscillator_force(double const t,
                                              std::vector<double> const& q,
                                              std::vector<double>* result) {
  (*result)[0] = -q[0];
}

inline void compute_harmonic_oscillator_velocity(std::vector<double> const& p,
                                                  std::vector<double>* result) {
  (*result)[0] = p[0];
}

}  // namespace

class SPRKTest : public testing::Test {
 public:
  static void SetUpTestCase() {
    google::LogToStderr();
  }

 protected:
  void SetUp() override {}

  SPRKIntegrator             integrator_;
  SPRKIntegrator::Parameters parameters_;
  SPRKIntegrator::Solution   solution_;
};

TEST_F(SPRKTest, HarmonicOscillator) {
  parameters_.q0 = {1.0};
  parameters_.p0 = {0.0};
  parameters_.t0 = 0.0;
#ifdef _DEBUG
  parameters_.tmax = 100.0;
#else
  parameters_.tmax = 1000.0;
#endif
  parameters_.Δt = 1.0E-4;
  parameters_.coefficients = integrator_.Order5Optimal();
  parameters_.sampling_period = 1;
  integrator_.Solve(&compute_harmonic_oscillator_force,
                    &compute_harmonic_oscillator_velocity,
                    parameters_, &solution_);
  double q_error = 0;
  double p_error = 0;
  for (size_t i = 0; i < solution_.time.quantities.size(); ++i) {
    q_error = std::max(q_error,
                       std::abs(solution_.position[0].quantities[i] -
                                std::cos(solution_.time.quantities[i])));
    p_error = std::max(p_error,
                       std::abs(solution_.momentum[0].quantities[i] +
                                std::sin(solution_.time.quantities[i])));
  }
  LOG(INFO) << "q_error = " << q_error;
  LOG(INFO) << "p_error = " << p_error;
  EXPECT_THAT(q_error, Lt(2E-16 * parameters_.tmax));
  EXPECT_THAT(p_error, Lt(2E-16 * parameters_.tmax));
}

TEST_F(SPRKTest, Convergence) {
  parameters_.q0 = {1.0};
  parameters_.p0 = {0.0};
  parameters_.t0 = 0.0;
  parameters_.tmax = 100;
  parameters_.coefficients = integrator_.Order5Optimal();
  parameters_.sampling_period = 0;
  // For 0.2 * 1.1⁻²¹ < |Δt| < 0.2 , the correlation between step size and error
  // is very strong. It the step is small enough to converge and large enough to
  // stay clear of floating point inaccuracy.
  parameters_.Δt = 0.2;
  int const step_sizes = 22;
  double const step_reduction = 1.1;
  std::vector<Dimensionless> log_step_sizes(step_sizes);
  std::vector<Dimensionless> log_q_errors(step_sizes);
  std::vector<Dimensionless> log_p_errors(step_sizes);
  for (int i = 0; i < step_sizes; ++i, parameters_.Δt /= step_reduction) {
    solution_ = SPRKIntegrator::Solution();
    integrator_.Solve(&compute_harmonic_oscillator_force,
                      &compute_harmonic_oscillator_velocity,
                      parameters_, &solution_);
    log_step_sizes[i] = std::log10(parameters_.Δt);
    log_q_errors[i] = std::log10(
        std::abs(solution_.position[0].quantities[0] -
                 std::cos(solution_.time.quantities[0])));
    log_p_errors[i] = std::log10(
        std::abs(solution_.momentum[0].quantities[0] +
                 std::sin(solution_.time.quantities[0])));
  }
  std::string mathematica_out = "ToExpression[StringReplace[\"\n{";
  for (int i = 0; i < step_sizes; ++i) {
    mathematica_out += "{";
    mathematica_out += ToString(log_step_sizes[i]);
    mathematica_out += ",";
    mathematica_out += ToString(log_q_errors[i]);
    mathematica_out += "}";
    if (i + 1 < step_sizes) {
      mathematica_out += ",\n";
    }
  }
  mathematica_out += "}\",\n{\"e\"->\"*^\", \"\\n\"->\"\", \" \"->\"\"}]];";
  google::LogToStderr();
  Dimensionless const q_convergence_order = Slope(log_step_sizes, log_q_errors);
  Dimensionless const q_correlation =
      PearsonProductMomentCorrelationCoefficient(log_step_sizes, log_q_errors);
  LOG(INFO) << "Convergence order in q : " << q_convergence_order;
  LOG(INFO) << "Correlation            : " << q_correlation;
  LOG(INFO) << "Convergence data for q :\n" << mathematica_out;
  EXPECT_THAT(q_convergence_order, AllOf(Gt(4.9), Lt(5.1)));
  EXPECT_THAT(q_correlation, AllOf(Gt(0.999), Lt(1.01)));
  mathematica_out = "ToExpression[StringReplace[\"\n{";
  for (int i = 0; i < step_sizes; ++i) {
    mathematica_out += "{";
    mathematica_out += ToString(log_step_sizes[i]);
    mathematica_out += ",";
    mathematica_out += ToString(log_p_errors[i]);
    mathematica_out += "}";
    if (i + 1 < step_sizes) {
      mathematica_out += ",\n ";
    }
  }
  mathematica_out += "}\",\n{\"e\"->\"*^\", \"\\n\"->\"\", \" \"->\"\"}]];";
  Dimensionless const p_convergence_order = Slope(log_step_sizes, log_p_errors);
  Dimensionless const p_correlation =
      PearsonProductMomentCorrelationCoefficient(log_step_sizes, log_p_errors);
  LOG(INFO) << "Convergence order in p : " << p_convergence_order;
  LOG(INFO) << "Correlation            : " << p_correlation;
  LOG(INFO) << "Convergence data for p :\n" << mathematica_out;
  EXPECT_THAT(p_convergence_order, AllOf(Gt(5.9), Lt(6.1)));
  EXPECT_THAT(p_correlation, AllOf(Gt(0.999), Lt(1.01)));
}

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


<commit_before>
#include "integrators/symplectic_partitioned_runge_kutta_integrator.hpp"

#include <algorithm>
#include <vector>

#include "geometry/sign.hpp"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "testing_utilities/numerics.hpp"

using principia::testing_utilities::AbsoluteError;
using testing::Lt;

namespace principia {
namespace integrators {

namespace {

inline void compute_harmonic_oscillator_force(double const t,
                                              std::vector<double> const& q,
                                              std::vector<double>* result) {
  (*result)[0] = -q[0];
}

inline void compute_harmonice_oscillator_velocity(std::vector<double> const& p,
                                                  std::vector<double>* result) {
  (*result)[0] = p[0];
}

}  // namespace

class SPRKTest : public testing::Test {
 protected:
  void SetUp() override {
    integrator_.reset(new SPRKIntegrator);
    parameters_.reset(new SPRKIntegrator::Parameters);
    solution_.reset(new SPRKIntegrator::Solution);
  }

  std::unique_ptr<SPRKIntegrator> integrator_;
  std::unique_ptr<SPRKIntegrator::Parameters> parameters_;
  std::unique_ptr<SPRKIntegrator::Solution> solution_;
};

TEST_F(SPRKTest, HarmonicOscillator) {
  parameters_->q0 = {1.0};
  parameters_->p0 = {0.0};
  parameters_->t0 = 0.0;
#ifdef _DEBUG
  parameters_->tmax = 100.0;
#else
  parameters_->tmax = 1000.0;
#endif
  parameters_->Δt = 1.0E-4;
  parameters_->coefficients = integrator_->Order5Optimal();
  parameters_->sampling_period = 1;
  integrator_->Solve(&compute_harmonic_oscillator_force,
                         &compute_harmonice_oscillator_velocity,
                         *parameters_,
                         solution_.get());
  double q_error = 0;
  double p_error = 0;
  for (size_t i = 0; i < solution_->time.quantities.size(); ++i) {
    q_error = std::max(q_error,
                       std::abs(solution_->position[0].quantities[i] -
                                std::cos(solution_->time.quantities[i])));
    p_error = std::max(p_error,
                       std::abs(solution_->momentum[0].quantities[i] +
                                std::sin(solution_->time.quantities[i])));
  }
  LOG(ERROR) << "q_error = " << q_error;
  LOG(ERROR) << "p_error = " << p_error;
  EXPECT_THAT(AbsoluteError(0, q_error), Lt(2E-16 * parameters_->tmax));
  EXPECT_THAT(AbsoluteError(0, p_error), Lt(2E-16 * parameters_->tmax));
}

}  // namespace integrators
}  // namespace principia
<commit_msg>Empty line.<commit_after>
#include "integrators/symplectic_partitioned_runge_kutta_integrator.hpp"

#include <algorithm>
#include <vector>

#include "geometry/sign.hpp"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "testing_utilities/numerics.hpp"

using principia::testing_utilities::AbsoluteError;
using testing::Lt;

namespace principia {
namespace integrators {

namespace {

inline void compute_harmonic_oscillator_force(double const t,
                                              std::vector<double> const& q,
                                              std::vector<double>* result) {
  (*result)[0] = -q[0];
}

inline void compute_harmonice_oscillator_velocity(std::vector<double> const& p,
                                                  std::vector<double>* result) {
  (*result)[0] = p[0];
}

}  // namespace

class SPRKTest : public testing::Test {
 protected:
  void SetUp() override {
    integrator_.reset(new SPRKIntegrator);
    parameters_.reset(new SPRKIntegrator::Parameters);
    solution_.reset(new SPRKIntegrator::Solution);
  }

  std::unique_ptr<SPRKIntegrator> integrator_;
  std::unique_ptr<SPRKIntegrator::Parameters> parameters_;
  std::unique_ptr<SPRKIntegrator::Solution> solution_;
};

TEST_F(SPRKTest, HarmonicOscillator) {
  parameters_->q0 = {1.0};
  parameters_->p0 = {0.0};
  parameters_->t0 = 0.0;
#ifdef _DEBUG
  parameters_->tmax = 100.0;
#else
  parameters_->tmax = 1000.0;
#endif
  parameters_->Δt = 1.0E-4;
  parameters_->coefficients = integrator_->Order5Optimal();
  parameters_->sampling_period = 1;
  integrator_->Solve(&compute_harmonic_oscillator_force,
                         &compute_harmonice_oscillator_velocity,
                         *parameters_,
                         solution_.get());
  double q_error = 0;
  double p_error = 0;
  for (size_t i = 0; i < solution_->time.quantities.size(); ++i) {
    q_error = std::max(q_error,
                       std::abs(solution_->position[0].quantities[i] -
                                std::cos(solution_->time.quantities[i])));
    p_error = std::max(p_error,
                       std::abs(solution_->momentum[0].quantities[i] +
                                std::sin(solution_->time.quantities[i])));
  }
  LOG(ERROR) << "q_error = " << q_error;
  LOG(ERROR) << "p_error = " << p_error;
  EXPECT_THAT(AbsoluteError(0, q_error), Lt(2E-16 * parameters_->tmax));
  EXPECT_THAT(AbsoluteError(0, p_error), Lt(2E-16 * parameters_->tmax));
}

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


<commit_before>{##############################################################################}
{% macro generate_method(method, world_suffix) %}
{% filter conditional(method.conditional_string) %}
static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    {% if method.name in ['addEventListener', 'removeEventListener'] %}
    {{add_remove_event_listener_method(method.name) | indent}}
    {% else %}
    {% if method.number_of_required_arguments %}
    if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
        throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", ExceptionMessages::notEnoughArguments({{method.number_of_required_arguments}}, info.Length())), info.GetIsolate());
        return;
    }
    {% endif %}
    {% if not method.is_static %}
    {{cpp_class_name}}* imp = {{v8_class_name}}::toNative(info.Holder());
    {% endif %}
    {% if method.is_custom_element_callbacks %}
    CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
    {% endif %}
    {% if method.is_raises_exception %}
    ExceptionState exceptionState(info.Holder(), info.GetIsolate());
    {% endif %}
    {% if method.is_check_security_for_node %}
    if (!BindingSecurity::shouldAllowAccessToNode(imp->{{method.name}}(exceptionState), exceptionState)) {
        v8SetReturnValueNull(info);
        exceptionState.throwIfNeeded();
        return;
    }
    {% endif %}
    {% for argument in method.arguments %}
    {% if argument.is_optional and not argument.has_default and
          argument.idl_type != 'Dictionary' %}
    {# Optional arguments without a default value generate an early call with
       fewer arguments if they are omitted.
       Optional Dictionary arguments default to empty dictionary. #}
    if (UNLIKELY(info.Length() <= {{argument.index}})) {
        {{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value) | indent(8)}}
        return;
    }
    {% endif %}
    {% if method.is_strict_type_checking and argument.is_wrapper_type %}
    {# Type checking for wrapper interface types (if interface not implemented,
       throw TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
    if (info.Length() > {{argument.index}} && !isUndefinedOrNull(info[{{argument.index}}]) && !V8{{argument.idl_type}}::hasInstance(info[{{argument.index}}], info.GetIsolate(), worldType(info.GetIsolate()))) {
        throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", "parameter {{argument.index + 1}} is not of type '{{argument.idl_type}}'."), info.GetIsolate());
        return;
    }
    {% endif %}
    {% if argument.is_clamp %}
    {# NaN is treated as 0: http://www.w3.org/TR/WebIDL/#es-type-mapping #}
    {{argument.cpp_type}} {{argument.name}} = 0;
    V8TRYCATCH_VOID(double, {{argument.name}}NativeValue, info[{{argument.index}}]->NumberValue());
    if (!std::isnan({{argument.name}}NativeValue))
        {# IDL type is used for clamping, for the right bounds, since different
           IDL integer types have same internal C++ type (int or unsigned) #}
        {{argument.name}} = clampTo<{{argument.idl_type}}>({{argument.name}}NativeValue);
    {% elif argument.idl_type == 'SerializedScriptValue' %}
    bool {{argument.name}}DidThrow = false;
    {{argument.cpp_type}} {{argument.name}} = SerializedScriptValue::create(info[{{argument.index}}], 0, 0, {{argument.name}}DidThrow, info.GetIsolate());
    if ({{argument.name}}DidThrow)
        return;
    {% elif argument.is_variadic_wrapper_type %}
    Vector<{{argument.cpp_type}} > {{argument.name}};
    for (int i = {{argument.index}}; i < info.Length(); ++i) {
        if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate(), worldType(info.GetIsolate()))) {
            throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", "parameter {{argument.index + 1}} is not of type '{{argument.idl_type}}'."), info.GetIsolate());
            return;
        }
        {{argument.name}}.append(V8{{argument.idl_type}}::toNative(v8::Handle<v8::Object>::Cast(info[i])));
    }
    {% else %}
    {{argument.v8_value_to_local_cpp_value}};
    {% endif %}
    {% if argument.enum_validation_expression %}
    {# Methods throw on invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
    String string = {{argument.name}};
    if (!({{argument.enum_validation_expression}})) {
        throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", "parameter {{argument.index + 1}} ('" + string + "') is not a valid enum value."), info.GetIsolate());
        return;
    }
    {% endif %}
    {% if argument.idl_type in ['Dictionary', 'Promise'] %}
    if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
        throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", "parameter {{argument.index + 1}} ('{{argument.name}}') is not an object."), info.GetIsolate());
        return;
    }
    {% endif %}
    {% endfor %}{# arguments #}
    {{cpp_method_call(method, method.v8_set_return_value, method.cpp_value) | indent}}
    {% endif %}{# addEventListener, removeEventListener #}
}
{% endfilter %}
{% endmacro %}

{######################################}
{% macro add_remove_event_listener_method(method_name) %}
{# Set template values for addEventListener vs. removeEventListener #}
{% set listener_lookup_type, listener, hidden_dependency_action =
    ('ListenerFindOrCreate', 'listener', 'createHiddenDependency')
    if method_name == 'addEventListener' else
    ('ListenerFindOnly', 'listener.get()', 'removeHiddenDependency')
%}
EventTarget* impl = {{v8_class_name}}::toNative(info.Holder());
if (DOMWindow* window = impl->toDOMWindow()) {
    ExceptionState exceptionState(info.GetIsolate());
    if (!BindingSecurity::shouldAllowAccessToFrame(window->frame(), exceptionState)) {
        exceptionState.throwIfNeeded();
        return;
    }
    if (!window->document())
        return;
}
RefPtr<EventListener> listener = V8EventListenerList::getEventListener(info[1], false, {{listener_lookup_type}});
if (listener) {
    V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, eventName, info[0]);
    impl->{{method_name}}(eventName, {{listener}}, info[2]->BooleanValue());
    if (!impl->toNode())
        {{hidden_dependency_action}}(info.Holder(), info[1], {{v8_class_name}}::eventListenerCacheIndex, info.GetIsolate());
}
{% endmacro %}

{######################################}
{% macro cpp_method_call(method, v8_set_return_value, cpp_value) %}
{% if method.is_call_with_script_state %}
ScriptState* currentState = ScriptState::current();
if (!currentState)
    return;
ScriptState& state = *currentState;
{% endif %}
{% if method.is_call_with_execution_context %}
ExecutionContext* scriptContext = getExecutionContext();
{% endif %}
{% if method.is_call_with_script_arguments %}
RefPtr<ScriptArguments> scriptArguments(createScriptArguments(info, {{method.number_of_arguments}}));
{% endif %}
{% if method.idl_type == 'void' %}
{{cpp_value}};
{% elif method.is_call_with_script_state %}
{# FIXME: consider always using a local variable #}
{{method.cpp_type}} result = {{cpp_value}};
{% endif %}
{% if method.is_raises_exception %}
if (exceptionState.throwIfNeeded())
    return;
{% endif %}
{% if method.is_call_with_script_state %}
if (state.hadException()) {
    v8::Local<v8::Value> exception = state.exception();
    state.clearException();
    throwError(exception, info.GetIsolate());
    return;
}
{% endif %}
{% if v8_set_return_value %}{{v8_set_return_value}};{% endif %}{# None for void #}
{% endmacro %}

{##############################################################################}
{% macro overload_resolution_method(overloads, world_suffix) %}
static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    {% for method in overloads.methods %}
    if ({{method.overload_resolution_expression}}) {
        {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info);
        return;
    }
    {% endfor %}
    {% if overloads.minimum_number_of_required_arguments %}
    if (UNLIKELY(info.Length() < {{overloads.minimum_number_of_required_arguments}})) {
        throwTypeError(ExceptionMessages::failedToExecute("{{overloads.name}}", "{{interface_name}}", ExceptionMessages::notEnoughArguments({{overloads.minimum_number_of_required_arguments}}, info.Length())), info.GetIsolate());
        return;
    }
    {% endif %}
    throwUninformativeAndGenericTypeError(info.GetIsolate());
}
{% endmacro %}

{##############################################################################}
{% macro method_callback(method, world_suffix) %}
{% filter conditional(method.conditional_string) %}
static void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMMethod");
    {% if method.measure_as %}
    UseCounter::count(activeDOMWindow(), UseCounter::{{method.measure_as}});
    {% endif %}
    {% if method.deprecate_as %}
    UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{method.deprecate_as}});
    {% endif %}
    {% if world_suffix in method.activity_logging_world_list %}
    V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
    if (contextData && contextData->activityLogger()) {
        {# FIXME: replace toVectorOfArguments with toNativeArguments(info, 0)
           and delete toVectorOfArguments #}
        Vector<v8::Handle<v8::Value> > loggerArgs = toVectorOfArguments(info);
        contextData->activityLogger()->log("{{interface_name}}.{{method.name}}", info.Length(), loggerArgs.data(), "Method");
    }
    {% endif %}
    {% if method.is_custom %}
    {{v8_class_name}}::{{method.name}}MethodCustom(info);
    {% else %}
    {{cpp_class_name}}V8Internal::{{method.name}}Method{{world_suffix}}(info);
    {% endif %}
    TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
}
{% endfilter %}
{% endmacro %}
<commit_msg>Sync Python IDL compiler to r162010<commit_after>{##############################################################################}
{% macro generate_method(method, world_suffix) %}
{% filter conditional(method.conditional_string) %}
static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    {% if method.name in ['addEventListener', 'removeEventListener'] %}
    {{add_remove_event_listener_method(method.name) | indent}}
    {% else %}
    {% if method.number_of_required_arguments %}
    if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
        throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", ExceptionMessages::notEnoughArguments({{method.number_of_required_arguments}}, info.Length())), info.GetIsolate());
        return;
    }
    {% endif %}
    {% if not method.is_static %}
    {{cpp_class_name}}* imp = {{v8_class_name}}::toNative(info.Holder());
    {% endif %}
    {% if method.is_custom_element_callbacks %}
    CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
    {% endif %}
    {% if method.is_raises_exception %}
    ExceptionState exceptionState(info.Holder(), info.GetIsolate());
    {% endif %}
    {% if method.is_check_security_for_node %}
    if (!BindingSecurity::shouldAllowAccessToNode(imp->{{method.name}}(exceptionState), exceptionState)) {
        v8SetReturnValueNull(info);
        exceptionState.throwIfNeeded();
        return;
    }
    {% endif %}
    {% for argument in method.arguments %}
    {% if argument.is_optional and not argument.has_default and
          argument.idl_type != 'Dictionary' %}
    {# Optional arguments without a default value generate an early call with
       fewer arguments if they are omitted.
       Optional Dictionary arguments default to empty dictionary. #}
    if (UNLIKELY(info.Length() <= {{argument.index}})) {
        {{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value) | indent(8)}}
        return;
    }
    {% endif %}
    {% if method.is_strict_type_checking and argument.is_wrapper_type %}
    {# Type checking for wrapper interface types (if interface not implemented,
       throw TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
    if (info.Length() > {{argument.index}} && !isUndefinedOrNull(info[{{argument.index}}]) && !V8{{argument.idl_type}}::hasInstance(info[{{argument.index}}], info.GetIsolate(), worldType(info.GetIsolate()))) {
        throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", "parameter {{argument.index + 1}} is not of type '{{argument.idl_type}}'."), info.GetIsolate());
        return;
    }
    {% endif %}
    {% if argument.is_clamp %}
    {# NaN is treated as 0: http://www.w3.org/TR/WebIDL/#es-type-mapping #}
    {{argument.cpp_type}} {{argument.name}} = 0;
    V8TRYCATCH_VOID(double, {{argument.name}}NativeValue, info[{{argument.index}}]->NumberValue());
    if (!std::isnan({{argument.name}}NativeValue))
        {# IDL type is used for clamping, for the right bounds, since different
           IDL integer types have same internal C++ type (int or unsigned) #}
        {{argument.name}} = clampTo<{{argument.idl_type}}>({{argument.name}}NativeValue);
    {% elif argument.idl_type == 'SerializedScriptValue' %}
    bool {{argument.name}}DidThrow = false;
    {{argument.cpp_type}} {{argument.name}} = SerializedScriptValue::create(info[{{argument.index}}], 0, 0, {{argument.name}}DidThrow, info.GetIsolate());
    if ({{argument.name}}DidThrow)
        return;
    {% elif argument.is_variadic_wrapper_type %}
    Vector<{{argument.cpp_type}} > {{argument.name}};
    for (int i = {{argument.index}}; i < info.Length(); ++i) {
        if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate(), worldType(info.GetIsolate()))) {
            throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", "parameter {{argument.index + 1}} is not of type '{{argument.idl_type}}'."), info.GetIsolate());
            return;
        }
        {{argument.name}}.append(V8{{argument.idl_type}}::toNative(v8::Handle<v8::Object>::Cast(info[i])));
    }
    {% else %}
    {{argument.v8_value_to_local_cpp_value}};
    {% endif %}
    {% if argument.enum_validation_expression %}
    {# Methods throw on invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
    String string = {{argument.name}};
    if (!({{argument.enum_validation_expression}})) {
        throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", "parameter {{argument.index + 1}} ('" + string + "') is not a valid enum value."), info.GetIsolate());
        return;
    }
    {% endif %}
    {% if argument.idl_type in ['Dictionary', 'Promise'] %}
    if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
        throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", "parameter {{argument.index + 1}} ('{{argument.name}}') is not an object."), info.GetIsolate());
        return;
    }
    {% endif %}
    {% endfor %}{# arguments #}
    {{cpp_method_call(method, method.v8_set_return_value, method.cpp_value) | indent}}
    {% endif %}{# addEventListener, removeEventListener #}
}
{% endfilter %}
{% endmacro %}

{######################################}
{% macro add_remove_event_listener_method(method_name) %}
{# Set template values for addEventListener vs. removeEventListener #}
{% set listener_lookup_type, listener, hidden_dependency_action =
    ('ListenerFindOrCreate', 'listener', 'createHiddenDependency')
    if method_name == 'addEventListener' else
    ('ListenerFindOnly', 'listener.get()', 'removeHiddenDependency')
%}
EventTarget* impl = {{v8_class_name}}::toNative(info.Holder());
if (DOMWindow* window = impl->toDOMWindow()) {
    ExceptionState exceptionState(info.Holder(), info.GetIsolate());
    if (!BindingSecurity::shouldAllowAccessToFrame(window->frame(), exceptionState)) {
        exceptionState.throwIfNeeded();
        return;
    }
    if (!window->document())
        return;
}
RefPtr<EventListener> listener = V8EventListenerList::getEventListener(info[1], false, {{listener_lookup_type}});
if (listener) {
    V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, eventName, info[0]);
    impl->{{method_name}}(eventName, {{listener}}, info[2]->BooleanValue());
    if (!impl->toNode())
        {{hidden_dependency_action}}(info.Holder(), info[1], {{v8_class_name}}::eventListenerCacheIndex, info.GetIsolate());
}
{% endmacro %}

{######################################}
{% macro cpp_method_call(method, v8_set_return_value, cpp_value) %}
{% if method.is_call_with_script_state %}
ScriptState* currentState = ScriptState::current();
if (!currentState)
    return;
ScriptState& state = *currentState;
{% endif %}
{% if method.is_call_with_execution_context %}
ExecutionContext* scriptContext = getExecutionContext();
{% endif %}
{% if method.is_call_with_script_arguments %}
RefPtr<ScriptArguments> scriptArguments(createScriptArguments(info, {{method.number_of_arguments}}));
{% endif %}
{% if method.idl_type == 'void' %}
{{cpp_value}};
{% elif method.is_call_with_script_state %}
{# FIXME: consider always using a local variable #}
{{method.cpp_type}} result = {{cpp_value}};
{% endif %}
{% if method.is_raises_exception %}
if (exceptionState.throwIfNeeded())
    return;
{% endif %}
{% if method.is_call_with_script_state %}
if (state.hadException()) {
    v8::Local<v8::Value> exception = state.exception();
    state.clearException();
    throwError(exception, info.GetIsolate());
    return;
}
{% endif %}
{% if v8_set_return_value %}{{v8_set_return_value}};{% endif %}{# None for void #}
{% endmacro %}

{##############################################################################}
{% macro overload_resolution_method(overloads, world_suffix) %}
static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    {% for method in overloads.methods %}
    if ({{method.overload_resolution_expression}}) {
        {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info);
        return;
    }
    {% endfor %}
    {% if overloads.minimum_number_of_required_arguments %}
    if (UNLIKELY(info.Length() < {{overloads.minimum_number_of_required_arguments}})) {
        throwTypeError(ExceptionMessages::failedToExecute("{{overloads.name}}", "{{interface_name}}", ExceptionMessages::notEnoughArguments({{overloads.minimum_number_of_required_arguments}}, info.Length())), info.GetIsolate());
        return;
    }
    {% endif %}
    throwUninformativeAndGenericTypeError(info.GetIsolate());
}
{% endmacro %}

{##############################################################################}
{% macro method_callback(method, world_suffix) %}
{% filter conditional(method.conditional_string) %}
static void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMMethod");
    {% if method.measure_as %}
    UseCounter::count(activeDOMWindow(), UseCounter::{{method.measure_as}});
    {% endif %}
    {% if method.deprecate_as %}
    UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{method.deprecate_as}});
    {% endif %}
    {% if world_suffix in method.activity_logging_world_list %}
    V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
    if (contextData && contextData->activityLogger()) {
        {# FIXME: replace toVectorOfArguments with toNativeArguments(info, 0)
           and delete toVectorOfArguments #}
        Vector<v8::Handle<v8::Value> > loggerArgs = toVectorOfArguments(info);
        contextData->activityLogger()->log("{{interface_name}}.{{method.name}}", info.Length(), loggerArgs.data(), "Method");
    }
    {% endif %}
    {% if method.is_custom %}
    {{v8_class_name}}::{{method.name}}MethodCustom(info);
    {% else %}
    {{cpp_class_name}}V8Internal::{{method.name}}Method{{world_suffix}}(info);
    {% endif %}
    TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
}
{% endfilter %}
{% endmacro %}
<|endoftext|>


<commit_before>#ifndef BINDING_UTILS_HPP
#define BINDING_UTILS_HPP

#include <stddef.h>
#include <iostream>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include "random.hpp"

/* \file binding_utils.hpp
   Some useful functions to handle ublas matrices and vectors.
   Source = boost bindings examples.
*/

namespace Siconos {
  namespace algebra {

///////////////////////////////
// vectors

// element access:
    template <typename V>
    struct vct_access_traits {
      typedef typename
      boost::numeric::bindings::value_type<V>::type val_t;
      typedef val_t& ref_t;
      static ref_t elem (V& v, size_t i) { return v[i]; }
    };

    template <typename V>
    struct vct_access_traits<V const> {
      typedef typename
      boost::numeric::bindings::value_type<V>::type val_t;
      typedef val_t ref_t;
      static ref_t elem (V const& v, size_t i) { return v[i]; }
    };

    template <typename V>
    inline
    typename vct_access_traits<V>::ref_t elem_v (V& v, size_t i) {
      return vct_access_traits<V>::elem (v, i);
    }

// initialization:
    struct ident {
      size_t operator() (size_t i) const { return i; }
    };
    struct iplus1 {
      size_t operator() (size_t i) const { return i + 1; }
    };
    template <typename T>
    struct const_val {
      T val;
      const_val (T v = T()) : val (v) {}
      T operator() (size_t) const { return val; }
      T operator() (size_t, size_t) const { return val; }
    };
    struct kpp {
      size_t val;
      kpp (size_t v = 0) : val (v) {}
      size_t operator() (size_t) {
        size_t tmp = val;
        ++val;
        return tmp;
      }
      size_t operator() (size_t, size_t) {
        size_t tmp = val;
        ++val;
        return tmp;
      }
    };
    template <typename T>
    struct times_plus {
      T s, a, b;
      times_plus (T ss, T aa = T(), T bb = T()) : s (ss), a (aa), b (bb) {}
      T operator() (size_t i) const {
        return s * (T) i + a;
      }
      T operator() (size_t i, size_t j) const {
        return s * ((T) i + a) + (T) j + b;
      }
    };

    template <typename F, typename V>
    void init_v (V& v, F f = F()) {
      size_t sz
        = boost::numeric::bindings::size( v );
      for (std::size_t i = 0; i < sz; ++i)
        elem_v (v, i) = f (i);
    }

// printing:
    template <typename V>
    void print_v (V const& v, char const* ch = 0) {
      if (ch)
        std::cout << ch << ": ";
      size_t sz
        = boost::numeric::bindings::size( v );
      for (std::size_t i = 0; i < sz; ++i)
        std::cout << elem_v (v, i) << " ";
      std::cout << std::endl;
    }

/////////////////////////////////////
// matrices

// element access:
    template <typename M>
    struct matr_access_traits {
      typedef M mat_t;
      typedef typename boost::numeric::bindings::value_type<mat_t>::type val_t;
      typedef typename mat_t::reference ref_t;
      static ref_t elem (mat_t& m, size_t i, size_t j) { return m (i, j); }
    };

#ifdef EIGEN_FORWARDDECLARATIONS_H
    template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
    struct matr_access_traits<Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {
      typedef Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> mat_t;
      typedef typename boost::numeric::bindings::value_type<mat_t>::type val_t;
      typedef val_t& ref_t;
      static ref_t elem (mat_t& m, size_t i, size_t j) { return m (i, j); }
    };
#endif

    template <typename M>
    struct matr_access_traits<M const> {
      typedef M const mat_t;
      typedef typename boost::numeric::bindings::value_type<mat_t>::type val_t;
      typedef val_t ref_t;
      static ref_t elem (mat_t& m, size_t i, size_t j) { return m (i, j); }
    };

    template <typename M>
    inline
    typename matr_access_traits<M>::ref_t elem_m (M& m, size_t i, size_t j) {
      return matr_access_traits<M>::elem (m, i, j);
    }

// initialization:
    struct rws {
      size_t operator() (size_t i, size_t) const { return i; }
    };
    struct rws1 {
      size_t operator() (size_t i, size_t) const { return i + 1; }
    };
    struct cls {
      size_t operator() (size_t, size_t j) const { return j; }
    };
    struct cls1 {
      size_t operator() (size_t, size_t j) const { return j + 1; }
    };

    template <typename F, typename M>
    void init_m (M& m, F f = F()) {
      size_t sz1
        = boost::numeric::bindings::size_row( m );
      size_t sz2
        = boost::numeric::bindings::size_column( m );
      for (std::size_t i = 0; i < sz1; ++i)
        for (std::size_t j = 0; j < sz2; ++j)
          elem_m (m, i, j) = f (i, j);
    }

    template <typename M>
    void init_symm (M& m, char uplo = 'f') {
      size_t n
        = boost::numeric::bindings::size_row( m );
      for (size_t i = 0; i < n; ++i) {
        elem_m (m, i, i) = n;
        for (size_t j = i + 1; j < n; ++j) {
          if (uplo == 'u' || uplo == 'U')
            elem_m (m, i, j) = n - (j - i);
          else if (uplo == 'l' || uplo == 'L')
            elem_m (m, j, i) = n - (j - i);
          else
            elem_m (m, i, j) = elem_m (m, j, i) = n - (j - i);
        }
      }
    }

/** Print a boost-ublas matrix
 */
    template <typename M>
    void print_m (M const& m, char const* ch = 0) {
      if (ch)
        std::cout << ch << ":\n";
      size_t sz1
        = boost::numeric::bindings::size_row( m );
      size_t sz2
        = boost::numeric::bindings::size_column( m );
      for (std::size_t i = 0 ; i < sz1 ; ++i) {
        for (std::size_t j = 0 ; j < sz2 ; ++j)
          std::cout << elem_m (m, i, j) << ", ";
        std::cout << std::endl;
      }
      //  std::cout << std::endl;
    }

    template <typename M>
    void print_m_data (M const& m, char const* ch = 0) {
      if (ch)
        std::cout << ch << " data:\n";
      using namespace boost::numeric::bindings;
      std::copy( begin_value( m ), end_value( m ), std::ostream_iterator
                 < typename value_type< const M >::type >( std::cout, " " ) );
      std::cout << std::endl;
    }

// Below are functions from boost bindings tests (see ublas_heev.hpp).

    inline float conj(float v) { return v; }
    inline double conj(double v) { return v; }
    inline float real(float v) { return v; }
    inline double real(double v) { return v; }

/** Fill a banded matrix with random values
 */
    template <typename M>
    void fill_banded(M& m) {
      typedef typename M::size_type  size_type ;
      typedef typename M::value_type value_type ;

      int size = m.size2() ;
      int band = m.upper() ;

      for (int i=0; i<size; ++i) {
        for (int j=std::max(0,i-band); j<i; ++j) m(j,i) = random_value<value_type>();
        m(i,i) = real( random_value<value_type>() );
      }
    } // randomize()

/** Fill a symmetric matrix with random values
 */
    template <typename M>
    void fill_sym(M& m) {
      typedef typename M::size_type  size_type ;
      typedef typename M::value_type value_type ;

      int size = m.size2() ;

      for (int i=0; i<size; ++i) {
        for (int j=0; j<i; ++j) {
          m(j,i) = random_value<value_type>();
          m(i,j) = conj( m(j,i) ) ;
        }
        m(i,i) = real( random_value<value_type>() );
      }
    } // randomize()

/** Fill a  matrix with random values
 */
    template <typename M>
    void fill(M& m) {
      typedef typename M::size_type  size_type ;
      typedef typename M::value_type value_type ;

      for (int i=0; i<m.size1(); ++i) {
        for (int j=0; j<m.size2(); ++j) {
          m(i,j) = random_value<value_type>();
        }
      }
    } // randomize()

  } // Algebra namespace
} // Siconos namespace
#endif
<commit_msg>silent a warning on wrong type comparison<commit_after>#ifndef BINDING_UTILS_HPP
#define BINDING_UTILS_HPP

#include <stddef.h>
#include <iostream>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include "random.hpp"

/* \file binding_utils.hpp
   Some useful functions to handle ublas matrices and vectors.
   Source = boost bindings examples.
*/

namespace Siconos {
  namespace algebra {

///////////////////////////////
// vectors

// element access:
    template <typename V>
    struct vct_access_traits {
      typedef typename
      boost::numeric::bindings::value_type<V>::type val_t;
      typedef val_t& ref_t;
      static ref_t elem (V& v, size_t i) { return v[i]; }
    };

    template <typename V>
    struct vct_access_traits<V const> {
      typedef typename
      boost::numeric::bindings::value_type<V>::type val_t;
      typedef val_t ref_t;
      static ref_t elem (V const& v, size_t i) { return v[i]; }
    };

    template <typename V>
    inline
    typename vct_access_traits<V>::ref_t elem_v (V& v, size_t i) {
      return vct_access_traits<V>::elem (v, i);
    }

// initialization:
    struct ident {
      size_t operator() (size_t i) const { return i; }
    };
    struct iplus1 {
      size_t operator() (size_t i) const { return i + 1; }
    };
    template <typename T>
    struct const_val {
      T val;
      const_val (T v = T()) : val (v) {}
      T operator() (size_t) const { return val; }
      T operator() (size_t, size_t) const { return val; }
    };
    struct kpp {
      size_t val;
      kpp (size_t v = 0) : val (v) {}
      size_t operator() (size_t) {
        size_t tmp = val;
        ++val;
        return tmp;
      }
      size_t operator() (size_t, size_t) {
        size_t tmp = val;
        ++val;
        return tmp;
      }
    };
    template <typename T>
    struct times_plus {
      T s, a, b;
      times_plus (T ss, T aa = T(), T bb = T()) : s (ss), a (aa), b (bb) {}
      T operator() (size_t i) const {
        return s * (T) i + a;
      }
      T operator() (size_t i, size_t j) const {
        return s * ((T) i + a) + (T) j + b;
      }
    };

    template <typename F, typename V>
    void init_v (V& v, F f = F()) {
      size_t sz
        = boost::numeric::bindings::size( v );
      for (std::size_t i = 0; i < sz; ++i)
        elem_v (v, i) = f (i);
    }

// printing:
    template <typename V>
    void print_v (V const& v, char const* ch = 0) {
      if (ch)
        std::cout << ch << ": ";
      size_t sz
        = boost::numeric::bindings::size( v );
      for (std::size_t i = 0; i < sz; ++i)
        std::cout << elem_v (v, i) << " ";
      std::cout << std::endl;
    }

/////////////////////////////////////
// matrices

// element access:
    template <typename M>
    struct matr_access_traits {
      typedef M mat_t;
      typedef typename boost::numeric::bindings::value_type<mat_t>::type val_t;
      typedef typename mat_t::reference ref_t;
      static ref_t elem (mat_t& m, size_t i, size_t j) { return m (i, j); }
    };

#ifdef EIGEN_FORWARDDECLARATIONS_H
    template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
    struct matr_access_traits<Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {
      typedef Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> mat_t;
      typedef typename boost::numeric::bindings::value_type<mat_t>::type val_t;
      typedef val_t& ref_t;
      static ref_t elem (mat_t& m, size_t i, size_t j) { return m (i, j); }
    };
#endif

    template <typename M>
    struct matr_access_traits<M const> {
      typedef M const mat_t;
      typedef typename boost::numeric::bindings::value_type<mat_t>::type val_t;
      typedef val_t ref_t;
      static ref_t elem (mat_t& m, size_t i, size_t j) { return m (i, j); }
    };

    template <typename M>
    inline
    typename matr_access_traits<M>::ref_t elem_m (M& m, size_t i, size_t j) {
      return matr_access_traits<M>::elem (m, i, j);
    }

// initialization:
    struct rws {
      size_t operator() (size_t i, size_t) const { return i; }
    };
    struct rws1 {
      size_t operator() (size_t i, size_t) const { return i + 1; }
    };
    struct cls {
      size_t operator() (size_t, size_t j) const { return j; }
    };
    struct cls1 {
      size_t operator() (size_t, size_t j) const { return j + 1; }
    };

    template <typename F, typename M>
    void init_m (M& m, F f = F()) {
      size_t sz1
        = boost::numeric::bindings::size_row( m );
      size_t sz2
        = boost::numeric::bindings::size_column( m );
      for (std::size_t i = 0; i < sz1; ++i)
        for (std::size_t j = 0; j < sz2; ++j)
          elem_m (m, i, j) = f (i, j);
    }

    template <typename M>
    void init_symm (M& m, char uplo = 'f') {
      size_t n
        = boost::numeric::bindings::size_row( m );
      for (size_t i = 0; i < n; ++i) {
        elem_m (m, i, i) = n;
        for (size_t j = i + 1; j < n; ++j) {
          if (uplo == 'u' || uplo == 'U')
            elem_m (m, i, j) = n - (j - i);
          else if (uplo == 'l' || uplo == 'L')
            elem_m (m, j, i) = n - (j - i);
          else
            elem_m (m, i, j) = elem_m (m, j, i) = n - (j - i);
        }
      }
    }

/** Print a boost-ublas matrix
 */
    template <typename M>
    void print_m (M const& m, char const* ch = 0) {
      if (ch)
        std::cout << ch << ":\n";
      size_t sz1
        = boost::numeric::bindings::size_row( m );
      size_t sz2
        = boost::numeric::bindings::size_column( m );
      for (std::size_t i = 0 ; i < sz1 ; ++i) {
        for (std::size_t j = 0 ; j < sz2 ; ++j)
          std::cout << elem_m (m, i, j) << ", ";
        std::cout << std::endl;
      }
      //  std::cout << std::endl;
    }

    template <typename M>
    void print_m_data (M const& m, char const* ch = 0) {
      if (ch)
        std::cout << ch << " data:\n";
      using namespace boost::numeric::bindings;
      std::copy( begin_value( m ), end_value( m ), std::ostream_iterator
                 < typename value_type< const M >::type >( std::cout, " " ) );
      std::cout << std::endl;
    }

// Below are functions from boost bindings tests (see ublas_heev.hpp).

    inline float conj(float v) { return v; }
    inline double conj(double v) { return v; }
    inline float real(float v) { return v; }
    inline double real(double v) { return v; }

/** Fill a banded matrix with random values
 */
    template <typename M>
    void fill_banded(M& m) {
      typedef typename M::size_type  size_type ;
      typedef typename M::value_type value_type ;

      int size = m.size2() ;
      int band = m.upper() ;

      for (int i=0; i<size; ++i) {
        for (int j=std::max(0,i-band); j<i; ++j) m(j,i) = random_value<value_type>();
        m(i,i) = real( random_value<value_type>() );
      }
    } // randomize()

/** Fill a symmetric matrix with random values
 */
    template <typename M>
    void fill_sym(M& m) {
      typedef typename M::size_type  size_type ;
      typedef typename M::value_type value_type ;

      int size = m.size2() ;

      for (int i=0; i<size; ++i) {
        for (int j=0; j<i; ++j) {
          m(j,i) = random_value<value_type>();
          m(i,j) = conj( m(j,i) ) ;
        }
        m(i,i) = real( random_value<value_type>() );
      }
    } // randomize()

/** Fill a  matrix with random values
 */
    template <typename M>
    void fill(M& m) {
      typedef typename M::size_type  size_type ;
      typedef typename M::value_type value_type ;

      for (size_type i=0; i<m.size1(); ++i) {
        for (size_type j=0; j<m.size2(); ++j) {
          m(i,j) = random_value<value_type>();
        }
      }
    } // randomize()

  } // Algebra namespace
} // Siconos namespace
#endif
<|endoftext|>


<commit_before>
/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#ifndef _Stroika_Foundation_Debug_Trace_inl_
#define _Stroika_Foundation_Debug_Trace_inl_ 1

#if qTraceToFile
#include <filesystem>
#endif

CompileTimeFlagChecker_HEADER (Stroika::Foundation::Debug, qTraceToFile, qTraceToFile);
CompileTimeFlagChecker_HEADER (Stroika::Foundation::Debug, qDefaultTracingOn, qDefaultTracingOn);

namespace Stroika::Foundation::Debug {

    /*
     ********************************************************************************
     ******************************* Trace::Emitter *********************************
     ********************************************************************************
     */
    template <typename CHARTYPE>
    inline void Emitter::EmitUnadornedText (const CHARTYPE* p)
    {
        DoEmit_ (p);
    }

    /*
     ********************************************************************************
     ******************************* TraceContextBumper *****************************
     ********************************************************************************
     */
    inline TraceContextBumper::TraceContextBumper () noexcept
#if qDefaultTracingOn
        : fDoEndMarker (false)
#endif
    {
#if qDefaultTracingOn
        IncCount_ ();
#endif
    }
#if !qDefaultTracingOn
    inline TraceContextBumper::TraceContextBumper ([[maybe_unused]] const wchar_t* contextName) noexcept
    {
    }
    inline TraceContextBumper::TraceContextBumper ([[maybe_unused]] const wchar_t* contextName, [[maybe_unused]] const wchar_t* extraFmt, ...) noexcept
    {
    }
    inline TraceContextBumper::TraceContextBumper ([[maybe_unused]] const char* contextName) noexcept
    {
    }
    inline TraceContextBumper::~TraceContextBumper ()
    {
    }
#endif

    namespace Private_ {
        struct TraceModuleData_ {
            TraceModuleData_ ();
            ~TraceModuleData_ ();

            Emitter fEmitter;
#if qTraceToFile
            filesystem::path fTraceFileName;
#endif
        };
    }

}

namespace {
    Stroika::Foundation::Execution::ModuleInitializer<Stroika::Foundation::Debug::Private_::TraceModuleData_> _Stroika_Foundation_Debug_Trace_ModuleData_; // this object constructed for the CTOR/DTOR per-module side-effects
}

inline Stroika::Foundation::Debug::Emitter& Stroika::Foundation::Debug::Emitter::Get () noexcept
{
    return Execution::ModuleInitializer<Private_::TraceModuleData_>::Actual ().fEmitter;
}
#endif /*_Stroika_Foundation_Debug_Trace_inl_*/
<commit_msg>cosmetic<commit_after>
/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#ifndef _Stroika_Foundation_Debug_Trace_inl_
#define _Stroika_Foundation_Debug_Trace_inl_ 1

#if qTraceToFile
#include <filesystem>
#endif

CompileTimeFlagChecker_HEADER (Stroika::Foundation::Debug, qTraceToFile, qTraceToFile);
CompileTimeFlagChecker_HEADER (Stroika::Foundation::Debug, qDefaultTracingOn, qDefaultTracingOn);

namespace Stroika::Foundation::Debug {

    /*
     ********************************************************************************
     ******************************* Trace::Emitter *********************************
     ********************************************************************************
     */
    template <typename CHARTYPE>
    inline void Emitter::EmitUnadornedText (const CHARTYPE* p)
    {
        DoEmit_ (p);
    }

    /*
     ********************************************************************************
     ******************************* TraceContextBumper *****************************
     ********************************************************************************
     */
    inline TraceContextBumper::TraceContextBumper () noexcept
#if qDefaultTracingOn
        : fDoEndMarker (false)
#endif
    {
#if qDefaultTracingOn
        IncCount_ ();
#endif
    }
#if !qDefaultTracingOn
    inline TraceContextBumper::TraceContextBumper ([[maybe_unused]] const wchar_t* contextName) noexcept
    {
    }
    inline TraceContextBumper::TraceContextBumper ([[maybe_unused]] const wchar_t* contextName, [[maybe_unused]] const wchar_t* extraFmt, ...) noexcept
    {
    }
    inline TraceContextBumper::TraceContextBumper ([[maybe_unused]] const char* contextName) noexcept
    {
    }
    inline TraceContextBumper::~TraceContextBumper ()
    {
    }
#endif

    namespace Private_ {
        struct TraceModuleData_ {
            TraceModuleData_ ();
            ~TraceModuleData_ ();

            Emitter fEmitter;
#if qTraceToFile
            filesystem::path fTraceFileName;
#endif
        };
    }

}

namespace {
    Stroika::Foundation::Execution::ModuleInitializer<Stroika::Foundation::Debug::Private_::TraceModuleData_> _Stroika_Foundation_Debug_Trace_ModuleData_; // this object constructed for the CTOR/DTOR per-module side-effects
}

inline Stroika::Foundation::Debug::Emitter& Stroika::Foundation::Debug::Emitter::Get () noexcept
{
    return Execution::ModuleInitializer<Private_::TraceModuleData_>::Actual ().fEmitter;
}
#endif /*_Stroika_Foundation_Debug_Trace_inl_*/
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

//#define _USE_MATH_DEFINES
#include <QmitkUSNewVideoDeviceWidget.h>

//QT headers

//mitk headers

//itk headers

const std::string QmitkUSNewVideoDeviceWidget::VIEW_ID = "org.mitk.views.QmitkUSNewVideoDeviceWidget";

QmitkUSNewVideoDeviceWidget::QmitkUSNewVideoDeviceWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f)
{
  m_Controls = NULL;
  CreateQtPartControl(this);
}

QmitkUSNewVideoDeviceWidget::~QmitkUSNewVideoDeviceWidget()
{
}

//////////////////// INITIALIZATION /////////////////////

void QmitkUSNewVideoDeviceWidget::CreateQtPartControl(QWidget *parent)
{
  if (!m_Controls)
  {
    // create GUI widgets
    m_Controls = new Ui::QmitkUSNewVideoDeviceWidgetControls;
    m_Controls->setupUi(parent);
    this->CreateConnections();
  }
}

void QmitkUSNewVideoDeviceWidget::CreateConnections()
{
  if ( m_Controls )
  {
    connect( m_Controls->m_BtnDone,   SIGNAL(clicked()), this, SLOT(OnClickedDone()) );
    connect( m_Controls->m_BtnCancel, SIGNAL(clicked()), this, SLOT(OnClickedCancel()) );
    connect( m_Controls->m_RadioDeviceSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection()) );
    connect( m_Controls->m_RadioFileSource,   SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection()) );

  }
  // Hide & show stuff
  m_Controls->m_FilePathSelector->setVisible(false);
}

///////////// Methods & Slots Handling Direct Interaction /////////////////

void QmitkUSNewVideoDeviceWidget::OnClickedDone(){
   m_Active = false;
  MITK_INFO << "NewDeviceWidget: ClickedDone()";

  // Assemble Metadata
  mitk::USImageMetadata::Pointer metadata = mitk::USImageMetadata::New();
  metadata->SetDeviceComment(m_Controls->m_Comment->text().toStdString());
  metadata->SetDeviceModel(m_Controls->m_Model->text().toStdString());
  metadata->SetDeviceManufacturer(m_Controls->m_Manufacturer->text().toStdString());
  metadata->SetProbeName(m_Controls->m_Probe->text().toStdString());
  metadata->SetZoom(m_Controls->m_Zoom->text().toStdString());

  // Create Device
  mitk::USVideoDevice::Pointer newDevice;
  if (m_Controls->m_RadioDeviceSource->isChecked()){
    int deviceID = m_Controls->m_DeviceSelector->value();
    newDevice = mitk::USVideoDevice::New(deviceID, metadata);
  } else {
    std::string filepath = m_Controls->m_FilePathSelector->text().toStdString();
    newDevice = mitk::USVideoDevice::New(filepath, metadata);
  }

  newDevice->Connect();

  emit Finished();
}

void QmitkUSNewVideoDeviceWidget::OnClickedCancel(){
  m_TargetDevice = 0;
  m_Active = false;
   MITK_INFO << "NewDeviceWidget: OnClickedCancel()";
  emit Finished();

}

void QmitkUSNewVideoDeviceWidget::OnDeviceTypeSelection(){
  m_Controls->m_FilePathSelector->setVisible(m_Controls->m_RadioFileSource->isChecked());
  m_Controls->m_DeviceSelector->setVisible(m_Controls->m_RadioDeviceSource->isChecked());
}

///////////////// Methods & Slots Handling Logic //////////////////////////

void QmitkUSNewVideoDeviceWidget::EditDevice(mitk::USDevice::Pointer device)
{
  // If no VideoDevice is given, throw an exception
  if (device->GetClassName().compare("org.mitk.modules.us.USVideoDevice") != 0){
    // TODO Alert if bad path
    mitkThrow() << "NewVideoDevcieWidget recieved an incompatible Device Type to edit. Devicetype was: " << device->GetClassName();
  }
  MITK_INFO << "NewDeviceWidget: EditDevice()";
  m_TargetDevice = static_cast<mitk::USVideoDevice*> (device.GetPointer());
  m_Active = true;
}

void QmitkUSNewVideoDeviceWidget::CreateNewDevice()
{
  MITK_INFO << "NewDeviceWidget: CreateNewDevice()";
  m_TargetDevice = 0;
  InitFields(mitk::USImageMetadata::New());
  m_Active = true;
}

/////////////////////// HOUSEHOLDING CODE /////////////////////////////////

QListWidgetItem* QmitkUSNewVideoDeviceWidget::ConstructItemFromDevice(mitk::USDevice::Pointer device){
  QListWidgetItem *result = new QListWidgetItem;
  std::string text = device->GetDeviceManufacturer() + "|" + device->GetDeviceModel();
  result->setText(text.c_str());
  return result;
}

void QmitkUSNewVideoDeviceWidget::InitFields(mitk::USImageMetadata::Pointer metadata){
  this->m_Controls->m_Manufacturer->setText (metadata->GetDeviceManufacturer().c_str());
  this->m_Controls->m_Model->setText (metadata->GetDeviceModel().c_str());
  this->m_Controls->m_Comment->setText (metadata->GetDeviceComment().c_str());
  this->m_Controls->m_Probe->setText (metadata->GetProbeName().c_str());
  this->m_Controls->m_Zoom->setText (metadata->GetZoom().c_str());
}
<commit_msg>Fixing DeviceClass behaviour in NewVideoDeviceWidget<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

//#define _USE_MATH_DEFINES
#include <QmitkUSNewVideoDeviceWidget.h>

//QT headers

//mitk headers

//itk headers

const std::string QmitkUSNewVideoDeviceWidget::VIEW_ID = "org.mitk.views.QmitkUSNewVideoDeviceWidget";

QmitkUSNewVideoDeviceWidget::QmitkUSNewVideoDeviceWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f)
{
  m_Controls = NULL;
  CreateQtPartControl(this);
}

QmitkUSNewVideoDeviceWidget::~QmitkUSNewVideoDeviceWidget()
{
}

//////////////////// INITIALIZATION /////////////////////

void QmitkUSNewVideoDeviceWidget::CreateQtPartControl(QWidget *parent)
{
  if (!m_Controls)
  {
    // create GUI widgets
    m_Controls = new Ui::QmitkUSNewVideoDeviceWidgetControls;
    m_Controls->setupUi(parent);
    this->CreateConnections();
  }
}

void QmitkUSNewVideoDeviceWidget::CreateConnections()
{
  if ( m_Controls )
  {
    connect( m_Controls->m_BtnDone,   SIGNAL(clicked()), this, SLOT(OnClickedDone()) );
    connect( m_Controls->m_BtnCancel, SIGNAL(clicked()), this, SLOT(OnClickedCancel()) );
    connect( m_Controls->m_RadioDeviceSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection()) );
    connect( m_Controls->m_RadioFileSource,   SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection()) );

  }
  // Hide & show stuff
  m_Controls->m_FilePathSelector->setVisible(false);
}

///////////// Methods & Slots Handling Direct Interaction /////////////////

void QmitkUSNewVideoDeviceWidget::OnClickedDone(){
   m_Active = false;
  MITK_INFO << "NewDeviceWidget: ClickedDone()";

  // Assemble Metadata
  mitk::USImageMetadata::Pointer metadata = mitk::USImageMetadata::New();
  metadata->SetDeviceComment(m_Controls->m_Comment->text().toStdString());
  metadata->SetDeviceModel(m_Controls->m_Model->text().toStdString());
  metadata->SetDeviceManufacturer(m_Controls->m_Manufacturer->text().toStdString());
  metadata->SetProbeName(m_Controls->m_Probe->text().toStdString());
  metadata->SetZoom(m_Controls->m_Zoom->text().toStdString());

  // Create Device
  mitk::USVideoDevice::Pointer newDevice;
  if (m_Controls->m_RadioDeviceSource->isChecked()){
    int deviceID = m_Controls->m_DeviceSelector->value();
    newDevice = mitk::USVideoDevice::New(deviceID, metadata);
  } else {
    std::string filepath = m_Controls->m_FilePathSelector->text().toStdString();
    newDevice = mitk::USVideoDevice::New(filepath, metadata);
  }

  newDevice->Connect();

  emit Finished();
}

void QmitkUSNewVideoDeviceWidget::OnClickedCancel(){
  m_TargetDevice = 0;
  m_Active = false;
   MITK_INFO << "NewDeviceWidget: OnClickedCancel()";
  emit Finished();

}

void QmitkUSNewVideoDeviceWidget::OnDeviceTypeSelection(){
  m_Controls->m_FilePathSelector->setVisible(m_Controls->m_RadioFileSource->isChecked());
  m_Controls->m_DeviceSelector->setVisible(m_Controls->m_RadioDeviceSource->isChecked());
}

///////////////// Methods & Slots Handling Logic //////////////////////////

void QmitkUSNewVideoDeviceWidget::EditDevice(mitk::USDevice::Pointer device)
{
  // If no VideoDevice is given, throw an exception
  if (device->GetDeviceClass().compare("org.mitk.modules.us.USVideoDevice") != 0){
    // TODO Alert if bad path
    mitkThrow() << "NewVideoDevcieWidget recieved an incompatible Device Type to edit. Devicetype was: " << device->GetDeviceClass();
  }
  MITK_INFO << "NewDeviceWidget: EditDevice()";
  m_TargetDevice = static_cast<mitk::USVideoDevice*> (device.GetPointer());
  m_Active = true;
}

void QmitkUSNewVideoDeviceWidget::CreateNewDevice()
{
  MITK_INFO << "NewDeviceWidget: CreateNewDevice()";
  m_TargetDevice = 0;
  InitFields(mitk::USImageMetadata::New());
  m_Active = true;
}

/////////////////////// HOUSEHOLDING CODE ///////////////////////////////

QListWidgetItem* QmitkUSNewVideoDeviceWidget::ConstructItemFromDevice(mitk::USDevice::Pointer device){
  QListWidgetItem *result = new QListWidgetItem;
  std::string text = device->GetDeviceManufacturer() + "|" + device->GetDeviceModel();
  result->setText(text.c_str());
  return result;
}

void QmitkUSNewVideoDeviceWidget::InitFields(mitk::USImageMetadata::Pointer metadata){
  this->m_Controls->m_Manufacturer->setText (metadata->GetDeviceManufacturer().c_str());
  this->m_Controls->m_Model->setText (metadata->GetDeviceModel().c_str());
  this->m_Controls->m_Comment->setText (metadata->GetDeviceComment().c_str());
  this->m_Controls->m_Probe->setText (metadata->GetProbeName().c_str());
  this->m_Controls->m_Zoom->setText (metadata->GetZoom().c_str());
}
<|endoftext|>


<commit_before>#include "SoundService.h"
#include "../Logger.h"
#include "../Helpers/Helpers.h"

#ifdef ANDROID
#include "../Assets/Resource.h"
#endif

namespace star
{
	SoundService * SoundService::mSoundService = nullptr;
	bool SoundService::mbIsInitialized = false;

	SoundService * SoundService::GetInstance()
	{
		if(mSoundService == nullptr)
		{
			mSoundService = new SoundService();
		}
		return mSoundService;
	}

	SoundService::SoundService()
#ifdef ANDROID
		:mEngine(NULL),
		mEngineObj(NULL),
		mOutputMixObj(NULL),
		m_CurrentSoundEffect(nullptr),
		m_CurrentSoundFile(nullptr)
#endif
	{
		mQueueIterator = mBackgroundQueue.begin();
	}

	SoundService::~SoundService()
	{
		for(auto music : mMusicList)
		{
			delete music.second;
			music.second = nullptr;
		}

		for(auto effect : mEffectsList)
		{
			delete effect.second;
			effect.second = nullptr;
		}
	}

	void SoundService::Start()
	{
		if(mbIsInitialized) return;

		mbIsInitialized = true;
		star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Started making Audio Engine"));

#ifdef DESKTOP
		int32 audio_rate(44100);
		uint16 audio_format(MIX_DEFAULT_FORMAT);
		int32 audio_channels(2);
		int32 audio_buffers(4096);

		SDL_Init(SDL_INIT_AUDIO);
		int flags = MIX_INIT_OGG | MIX_INIT_MP3;
		int innited = Mix_Init(flags);
		if((innited & flags) != flags)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Info,
				_T("Audio :Could not init Ogg and Mp3, reason : ") + string_cast<tstring>(Mix_GetError()));
		}

		if(Mix_OpenAudio(audio_rate, audio_format,audio_channels,audio_buffers))
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Could Not open Audio Mix SDL"));
			Stop();
			return;
		}

		//check What we got
		int32 actual_rate, actual_channels;
		uint16 actual_format;

		Mix_QuerySpec(&actual_rate,&actual_format,&actual_channels);
		tstringstream buffer;
		buffer << "Actual Rate : " << actual_rate << ", Actual Format : " << actual_format
			<< ", Actual Channels : " << actual_channels << std::endl;
		star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : SDL specs : ")+buffer.str());
		Mix_Volume(-1,100);
#else

		SLresult lRes;
		const SLuint32 lEngineMixIIDCount =1;
		const SLInterfaceID lEngineMixIIDs[]={SL_IID_ENGINE};
		const SLboolean lEngineMixReqs[]={SL_BOOLEAN_TRUE};
		const SLuint32 lOutputMixIIDCount=0;
		const SLInterfaceID lOutputMixIIDs[]={};
		const SLboolean lOutputMixReqs[]={};

		lRes = slCreateEngine(&mEngineObj, 0, NULL, lEngineMixIIDCount, lEngineMixIIDs, lEngineMixReqs);
		if(lRes != SL_RESULT_SUCCESS)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't make Audio Engine"));
			Stop();
			return;
		}

		lRes = (*mEngineObj)->Realize(mEngineObj, SL_BOOLEAN_FALSE);
		if(lRes != SL_RESULT_SUCCESS)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't realize Engine"));
			Stop();
			return;
		}

		lRes = (*mEngineObj)->GetInterface(mEngineObj,SL_IID_ENGINE, &mEngine);
		if(lRes != SL_RESULT_SUCCESS)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't fetch engine interface"));
			Stop();
			return;
		}

		lRes = (*mEngine)->CreateOutputMix(mEngine, &mOutputMixObj, lOutputMixIIDCount, lOutputMixIIDs,lOutputMixReqs);
		if(lRes != SL_RESULT_SUCCESS)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't create outputmix"));
			Stop();
			return;
		}

		lRes = (*mOutputMixObj)->Realize(mOutputMixObj,SL_BOOLEAN_FALSE);
		if(lRes != SL_RESULT_SUCCESS)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't realise output object"));
			Stop();
			return;
		}
		star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Succesfull made Audio Engine"));
#endif
	}

	void SoundService::Stop()
	{
		StopAllSound();
		DeleteAllSound();

#ifdef DESKTOP
		Mix_CloseAudio();
		Mix_Quit();
		SDL_Quit();
#else
		if(mOutputMixObj != NULL)
		{
			(*mOutputMixObj)->Destroy(mOutputMixObj);
			mOutputMixObj = NULL;
		}
		if(mEngineObj != NULL)
		{
			(*mEngineObj)->Destroy(mEngineObj);
			mEngineObj = NULL;
			mEngine = NULL;
		}
#endif
		star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Stopped audio Engine"));
	}

	void SoundService::LoadMusic(const tstring& path, const tstring& name)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		if(mMusicList.find(name) != mMusicList.end())
		{
			return;
		}

		auto pathit = mMusicPathList.find(path);
		if(pathit != mMusicPathList.end())
		{
			star::Logger::GetInstance()->Log(LogLevel::Warning,_T("Sound Service : Sound File Path Already Exists"));
			tstring nameold = pathit->second;
			auto nameit = mMusicList.find(nameold);
			if(nameit != mMusicList.end())
			{
				star::Logger::GetInstance()->
					Log(LogLevel::Warning,_T("Sound Service : Found sound file of old path, making copy for new name"));
				mMusicList[name]=nameit->second;
				return;
			}
			mMusicPathList.erase(pathit);
			return;
		}

		SoundFile* music = new SoundFile(path);
		mMusicList[name] = music;
		mMusicPathList[path]=name;
		return;
	}

	void SoundService::LoadSoundEffect(const tstring& path, const tstring& name)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		if(mEffectsList.find(name) != mEffectsList.end())
		{
			star::Logger::GetInstance()->Log(LogLevel::Warning,_T("Sound Service : That effect already excists."));
		}

		auto pathit = mSoundEffectPathList.find(path);
		if(pathit != mSoundEffectPathList.end())
		{
			star::Logger::GetInstance()->Log(LogLevel::Warning,_T("Sound Service : Sound Effect Path Already Exists"));
			tstring nameold = pathit->second;
			auto nameit = mMusicList.find(nameold);
			if(nameit!= mMusicList.end())
			{
				star::Logger::GetInstance()->
					Log(LogLevel::Warning,_T("Sound Service : Found Sound Effect of old path, making copy for new name"));
				mMusicList[name] = nameit->second;
			}
			mSoundEffectPathList.erase(pathit);
		}

		SoundEffect* effect = new SoundEffect(path);
		mEffectsList[name] = effect;
		mSoundEffectPathList[path] = name;
	}

	void SoundService::PlaySoundFile(const tstring& path, const tstring& name, int loopTimes)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		if(mMusicList.find(name) == mMusicList.end())
		{
			LoadMusic(path,name);
		}
		return PlaySoundFile(name,loopTimes);
	}

	void SoundService::PlaySoundFile(const tstring& name, int loopTimes)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		auto it = mMusicList.find(name);
		if(it != mMusicList.end())
		{
			if(m_CurrentSoundFile != nullptr) m_CurrentSoundFile->Stop();
			m_CurrentSoundFile = mMusicList[name];
			m_CurrentSoundFile->Play(loopTimes);
			return;
		}
		else
		{
			m_CurrentSoundFile = nullptr;
			star::Logger::GetInstance()->
				Log(LogLevel::Warning,_T("Sound Service : Couldn't find song '") + name + _T("'."));
		}

	}

	void SoundService::PlaySoundEffect(const tstring& path, const tstring& name, int loopTimes=0)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		if(mEffectsList.find(name) == mEffectsList.end())
		{
			LoadSoundEffect(path,name);
		}
		PlaySoundEffect(name,loopTimes);
	}

	void SoundService::PlaySoundEffect(const tstring& name, int loopTimes=0)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		auto it = mEffectsList.find(name);
		if(it != mEffectsList.end())
		{
			m_CurrentSoundEffect = mEffectsList[name];
			mEffectsList[name]->Play(loopTimes);
		}
		else
		{
			star::Logger::GetInstance()->
				Log(LogLevel::Warning,_T("Sound Service : Couldn't find effect '") + name + _T("'."));
		}

	}

	void SoundService::AddToBackgroundQueue(const tstring& name)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		auto it = mMusicList.find(name);
		if(it != mMusicList.end())
		{
			mBackgroundQueue.push_back(mMusicList[name]);
		}
		else
		{
			star::Logger::GetInstance()->
				Log(LogLevel::Warning,_T("Sound Service : Couldn't find background song '") + name + _T("'."));
		}
	}

	void SoundService::PlayBackgroundQueue()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		mQueueIterator = mBackgroundQueue.begin();
		if(mQueueIterator != mBackgroundQueue.end())
		{
			(*mQueueIterator)->PlayQueued(0);
		}
		else
		{
			star::Logger::GetInstance()->Log(LogLevel::Warning,_T("Sound Service : No song in background queue."));
		}
	}

	void SoundService::PlayNextSongInQueue()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));
		if(mBackgroundQueue.size() == 0) return;

		++mQueueIterator;
		if(mQueueIterator != mBackgroundQueue.end())
		{
			(*mQueueIterator)->PlayQueued(0);
		}
		else
		{
			mQueueIterator==mBackgroundQueue.begin();
			(*mQueueIterator)->PlayQueued(0);
		}
	}

	void SoundService::StopSound(const tstring& name)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		auto it = mMusicList.find(name);
		if(it != mMusicList.end())
		{
			mMusicList[name]->Stop();
			return;
		}

		auto it2 = mEffectsList.find(name);
		if(it2 != mEffectsList.end())
		{
			mEffectsList[name]->Stop();
			return;
		}
	}

	void SoundService::StopAllSound()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		for(auto song : mMusicList)
		{
			song.second->Stop();
		}

		for(auto effect : mEffectsList)
		{
			effect.second->Stop();
		}
	}

	void SoundService::PauseAllSound()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		for(auto song : mMusicList)
		{
			song.second->Pause();
		}

		for(auto effect : mEffectsList)
		{
			effect.second->Pause();
		}
	}

	void SoundService::ResumeAllSound()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		for(auto song : mMusicList)
		{
			song.second->Resume();
		}

		for(auto effect : mEffectsList)
		{
			effect.second->Resume();
		}
	}

	void SoundService::DeleteAllSound()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		for(auto song : mMusicList)
		{
			delete song.second;
		}
		mMusicList.clear();

		for(auto effect : mEffectsList)
		{
			delete effect.second;
		}
		mEffectsList.clear();

	}

#ifdef ANDROID
	const SLEngineItf& SoundService::GetEngine() const
	{
		return mEngine;
	}

	const SLObjectItf& SoundService::GetOutputMixObject() const
	{
		return mOutputMixObj;
	}
#endif
}
<commit_msg>small fix<commit_after>#include "SoundService.h"
#include "../Logger.h"
#include "../Helpers/Helpers.h"

#ifdef ANDROID
#include "../Assets/Resource.h"
#endif

namespace star
{
	SoundService * SoundService::mSoundService = nullptr;
	bool SoundService::mbIsInitialized = false;

	SoundService * SoundService::GetInstance()
	{
		if(mSoundService == nullptr)
		{
			mSoundService = new SoundService();
		}
		return mSoundService;
	}

	SoundService::SoundService()
#ifdef ANDROID
		:mEngine(NULL),
		mEngineObj(NULL),
		mOutputMixObj(NULL),
		m_CurrentSoundEffect(nullptr),
		m_CurrentSoundFile(nullptr)
#endif
	{
		mQueueIterator = mBackgroundQueue.begin();
	}

	SoundService::~SoundService()
	{
		for(auto music : mMusicList)
		{
			delete music.second;
			music.second = nullptr;
		}

		for(auto effect : mEffectsList)
		{
			delete effect.second;
			effect.second = nullptr;
		}
	}

	void SoundService::Start()
	{
		if(mbIsInitialized) return;

		mbIsInitialized = true;
		star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Started making Audio Engine"));

#ifdef DESKTOP
		int32 audio_rate(44100);
		uint16 audio_format(MIX_DEFAULT_FORMAT);
		int32 audio_channels(2);
		int32 audio_buffers(4096);

		SDL_Init(SDL_INIT_AUDIO);
		int flags = MIX_INIT_OGG | MIX_INIT_MP3;
		int innited = Mix_Init(flags);
		if((innited & flags) != flags)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Info,
				_T("Audio :Could not init Ogg and Mp3, reason : ") + string_cast<tstring>(Mix_GetError()));
		}

		if(Mix_OpenAudio(audio_rate, audio_format,audio_channels,audio_buffers))
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Could Not open Audio Mix SDL"));
			Stop();
			return;
		}

		//check What we got
		int32 actual_rate, actual_channels;
		uint16 actual_format;

		Mix_QuerySpec(&actual_rate,&actual_format,&actual_channels);
		tstringstream buffer;
		buffer << "Actual Rate : " << actual_rate << ", Actual Format : " << actual_format
			<< ", Actual Channels : " << actual_channels << std::endl;
		star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : SDL specs : ")+buffer.str());
		Mix_Volume(-1,100);
#else

		SLresult lRes;
		const SLuint32 lEngineMixIIDCount =1;
		const SLInterfaceID lEngineMixIIDs[]={SL_IID_ENGINE};
		const SLboolean lEngineMixReqs[]={SL_BOOLEAN_TRUE};
		const SLuint32 lOutputMixIIDCount=0;
		const SLInterfaceID lOutputMixIIDs[]={};
		const SLboolean lOutputMixReqs[]={};

		lRes = slCreateEngine(&mEngineObj, 0, NULL, lEngineMixIIDCount, lEngineMixIIDs, lEngineMixReqs);
		if(lRes != SL_RESULT_SUCCESS)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't make Audio Engine"));
			Stop();
			return;
		}

		lRes = (*mEngineObj)->Realize(mEngineObj, SL_BOOLEAN_FALSE);
		if(lRes != SL_RESULT_SUCCESS)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't realize Engine"));
			Stop();
			return;
		}

		lRes = (*mEngineObj)->GetInterface(mEngineObj,SL_IID_ENGINE, &mEngine);
		if(lRes != SL_RESULT_SUCCESS)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't fetch engine interface"));
			Stop();
			return;
		}

		lRes = (*mEngine)->CreateOutputMix(mEngine, &mOutputMixObj, lOutputMixIIDCount, lOutputMixIIDs,lOutputMixReqs);
		if(lRes != SL_RESULT_SUCCESS)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't create outputmix"));
			Stop();
			return;
		}

		lRes = (*mOutputMixObj)->Realize(mOutputMixObj,SL_BOOLEAN_FALSE);
		if(lRes != SL_RESULT_SUCCESS)
		{
			star::Logger::GetInstance()->Log(star::LogLevel::Error, _T("Audio : Can't realise output object"));
			Stop();
			return;
		}
		star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Succesfull made Audio Engine"));
#endif
	}

	void SoundService::Stop()
	{
		StopAllSound();
		DeleteAllSound();

#ifdef DESKTOP
		Mix_CloseAudio();
		Mix_Quit();
		SDL_Quit();
#else
		if(mOutputMixObj != NULL)
		{
			(*mOutputMixObj)->Destroy(mOutputMixObj);
			mOutputMixObj = NULL;
		}
		if(mEngineObj != NULL)
		{
			(*mEngineObj)->Destroy(mEngineObj);
			mEngineObj = NULL;
			mEngine = NULL;
		}
#endif
		star::Logger::GetInstance()->Log(star::LogLevel::Info, _T("Audio : Stopped audio Engine"));
	}

	void SoundService::LoadMusic(const tstring& path, const tstring& name)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		if(mMusicList.find(name) != mMusicList.end())
		{
			return;
		}

		auto pathit = mMusicPathList.find(path);
		if(pathit != mMusicPathList.end())
		{
			star::Logger::GetInstance()->Log(LogLevel::Warning,_T("Sound Service : Sound File Path Already Exists"));
			tstring nameold = pathit->second;
			auto nameit = mMusicList.find(nameold);
			if(nameit != mMusicList.end())
			{
				star::Logger::GetInstance()->
					Log(LogLevel::Warning,_T("Sound Service : Found sound file of old path, making copy for new name"));
				mMusicList[name]=nameit->second;
				return;
			}
			mMusicPathList.erase(pathit);
			return;
		}

		SoundFile* music = new SoundFile(path);
		mMusicList[name] = music;
		mMusicPathList[path]=name;
		return;
	}

	void SoundService::LoadSoundEffect(const tstring& path, const tstring& name)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		if(mEffectsList.find(name) != mEffectsList.end())
		{
			star::Logger::GetInstance()->Log(LogLevel::Warning,_T("Sound Service : That effect already excists."));
		}

		auto pathit = mSoundEffectPathList.find(path);
		if(pathit != mSoundEffectPathList.end())
		{
			star::Logger::GetInstance()->Log(LogLevel::Warning,_T("Sound Service : Sound Effect Path Already Exists"));
			tstring nameold = pathit->second;
			auto nameit = mMusicList.find(nameold);
			if(nameit!= mMusicList.end())
			{
				star::Logger::GetInstance()->
					Log(LogLevel::Warning,_T("Sound Service : Found Sound Effect of old path, making copy for new name"));
				mMusicList[name] = nameit->second;
			}
			mSoundEffectPathList.erase(pathit);
		}

		SoundEffect* effect = new SoundEffect(path);
		mEffectsList[name] = effect;
		mSoundEffectPathList[path] = name;
	}

	void SoundService::PlaySoundFile(const tstring& path, const tstring& name, int loopTimes)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		if(mMusicList.find(name) == mMusicList.end())
		{
			LoadMusic(path,name);
		}
		return PlaySoundFile(name,loopTimes);
	}

	void SoundService::PlaySoundFile(const tstring& name, int loopTimes)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		auto it = mMusicList.find(name);
		if(it != mMusicList.end())
		{
			if(m_CurrentSoundFile != nullptr) m_CurrentSoundFile->Stop();
			m_CurrentSoundFile = mMusicList[name];
			m_CurrentSoundFile->Play(loopTimes);
			return;
		}
		else
		{
			m_CurrentSoundFile = nullptr;
			star::Logger::GetInstance()->
				Log(LogLevel::Warning,_T("Sound Service : Couldn't find song '") + name + _T("'."));
		}

	}

	void SoundService::PlaySoundEffect(const tstring& path, const tstring& name, int loopTimes)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		if(mEffectsList.find(name) == mEffectsList.end())
		{
			LoadSoundEffect(path,name);
		}
		PlaySoundEffect(name,loopTimes);
	}

	void SoundService::PlaySoundEffect(const tstring& name, int loopTimes)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		auto it = mEffectsList.find(name);
		if(it != mEffectsList.end())
		{
			m_CurrentSoundEffect = mEffectsList[name];
			mEffectsList[name]->Play(loopTimes);
		}
		else
		{
			star::Logger::GetInstance()->
				Log(LogLevel::Warning,_T("Sound Service : Couldn't find effect '") + name + _T("'."));
		}

	}

	void SoundService::AddToBackgroundQueue(const tstring& name)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		auto it = mMusicList.find(name);
		if(it != mMusicList.end())
		{
			mBackgroundQueue.push_back(mMusicList[name]);
		}
		else
		{
			star::Logger::GetInstance()->
				Log(LogLevel::Warning,_T("Sound Service : Couldn't find background song '") + name + _T("'."));
		}
	}

	void SoundService::PlayBackgroundQueue()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		mQueueIterator = mBackgroundQueue.begin();
		if(mQueueIterator != mBackgroundQueue.end())
		{
			(*mQueueIterator)->PlayQueued(0);
		}
		else
		{
			star::Logger::GetInstance()->Log(LogLevel::Warning,_T("Sound Service : No song in background queue."));
		}
	}

	void SoundService::PlayNextSongInQueue()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));
		if(mBackgroundQueue.size() == 0) return;

		++mQueueIterator;
		if(mQueueIterator != mBackgroundQueue.end())
		{
			(*mQueueIterator)->PlayQueued(0);
		}
		else
		{
			mQueueIterator==mBackgroundQueue.begin();
			(*mQueueIterator)->PlayQueued(0);
		}
	}

	void SoundService::StopSound(const tstring& name)
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		auto it = mMusicList.find(name);
		if(it != mMusicList.end())
		{
			mMusicList[name]->Stop();
			return;
		}

		auto it2 = mEffectsList.find(name);
		if(it2 != mEffectsList.end())
		{
			mEffectsList[name]->Stop();
			return;
		}
	}

	void SoundService::StopAllSound()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		for(auto song : mMusicList)
		{
			song.second->Stop();
		}

		for(auto effect : mEffectsList)
		{
			effect.second->Stop();
		}
	}

	void SoundService::PauseAllSound()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		for(auto song : mMusicList)
		{
			song.second->Pause();
		}

		for(auto effect : mEffectsList)
		{
			effect.second->Pause();
		}
	}

	void SoundService::ResumeAllSound()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		for(auto song : mMusicList)
		{
			song.second->Resume();
		}

		for(auto effect : mEffectsList)
		{
			effect.second->Resume();
		}
	}

	void SoundService::DeleteAllSound()
	{
		ASSERT(mSoundService != nullptr, _T("Sound Service is invalid."));

		for(auto song : mMusicList)
		{
			delete song.second;
		}
		mMusicList.clear();

		for(auto effect : mEffectsList)
		{
			delete effect.second;
		}
		mEffectsList.clear();

	}

#ifdef ANDROID
	const SLEngineItf& SoundService::GetEngine() const
	{
		return mEngine;
	}

	const SLObjectItf& SoundService::GetOutputMixObject() const
	{
		return mOutputMixObj;
	}
#endif
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "Color.h"
#include <cassert>

namespace facebook {
namespace react {

SharedColor colorFromComponents(ColorComponents components) {
  const CGFloat componentsArray[] = {
      components.red, components.green, components.blue, components.alpha};

  auto color = CGColorCreate(CGColorSpaceCreateDeviceRGB(), componentsArray);

  return SharedColor(color, CFRelease);
}

ColorComponents colorComponentsFromColor(SharedColor color) {
  if (!color) {
    // Empty color object can be considered as `clear` (black, fully
    // transparent) color.
    return ColorComponents{0, 0, 0, 0};
  }

  auto numberOfComponents __unused = CGColorGetNumberOfComponents(color.get());
  assert(numberOfComponents == 4);
  const CGFloat *components = CGColorGetComponents(color.get());
  return ColorComponents{(float)components[0],
                         (float)components[1],
                         (float)components[2],
                         (float)components[3]};
}

SharedColor clearColor() {
  static SharedColor color = colorFromComponents(ColorComponents{0, 0, 0, 0});
  return color;
}

SharedColor blackColor() {
  static SharedColor color = colorFromComponents(ColorComponents{0, 0, 0, 1});
  return color;
}

SharedColor whiteColor() {
  static SharedColor color = colorFromComponents(ColorComponents{1, 1, 1, 1});
  return color;
}

} // namespace react
} // namespace facebook
<commit_msg>Use CGColorRelease instead of CGRelease<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "Color.h"
#include <cassert>

namespace facebook {
namespace react {

SharedColor colorFromComponents(ColorComponents components) {
  const CGFloat componentsArray[] = {
      components.red, components.green, components.blue, components.alpha};

  auto color = CGColorCreate(CGColorSpaceCreateDeviceRGB(), componentsArray);

  return SharedColor(color, CGColorRelease);
}

ColorComponents colorComponentsFromColor(SharedColor color) {
  if (!color) {
    // Empty color object can be considered as `clear` (black, fully
    // transparent) color.
    return ColorComponents{0, 0, 0, 0};
  }

  auto numberOfComponents __unused = CGColorGetNumberOfComponents(color.get());
  assert(numberOfComponents == 4);
  const CGFloat *components = CGColorGetComponents(color.get());
  return ColorComponents{(float)components[0],
                         (float)components[1],
                         (float)components[2],
                         (float)components[3]};
}

SharedColor clearColor() {
  static SharedColor color = colorFromComponents(ColorComponents{0, 0, 0, 0});
  return color;
}

SharedColor blackColor() {
  static SharedColor color = colorFromComponents(ColorComponents{0, 0, 0, 1});
  return color;
}

SharedColor whiteColor() {
  static SharedColor color = colorFromComponents(ColorComponents{1, 1, 1, 1});
  return color;
}

} // namespace react
} // namespace facebook
<|endoftext|>