<commit_before>#include "error-handler.hh"
#include "server-channel.hh"

namespace mimosa
{
  namespace http
  {
    ServerChannel::ServerChannel(stream::BufferedStream::Ptr stream,
                                 Handler::Ptr                handler)
      : stream_(stream),
        handler_(handler),
        request_(new RequestReader(*this)),
        response_(new ResponseWriter(*this)),
        addr_(nullptr),
        addr_len_(0),
        read_timeout_(0),
        write_timeout_(0)
    {
    }

    ServerChannel::~ServerChannel()
    {
    }

    void
    ServerChannel::run()
    {
      do {
        request_->clear();
        response_->clear();
        if (!readRequest() ||
            !runHandler() ||
            !sendResponse())
          break;
      } while (response_->keep_alive_);
    }

    bool
    ServerChannel::readRequest()
    {
      bool found = false;
      stream_->setReadTimeout(read_timeout_ > 0 ? read_timeout_ + monotonicTimeCoarse() : 0);
      stream::Buffer::Ptr buffer = stream_->readUntil(
        "\r\n\r\n", 5 * 1024, &found);
      if (!buffer)
      {
        requestTimeout();
        return false;
      }

      if (!found)
      {
        ErrorHandler::basicResponse(*request_, *response_, kStatusRequestEntityTooLarge);
        return false;
      }

      if (!request_->parse(buffer->data(), buffer->size() + 2))
      {
        badRequest();
        return false;
      }

      response_->keep_alive_ = request_->keep_alive_;
      return request_->prepare();
    }

    bool
    ServerChannel::runHandler()
    {
      stream_->setWriteTimeout(write_timeout_ > 0 ? write_timeout_ + monotonicTimeCoarse() : 0);
      return handler_->handle(*request_, *response_);
    }

    bool
    ServerChannel::sendResponse()
    {
      if (!response_->finish())
        return false;

      // don't flush yet if we can handle next request and send just one tcp packet
      if (stream_->readyRead() == 0)
        return stream_->flush();

      return true;
    }

    void
    ServerChannel::requestTimeout()
    {
      ErrorHandler::basicResponse(*request_, *response_, kStatusRequestTimeout);
    }

    void
    ServerChannel::badRequest()
    {
      ErrorHandler::basicResponse(*request_, *response_, kStatusBadRequest);
    };
  }
}
<commit_msg>http::ServerChannel: enable compression by default<commit_after>#include "error-handler.hh"
#include "server-channel.hh"

namespace mimosa
{
  namespace http
  {
    ServerChannel::ServerChannel(stream::BufferedStream::Ptr stream,
                                 Handler::Ptr                handler)
      : stream_(stream),
        handler_(handler),
        request_(new RequestReader(*this)),
        response_(new ResponseWriter(*this)),
        addr_(nullptr),
        addr_len_(0),
        read_timeout_(0),
        write_timeout_(0)
    {
    }

    ServerChannel::~ServerChannel()
    {
    }

    void
    ServerChannel::run()
    {
      do {
        request_->clear();
        response_->clear();
        if (!readRequest() ||
            !runHandler() ||
            !sendResponse())
          break;
      } while (response_->keep_alive_);
    }

    bool
    ServerChannel::readRequest()
    {
      bool found = false;
      stream_->setReadTimeout(read_timeout_ > 0 ? read_timeout_ + monotonicTimeCoarse() : 0);
      stream::Buffer::Ptr buffer = stream_->readUntil(
        "\r\n\r\n", 5 * 1024, &found);
      if (!buffer)
      {
        requestTimeout();
        return false;
      }

      if (!found)
      {
        ErrorHandler::basicResponse(*request_, *response_, kStatusRequestEntityTooLarge);
        return false;
      }

      if (!request_->parse(buffer->data(), buffer->size() + 2))
      {
        badRequest();
        return false;
      }

      response_->keep_alive_ = request_->keep_alive_;
      return request_->prepare();
    }

    bool
    ServerChannel::runHandler()
    {
      stream_->setWriteTimeout(write_timeout_ > 0 ? write_timeout_ + monotonicTimeCoarse() : 0);
      // enable compression by default
      response_->enableCompression(*request_);
      return handler_->handle(*request_, *response_);
    }

    bool
    ServerChannel::sendResponse()
    {
      if (!response_->finish())
        return false;

      // don't flush yet if we can handle next request and send just one tcp packet
      if (stream_->readyRead() == 0)
        return stream_->flush();

      return true;
    }

    void
    ServerChannel::requestTimeout()
    {
      ErrorHandler::basicResponse(*request_, *response_, kStatusRequestTimeout);
    }

    void
    ServerChannel::badRequest()
    {
      ErrorHandler::basicResponse(*request_, *response_, kStatusBadRequest);
    };
  }
}
<|endoftext|>


<commit_before>#pragma once

#include <agency/detail/config.hpp>
#include <agency/future.hpp>
#include <agency/new_executor_traits.hpp>
#include <agency/detail/executor_traits/shared_parameter_container.hpp>
#include <agency/detail/executor_traits/check_for_member_functions.hpp>
#include <agency/detail/index_cast.hpp>
#include <type_traits>
#include <utility>
#include <cassert>

namespace agency
{
namespace detail
{
namespace new_executor_traits_detail
{
namespace multi_agent_when_all_execute_and_select_with_shared_inits_implementation_strategies
{

struct use_multi_agent_when_all_execute_and_select_with_shared_inits_member_function {};

struct use_multi_agent_when_all_execute_and_select_member_function {};

struct use_single_agent_when_all_execute_and_select_with_nested_terminal_multi_agent_execute_with_shared_inits {};

template<class Function, class Shape>
struct multi_agent_when_all_execute_and_select_with_shared_inits_functor
{
  mutable Function f;
  Shape shape;

  template<size_t depth, class AgentIndex>
  __AGENCY_ANNOTATION
  size_t rank_in_group(const AgentIndex& idx) const
  {
    // to compute the rank of an index at a particular depth,
    // first prepend 0 (1) to idx (shape) to represent an index of the root group (it has none otherwise)
    // XXX seems like index_cast() should just do the right thing for empty indices
    //     it would correspond to a single-agent task
    auto augmented_idx   = detail::tuple_prepend(detail::wrap_scalar(idx), size_t{0});
    auto augmented_shape = detail::tuple_prepend(detail::wrap_scalar(shape), size_t{1});

    // take the first depth+1 (plus one because we prepended 1) indices of the index & shape and do an index_cast to size_t
    return detail::index_cast<size_t>(detail::tuple_take<depth+1>(augmented_idx),
                                      detail::tuple_take<depth+1>(augmented_shape),
                                      detail::shape_size(detail::tuple_take<depth+1>(augmented_shape)));
  }

  template<size_t... ContainerIndices, class AgentIndex, class TupleOfContainers, class... Types>
  __AGENCY_ANNOTATION
  void impl(detail::index_sequence<ContainerIndices...>, AgentIndex&& agent_idx, TupleOfContainers&& shared_arg_containers, Types&... past_args) const
  {
    f(std::forward<AgentIndex>(agent_idx),                                                             // pass the agent index
      past_args...,                                                                                // pass the arguments coming in from futures
      std::get<ContainerIndices>(shared_arg_containers)[rank_in_group<ContainerIndices>(agent_idx)]... // pass the arguments coming in from shared parameters
    );
  }

  template<class Index, class TupleOfContainers, class... Types>
  __AGENCY_ANNOTATION
  void operator()(Index&& idx, TupleOfContainers& shared_arg_containers, Types&... past_args) const
  {
    static const size_t num_containers = std::tuple_size<TupleOfContainers>::value;
    impl(detail::make_index_sequence<num_containers>(), std::forward<Index>(idx), shared_arg_containers, past_args...);
  }
};

template<class IndexSequence, class Executor, class Function, class TupleOfFutures, class TypeList>
struct has_multi_agent_when_all_execute_and_select_member_function_impl;

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
struct has_multi_agent_when_all_execute_and_select_member_function_impl<detail::index_sequence<Indices...>,Executor,Function,TupleOfFutures,detail::type_list<Types...>>
{
  using tuple_of_shared_parameter_containers_type = tuple_of_shared_parameter_containers<Executor, typename std::decay<Types>::type...>;

  using future_tuple_of_shared_parameter_containers_type = typename new_executor_traits<Executor>::template future<tuple_of_shared_parameter_containers_type>;

  using prepended_tuple_of_futures_type = tuple_prepend_result_t<TupleOfFutures, future_tuple_of_shared_parameter_containers_type>;

  using shape_type = typename new_executor_traits<Executor>::shape_type;

  using wrapped_function_type = multi_agent_when_all_execute_and_select_with_shared_inits_functor<Function, shape_type>;

  using type = typename new_executor_traits_detail::has_multi_agent_when_all_execute_and_select<
    Executor, wrapped_function_type, prepended_tuple_of_futures_type, (Indices+1)...
  >::type;
};

template<class IndexSequence, class Executor, class Function, class TupleOfFutures, class TypeList>
struct select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation_impl;

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
struct select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation_impl<
  detail::index_sequence<Indices...>, Executor, Function, TupleOfFutures, type_list<Types...>
>
{
  using type = typename std::conditional<
    has_multi_agent_when_all_execute_and_select_with_shared_inits<
      detail::index_sequence<Indices...>, Executor, Function, TupleOfFutures, type_list<Types...>
    >::value,
    use_multi_agent_when_all_execute_and_select_with_shared_inits_member_function,
    typename std::conditional<
      has_multi_agent_when_all_execute_and_select<Executor, Function, TupleOfFutures, Indices...>::value,
      use_multi_agent_when_all_execute_and_select_member_function,
      use_single_agent_when_all_execute_and_select_with_nested_terminal_multi_agent_execute_with_shared_inits
    >::type
  >::type;
};

template<class IndexSequence, class Executor, class Function, class TupleOfFutures, class TypeList>
using select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation = typename select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation_impl<IndexSequence,Executor,Function,TupleOfFutures,TypeList>::type;

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(use_multi_agent_when_all_execute_and_select_with_shared_inits_member_function,
                                                            Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Types&&... shared_inits)
{
  return ex.template when_all_execute_and_select<Indices...>(f, shape, std::forward<TupleOfFutures>(futures), std::forward<Types>(shared_inits)...);
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Factories>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(use_multi_agent_when_all_execute_and_select_member_function,
                                                            Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Factories... shared_factories)
{
  // create a tuple of containers holding a shared parameter for each group
  auto shared_param_containers_tuple = new_executor_traits_detail::make_tuple_of_shared_parameter_containers(ex, shape, shared_factories...);

  // turn it into a future
  auto shared_param_containers_tuple_fut = new_executor_traits<Executor>::template make_ready_future<decltype(shared_param_containers_tuple)>(ex, std::move(shared_param_containers_tuple));

  // combine the shared parameters with the incoming futures
  // the tuple of containers goes in front of the incoming futures
  auto shared_and_futures = detail::tuple_prepend(std::move(futures), std::move(shared_param_containers_tuple_fut));

  // wrap f with a functor to map container elements to shared parameters
  auto g = multi_agent_when_all_execute_and_select_with_shared_inits_functor<Function, typename new_executor_traits<Executor>::shape_type>{f, shape};

  // add one to the indices to skip the tuple of containers which was prepended to the tuple of futures
  return ex.template when_all_execute_and_select<(Indices+1)...>(g, shape, std::move(shared_and_futures));
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

// this functor is passed to single-agent when_all_execute_and_select below
// it makes a nested call to terminal multi-agent execute()
template<class Executor, class Function, class... Types>
struct terminal_execute_with_shared_inits_functor
{
  Executor& ex;
  mutable Function f;
  typename new_executor_traits<Executor>::shape_type shape;
  detail::tuple<Types...> shared_inits;

  // this is the functor we pass to new_executor_traits::execute() below
  template<class... FutureValueTypes>
  struct nested_functor
  {
    mutable Function f;
    mutable detail::tuple<FutureValueTypes&...> args_from_futures;

    template<size_t... TupleIndices, class Index, class... Args>
    __AGENCY_ANNOTATION
    void impl(detail::index_sequence<TupleIndices...>, const Index& idx, Args&... shared_args) const
    {
      // XXX should use std::invoke()
      f(idx, std::get<TupleIndices>(args_from_futures)..., shared_args...);
    }

    template<class Index, class... Args>
    __AGENCY_ANNOTATION
    void operator()(const Index& idx, Args&... shared_args) const
    {
      impl(detail::make_index_sequence<sizeof...(FutureValueTypes)>(), idx, shared_args...);
    }
  };

  template<size_t... TupleIndices, class... Args>
  __AGENCY_ANNOTATION
  void impl(detail::index_sequence<TupleIndices...>, Args&... future_args) const
  {
    //// XXX with polymorphic lambda we'd write something like this:
    //new_executor_traits<Executor>::execute(ex, [=,&args...](const auto& idx, auto&... shared_args)
    //{
    //  // XXX should use std::invoke()
    //  f(idx, args..., shared_args...);
    //},
    //shape,
    //std::get<Indices>(shared_inits)...
    //);

    auto g = nested_functor<Args...>{f, detail::tie(future_args...)};

    new_executor_traits<Executor>::execute(ex, g, shape, std::get<TupleIndices>(shared_inits)...);
  }

  template<class... Args>
  __AGENCY_ANNOTATION
  void operator()(Args&... future_args) const
  {
    impl(detail::make_index_sequence<sizeof...(Types)>(), future_args...);
  }
};

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(use_single_agent_when_all_execute_and_select_with_nested_terminal_multi_agent_execute_with_shared_inits,
                                                            Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Types&&... shared_inits)
{
  // XXX with polymorphic lambda we'd write something like this:
  //return new_executor_traits<Executor>::template when_all_execute_and_select<Indices...>(ex, [=,&ex](auto&... args)
  //{
  //  new_executor_traits<Executor>::execute(ex, [=,&args](const auto& idx)
  //  {
  //    f(idx, args...);
  //  },
  //  shape,
  //  shared_inits...);
  //},
  //std::forward<TupleOfFutures>(futures),
  //std::forward<Types>(shared_inits)...
  //);

  using functor_type = terminal_execute_with_shared_inits_functor<Executor,Function,typename std::decay<Types>::type...>;
  functor_type g{ex, f, shape, detail::make_tuple(std::forward<Types>(shared_inits)...)};

  return new_executor_traits<Executor>::template when_all_execute_and_select<Indices...>(ex, g, std::forward<TupleOfFutures>(futures));
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

} // end multi_agent_when_all_execute_and_select_with_shared_inits_implementation_strategies
} // end detail
} // end new_executor_traits_detail

template<class Executor>
template<size_t... Indices, class Function, class TupleOfFutures, class Factory, class... Factories>
  typename new_executor_traits<Executor>::template future<
    detail::when_all_execute_and_select_result_t<
      detail::index_sequence<Indices...>,
      typename std::decay<TupleOfFutures>::type
    >
  >
  new_executor_traits<Executor>
    ::when_all_execute_and_select(typename new_executor_traits<Executor>::executor_type& ex,
                                  Function f,
                                  typename new_executor_traits<Executor>::shape_type shape,
                                  TupleOfFutures&& futures,
                                  Factory outer_shared_factory,
                                  Factories... inner_shared_factories)
{
  static_assert(new_executor_traits<Executor>::execution_depth == 1 + sizeof...(Factories), "The number of factories must be equal to the executor's execution_depth.");

  namespace ns = detail::new_executor_traits_detail::multi_agent_when_all_execute_and_select_with_shared_inits_implementation_strategies;

  using implementation_strategy = ns::select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation<
    detail::index_sequence<Indices...>,
    Executor,
    Function,
    typename std::decay<TupleOfFutures>::type,
    detail::type_list<Factory,Factories...>
  >;

  return ns::multi_agent_when_all_execute_and_select_with_shared_inits<Indices...>(implementation_strategy(), ex, f, shape, std::forward<TupleOfFutures>(futures), outer_shared_factory, inner_shared_factories...);
} // end new_executor_traits::when_all_execute_and_select()

} // end agency

<commit_msg>Eliminate vestigal code<commit_after>#pragma once

#include <agency/detail/config.hpp>
#include <agency/future.hpp>
#include <agency/new_executor_traits.hpp>
#include <agency/detail/executor_traits/shared_parameter_container.hpp>
#include <agency/detail/executor_traits/check_for_member_functions.hpp>
#include <agency/detail/index_cast.hpp>
#include <type_traits>
#include <utility>
#include <cassert>

namespace agency
{
namespace detail
{
namespace new_executor_traits_detail
{
namespace multi_agent_when_all_execute_and_select_with_shared_inits_implementation_strategies
{

struct use_multi_agent_when_all_execute_and_select_with_shared_inits_member_function {};

struct use_multi_agent_when_all_execute_and_select_member_function {};

struct use_single_agent_when_all_execute_and_select_with_nested_terminal_multi_agent_execute_with_shared_inits {};

template<class Function, class Shape>
struct multi_agent_when_all_execute_and_select_with_shared_inits_functor
{
  mutable Function f;
  Shape shape;

  template<size_t depth, class AgentIndex>
  __AGENCY_ANNOTATION
  size_t rank_in_group(const AgentIndex& idx) const
  {
    // to compute the rank of an index at a particular depth,
    // first prepend 0 (1) to idx (shape) to represent an index of the root group (it has none otherwise)
    // XXX seems like index_cast() should just do the right thing for empty indices
    //     it would correspond to a single-agent task
    auto augmented_idx   = detail::tuple_prepend(detail::wrap_scalar(idx), size_t{0});
    auto augmented_shape = detail::tuple_prepend(detail::wrap_scalar(shape), size_t{1});

    // take the first depth+1 (plus one because we prepended 1) indices of the index & shape and do an index_cast to size_t
    return detail::index_cast<size_t>(detail::tuple_take<depth+1>(augmented_idx),
                                      detail::tuple_take<depth+1>(augmented_shape),
                                      detail::shape_size(detail::tuple_take<depth+1>(augmented_shape)));
  }

  template<size_t... ContainerIndices, class AgentIndex, class TupleOfContainers, class... Types>
  __AGENCY_ANNOTATION
  void impl(detail::index_sequence<ContainerIndices...>, AgentIndex&& agent_idx, TupleOfContainers&& shared_arg_containers, Types&... past_args) const
  {
    f(std::forward<AgentIndex>(agent_idx),                                                             // pass the agent index
      past_args...,                                                                                // pass the arguments coming in from futures
      std::get<ContainerIndices>(shared_arg_containers)[rank_in_group<ContainerIndices>(agent_idx)]... // pass the arguments coming in from shared parameters
    );
  }

  template<class Index, class TupleOfContainers, class... Types>
  __AGENCY_ANNOTATION
  void operator()(Index&& idx, TupleOfContainers& shared_arg_containers, Types&... past_args) const
  {
    static const size_t num_containers = std::tuple_size<TupleOfContainers>::value;
    impl(detail::make_index_sequence<num_containers>(), std::forward<Index>(idx), shared_arg_containers, past_args...);
  }
};

template<class IndexSequence, class Executor, class Function, class TupleOfFutures, class TypeList>
struct select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation_impl;

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
struct select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation_impl<
  detail::index_sequence<Indices...>, Executor, Function, TupleOfFutures, type_list<Types...>
>
{
  using type = typename std::conditional<
    has_multi_agent_when_all_execute_and_select_with_shared_inits<
      detail::index_sequence<Indices...>, Executor, Function, TupleOfFutures, type_list<Types...>
    >::value,
    use_multi_agent_when_all_execute_and_select_with_shared_inits_member_function,
    typename std::conditional<
      has_multi_agent_when_all_execute_and_select<Executor, Function, TupleOfFutures, Indices...>::value,
      use_multi_agent_when_all_execute_and_select_member_function,
      use_single_agent_when_all_execute_and_select_with_nested_terminal_multi_agent_execute_with_shared_inits
    >::type
  >::type;
};

template<class IndexSequence, class Executor, class Function, class TupleOfFutures, class TypeList>
using select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation = typename select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation_impl<IndexSequence,Executor,Function,TupleOfFutures,TypeList>::type;

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(use_multi_agent_when_all_execute_and_select_with_shared_inits_member_function,
                                                            Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Types&&... shared_inits)
{
  return ex.template when_all_execute_and_select<Indices...>(f, shape, std::forward<TupleOfFutures>(futures), std::forward<Types>(shared_inits)...);
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Factories>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(use_multi_agent_when_all_execute_and_select_member_function,
                                                            Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Factories... shared_factories)
{
  // create a tuple of containers holding a shared parameter for each group
  auto shared_param_containers_tuple = new_executor_traits_detail::make_tuple_of_shared_parameter_containers(ex, shape, shared_factories...);

  // turn it into a future
  auto shared_param_containers_tuple_fut = new_executor_traits<Executor>::template make_ready_future<decltype(shared_param_containers_tuple)>(ex, std::move(shared_param_containers_tuple));

  // combine the shared parameters with the incoming futures
  // the tuple of containers goes in front of the incoming futures
  auto shared_and_futures = detail::tuple_prepend(std::move(futures), std::move(shared_param_containers_tuple_fut));

  // wrap f with a functor to map container elements to shared parameters
  auto g = multi_agent_when_all_execute_and_select_with_shared_inits_functor<Function, typename new_executor_traits<Executor>::shape_type>{f, shape};

  // add one to the indices to skip the tuple of containers which was prepended to the tuple of futures
  return ex.template when_all_execute_and_select<(Indices+1)...>(g, shape, std::move(shared_and_futures));
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

// this functor is passed to single-agent when_all_execute_and_select below
// it makes a nested call to terminal multi-agent execute()
template<class Executor, class Function, class... Types>
struct terminal_execute_with_shared_inits_functor
{
  Executor& ex;
  mutable Function f;
  typename new_executor_traits<Executor>::shape_type shape;
  detail::tuple<Types...> shared_inits;

  // this is the functor we pass to new_executor_traits::execute() below
  template<class... FutureValueTypes>
  struct nested_functor
  {
    mutable Function f;
    mutable detail::tuple<FutureValueTypes&...> args_from_futures;

    template<size_t... TupleIndices, class Index, class... Args>
    __AGENCY_ANNOTATION
    void impl(detail::index_sequence<TupleIndices...>, const Index& idx, Args&... shared_args) const
    {
      // XXX should use std::invoke()
      f(idx, std::get<TupleIndices>(args_from_futures)..., shared_args...);
    }

    template<class Index, class... Args>
    __AGENCY_ANNOTATION
    void operator()(const Index& idx, Args&... shared_args) const
    {
      impl(detail::make_index_sequence<sizeof...(FutureValueTypes)>(), idx, shared_args...);
    }
  };

  template<size_t... TupleIndices, class... Args>
  __AGENCY_ANNOTATION
  void impl(detail::index_sequence<TupleIndices...>, Args&... future_args) const
  {
    //// XXX with polymorphic lambda we'd write something like this:
    //new_executor_traits<Executor>::execute(ex, [=,&args...](const auto& idx, auto&... shared_args)
    //{
    //  // XXX should use std::invoke()
    //  f(idx, args..., shared_args...);
    //},
    //shape,
    //std::get<Indices>(shared_inits)...
    //);

    auto g = nested_functor<Args...>{f, detail::tie(future_args...)};

    new_executor_traits<Executor>::execute(ex, g, shape, std::get<TupleIndices>(shared_inits)...);
  }

  template<class... Args>
  __AGENCY_ANNOTATION
  void operator()(Args&... future_args) const
  {
    impl(detail::make_index_sequence<sizeof...(Types)>(), future_args...);
  }
};

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(use_single_agent_when_all_execute_and_select_with_nested_terminal_multi_agent_execute_with_shared_inits,
                                                            Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Types&&... shared_inits)
{
  // XXX with polymorphic lambda we'd write something like this:
  //return new_executor_traits<Executor>::template when_all_execute_and_select<Indices...>(ex, [=,&ex](auto&... args)
  //{
  //  new_executor_traits<Executor>::execute(ex, [=,&args](const auto& idx)
  //  {
  //    f(idx, args...);
  //  },
  //  shape,
  //  shared_inits...);
  //},
  //std::forward<TupleOfFutures>(futures),
  //std::forward<Types>(shared_inits)...
  //);

  using functor_type = terminal_execute_with_shared_inits_functor<Executor,Function,typename std::decay<Types>::type...>;
  functor_type g{ex, f, shape, detail::make_tuple(std::forward<Types>(shared_inits)...)};

  return new_executor_traits<Executor>::template when_all_execute_and_select<Indices...>(ex, g, std::forward<TupleOfFutures>(futures));
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

} // end multi_agent_when_all_execute_and_select_with_shared_inits_implementation_strategies
} // end detail
} // end new_executor_traits_detail

template<class Executor>
template<size_t... Indices, class Function, class TupleOfFutures, class Factory, class... Factories>
  typename new_executor_traits<Executor>::template future<
    detail::when_all_execute_and_select_result_t<
      detail::index_sequence<Indices...>,
      typename std::decay<TupleOfFutures>::type
    >
  >
  new_executor_traits<Executor>
    ::when_all_execute_and_select(typename new_executor_traits<Executor>::executor_type& ex,
                                  Function f,
                                  typename new_executor_traits<Executor>::shape_type shape,
                                  TupleOfFutures&& futures,
                                  Factory outer_shared_factory,
                                  Factories... inner_shared_factories)
{
  static_assert(new_executor_traits<Executor>::execution_depth == 1 + sizeof...(Factories), "The number of factories must be equal to the executor's execution_depth.");

  namespace ns = detail::new_executor_traits_detail::multi_agent_when_all_execute_and_select_with_shared_inits_implementation_strategies;

  using implementation_strategy = ns::select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation<
    detail::index_sequence<Indices...>,
    Executor,
    Function,
    typename std::decay<TupleOfFutures>::type,
    detail::type_list<Factory,Factories...>
  >;

  return ns::multi_agent_when_all_execute_and_select_with_shared_inits<Indices...>(implementation_strategy(), ex, f, shape, std::forward<TupleOfFutures>(futures), outer_shared_factory, inner_shared_factories...);
} // end new_executor_traits::when_all_execute_and_select()

} // end agency

<|endoftext|>


<commit_before>#include "ImportMatcher.h"
#include "clang/Basic/SourceManager.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/AST/ExprObjC.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>

using namespace clang;
using namespace clang::ast_matchers;
using namespace clang::tooling;
using namespace import_tidy;

namespace clang {
namespace ast_matchers {
  static const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr> messageExpr;
  static const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl> interfaceDecl;
  static const internal::VariadicDynCastAllOfMatcher<Decl, ObjCContainerDecl> containerDecl;
  static const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl> objcMethodDecl;
  static const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl> protocolDecl;
  static const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCProtocolExpr> protocolExpr;
  static const internal::VariadicDynCastAllOfMatcher<Decl, ImportDecl> importDecl;

  AST_MATCHER(ObjCInterfaceDecl, isImplementationInMainFile) {
    if (!Node.isThisDeclarationADefinition())
      return false;

    if (auto *ImpDecl = Node.getImplementation()) {
      auto &SourceManager = Finder->getASTContext().getSourceManager();
      return SourceManager.isInMainFile(SourceManager.getExpansionLoc(ImpDecl->getLocStart()));
    } else {
      return false;
    }
  }

  AST_MATCHER(ObjCInterfaceDecl, isForwardDeclare) {
    return !Node.isThisDeclarationADefinition();
  }

  AST_POLYMORPHIC_MATCHER(isNotInSystemHeader,
                          AST_POLYMORPHIC_SUPPORTED_TYPES_2(Decl, Stmt)) {
    auto Loc = Node.getLocation();
    if (!Loc.isValid())
      return false;

    auto &SM = Finder->getASTContext().getSourceManager();
    return !SM.isInSystemHeader(Loc);
  }

} // end namespace ast_matchers
} // end namespace clang

namespace {

  static bool haveReplacementForFile(Replacements &Replacements, StringRef Path) {
    auto Found = std::find_if(Replacements.begin(), Replacements.end(),
                              [Path](const Replacement &R) {
                                return R.getFilePath() == Path;
                              });
    return Found != Replacements.end();
  }

  unsigned RangeEnd(const Range &R) {
    return R.getOffset() + R.getLength();
  }

  static std::vector<Range> collapsedRanges(const std::vector<Range> &Ranges) {
    std::vector<Range> sorted(Ranges.begin(), Ranges.end());
    if (Ranges.size() == 0)
      return sorted;

    std::sort(sorted.begin(), sorted.end(), [](Range &lhs, Range &rhs) {
      return lhs.getOffset() < rhs.getOffset();
    });

    auto I = sorted.begin();
    while (I < sorted.end() - 1) {
      if (RangeEnd(*I) >= (*(I + 1)).getOffset()) {
        *I = Range((*I).getOffset(), RangeEnd(*(I+1)) - (*I).getOffset());
        sorted.erase(I + 1);
      } else {
        I++;
      }
    }

    return sorted;
  }

} // end anonymous namespace

namespace import_tidy {

#pragma mark - ImportMatcher

  std::unique_ptr<FrontendActionFactory>
  ImportMatcher::getActionFactory(MatchFinder& Finder) {
    auto CallMatcher = callExpr(isExpansionInMainFile()).bind(nodeKey);
    auto DeclRefMatcher = declRefExpr(isNotInSystemHeader()).bind(nodeKey);
    auto InterfaceMatcher = interfaceDecl(isImplementationInMainFile()).bind(nodeKey);
    auto ForwardDeclareMatcher = interfaceDecl(isNotInSystemHeader(), isForwardDeclare()).bind(nodeKey);
    auto ImportMatcher = importDecl(isNotInSystemHeader()).bind(nodeKey);
    auto MsgMatcher = messageExpr(isExpansionInMainFile()).bind(nodeKey);
    auto MtdMatcher = containerDecl(isNotInSystemHeader(),
                                    forEachDescendant(objcMethodDecl().bind(nodeKey)));
    auto ProtoDeclMatcher = protocolDecl(isNotInSystemHeader()).bind(nodeKey);
    auto ProtoExprMatcher = protocolExpr(isExpansionInMainFile()).bind(nodeKey);
    auto FuncDecl = functionDecl(isNotInSystemHeader()).bind(nodeKey);

    Finder.addMatcher(CallMatcher, &CallCallback);
    Finder.addMatcher(DeclRefMatcher, &DeclRefCallback);
    Finder.addMatcher(InterfaceMatcher, &InterfaceCallback);
    Finder.addMatcher(ForwardDeclareMatcher, &StripCallback);
    Finder.addMatcher(ImportMatcher, &StripCallback);
    Finder.addMatcher(MsgMatcher, &MsgCallback);
    Finder.addMatcher(MtdMatcher, &MtdCallback);
    Finder.addMatcher(ProtoExprMatcher, &ProtoCallback);
    Finder.addMatcher(ProtoDeclMatcher, &ProtoCallback);
    Finder.addMatcher(FuncDecl, &FuncDeclCallback);

    return newFrontendActionFactory(&Finder, &FileCallbacks);
  }

  void ImportMatcher::addImport(const FileID InFile,
                                const Decl *D,
                                const SourceManager &SM,
                                bool isForwardDeclare) {
    // only allow file locations
    auto Loc = getDeclLoc(D);
    if (!SM.getFileEntryForID(InFile) || SM.getFilename(Loc).size() == 0)
      return;

    // don't include files in themselves
    if (!isForwardDeclare && SM.getFileID(Loc) == InFile)
      return;

    ImportMap[InFile].push_back(Import(SM, D, isForwardDeclare));
  }

  void ImportMatcher::removeImport(const SourceLocation Loc, const SourceManager &SM) {
    auto fid = SM.getFileID(Loc);
    auto *buffer = SM.getBuffer(fid);
    auto *fileStart = buffer->getBufferStart();
    unsigned start = SM.getFileOffset(Loc);
    unsigned length = strchr(fileStart + start, '\n') - fileStart - start + 1;

    // strip any empty lines after this import
    auto *c = fileStart + start + length;
    while (isWhitespace(*c) && c++ < buffer->getBufferEnd())
      length++;

    ImportRanges[fid].push_back(Range(start, length));
  }

  // TODO: move this into ImportCallbacks as a helper function
  void ImportMatcher::addType(const FileID InFile, QualType T, const SourceManager &SM) {
    bool isMainFile = SM.getMainFileID() == InFile;

    if (auto *PT = T->getAs<ObjCObjectPointerType>()) {
      // import or forward declare the class type
      if (auto *ID = PT->getInterfaceDecl()) {
        auto Filename = SM.getFilename(ID->getLocation());
        bool isSystemDecl = Filename.startswith(getSysroot());
        addImport(InFile, ID, SM, !isSystemDecl && !isMainFile);
      }

      // import or forward declare any protocols being conformed to
      for (auto i = PT->qual_begin(); i != PT->qual_end(); i++) {
        auto Filename = SM.getFilename((*i)->getLocation());
        bool isSystemDecl = Filename.startswith(getSysroot());
        addImport(InFile, *i, SM, !isSystemDecl && !isMainFile);
      }
    } else if (auto *TD = T->getAs<TypedefType>()) {
      // any typedefs need to be imported
      if (auto *TypeDecl = TD->getDecl()) {
        addImport(InFile, TypeDecl, SM);
      }
    } else if (auto *BP = T->getAs<BlockPointerType>()) {
      // any types used in blocks need to be imported
      if (auto *FT = BP->getPointeeType()->getAs<FunctionProtoType>()) {
        addType(InFile, FT->getReturnType(), SM);
        for (auto PT : FT->param_types()) {
          addType(InFile, PT, SM);
        }
      }
    }
  }

  void ImportMatcher::addHeaderFile(const FileID FID) {
    HeaderFiles.insert(FID);
  }

  void ImportMatcher::flush(const SourceManager &SM) {
    auto &out = llvm::outs();
    HeaderFiles.insert(SM.getMainFileID());

    for (auto &Pair : ImportMap) {
      // only tidy the main file and files with interfaces
      // implemented in the main file
      if (HeaderFiles.count(Pair.first) == 0)
        continue;

      std::string import;
      llvm::raw_string_ostream ImportStr(import);
      auto Imports = sortedUniqueImports(Pair.second);
      for (auto *Import : Imports) {
        ImportStr << *Import << '\n';
        if (Import->getType() == ImportType::Library) {
          LibraryCounts[Import->getName()]++;
        }
      }
      ImportStr << '\n';

      auto Fid = Pair.first;
      auto StartLoc = SM.getLocForStartOfFile(Fid);
      auto Path = SM.getFilename(StartLoc);
      if (haveReplacementForFile(Replacements, Path))
        continue;

      auto ReplacementRanges = collapsedRanges(ImportRanges[Fid]);
      for (auto I = ReplacementRanges.cbegin(); I != ReplacementRanges.cend(); I++) {
        auto Text = I == ReplacementRanges.cbegin() ? ImportStr.str() : "";
        auto Start = StartLoc.getLocWithOffset(I->getOffset());

        Replacements.insert(Replacement(SM, Start, I->getLength(), Text));
      }

      out << "File: " << SM.getFilename(StartLoc) << "\n";
      out << ImportStr.str() << "\n";
    }
    ImportMap.clear();
    ImportRanges.clear();
    HeaderFiles.clear();
  }

  void ImportMatcher::printLibraryCounts(llvm::raw_ostream &OS) {
    using ImpPair = std::pair<StringRef, unsigned>;
    std::vector<ImpPair> counts(LibraryCounts.begin(), LibraryCounts.end());
    std::sort(counts.begin(), counts.end(), [](const ImpPair &L, const ImpPair &R) {
      return L.second < R.second;
    });

    OS << "\n\n";
    OS << "--------------------------------" << "\n";
    OS << "Libraries sorted by import count" << "\n";
    OS << "--------------------------------" << "\n";
    for (auto I = counts.rbegin(); I != counts.rend(); I++) {
      OS << I->first << " : " << I->second << " times\n";
    }
  }

} // end namespace import_tidy
<commit_msg>don't output library counts when there are none<commit_after>#include "ImportMatcher.h"
#include "clang/Basic/SourceManager.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/AST/ExprObjC.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>

using namespace clang;
using namespace clang::ast_matchers;
using namespace clang::tooling;
using namespace import_tidy;

namespace clang {
namespace ast_matchers {
  static const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr> messageExpr;
  static const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl> interfaceDecl;
  static const internal::VariadicDynCastAllOfMatcher<Decl, ObjCContainerDecl> containerDecl;
  static const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl> objcMethodDecl;
  static const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl> protocolDecl;
  static const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCProtocolExpr> protocolExpr;
  static const internal::VariadicDynCastAllOfMatcher<Decl, ImportDecl> importDecl;

  AST_MATCHER(ObjCInterfaceDecl, isImplementationInMainFile) {
    if (!Node.isThisDeclarationADefinition())
      return false;

    if (auto *ImpDecl = Node.getImplementation()) {
      auto &SourceManager = Finder->getASTContext().getSourceManager();
      return SourceManager.isInMainFile(SourceManager.getExpansionLoc(ImpDecl->getLocStart()));
    } else {
      return false;
    }
  }

  AST_MATCHER(ObjCInterfaceDecl, isForwardDeclare) {
    return !Node.isThisDeclarationADefinition();
  }

  AST_POLYMORPHIC_MATCHER(isNotInSystemHeader,
                          AST_POLYMORPHIC_SUPPORTED_TYPES_2(Decl, Stmt)) {
    auto Loc = Node.getLocation();
    if (!Loc.isValid())
      return false;

    auto &SM = Finder->getASTContext().getSourceManager();
    return !SM.isInSystemHeader(Loc);
  }

} // end namespace ast_matchers
} // end namespace clang

namespace {

  static bool haveReplacementForFile(Replacements &Replacements, StringRef Path) {
    auto Found = std::find_if(Replacements.begin(), Replacements.end(),
                              [Path](const Replacement &R) {
                                return R.getFilePath() == Path;
                              });
    return Found != Replacements.end();
  }

  unsigned RangeEnd(const Range &R) {
    return R.getOffset() + R.getLength();
  }

  static std::vector<Range> collapsedRanges(const std::vector<Range> &Ranges) {
    std::vector<Range> sorted(Ranges.begin(), Ranges.end());
    if (Ranges.size() == 0)
      return sorted;

    std::sort(sorted.begin(), sorted.end(), [](Range &lhs, Range &rhs) {
      return lhs.getOffset() < rhs.getOffset();
    });

    auto I = sorted.begin();
    while (I < sorted.end() - 1) {
      if (RangeEnd(*I) >= (*(I + 1)).getOffset()) {
        *I = Range((*I).getOffset(), RangeEnd(*(I+1)) - (*I).getOffset());
        sorted.erase(I + 1);
      } else {
        I++;
      }
    }

    return sorted;
  }

} // end anonymous namespace

namespace import_tidy {

#pragma mark - ImportMatcher

  std::unique_ptr<FrontendActionFactory>
  ImportMatcher::getActionFactory(MatchFinder& Finder) {
    auto CallMatcher = callExpr(isExpansionInMainFile()).bind(nodeKey);
    auto DeclRefMatcher = declRefExpr(isNotInSystemHeader()).bind(nodeKey);
    auto InterfaceMatcher = interfaceDecl(isImplementationInMainFile()).bind(nodeKey);
    auto ForwardDeclareMatcher = interfaceDecl(isNotInSystemHeader(), isForwardDeclare()).bind(nodeKey);
    auto ImportMatcher = importDecl(isNotInSystemHeader()).bind(nodeKey);
    auto MsgMatcher = messageExpr(isExpansionInMainFile()).bind(nodeKey);
    auto MtdMatcher = containerDecl(isNotInSystemHeader(),
                                    forEachDescendant(objcMethodDecl().bind(nodeKey)));
    auto ProtoDeclMatcher = protocolDecl(isNotInSystemHeader()).bind(nodeKey);
    auto ProtoExprMatcher = protocolExpr(isExpansionInMainFile()).bind(nodeKey);
    auto FuncDecl = functionDecl(isNotInSystemHeader()).bind(nodeKey);

    Finder.addMatcher(CallMatcher, &CallCallback);
    Finder.addMatcher(DeclRefMatcher, &DeclRefCallback);
    Finder.addMatcher(InterfaceMatcher, &InterfaceCallback);
    Finder.addMatcher(ForwardDeclareMatcher, &StripCallback);
    Finder.addMatcher(ImportMatcher, &StripCallback);
    Finder.addMatcher(MsgMatcher, &MsgCallback);
    Finder.addMatcher(MtdMatcher, &MtdCallback);
    Finder.addMatcher(ProtoExprMatcher, &ProtoCallback);
    Finder.addMatcher(ProtoDeclMatcher, &ProtoCallback);
    Finder.addMatcher(FuncDecl, &FuncDeclCallback);

    return newFrontendActionFactory(&Finder, &FileCallbacks);
  }

  void ImportMatcher::addImport(const FileID InFile,
                                const Decl *D,
                                const SourceManager &SM,
                                bool isForwardDeclare) {
    // only allow file locations
    auto Loc = getDeclLoc(D);
    if (!SM.getFileEntryForID(InFile) || SM.getFilename(Loc).size() == 0)
      return;

    // don't include files in themselves
    if (!isForwardDeclare && SM.getFileID(Loc) == InFile)
      return;

    ImportMap[InFile].push_back(Import(SM, D, isForwardDeclare));
  }

  void ImportMatcher::removeImport(const SourceLocation Loc, const SourceManager &SM) {
    auto fid = SM.getFileID(Loc);
    auto *buffer = SM.getBuffer(fid);
    auto *fileStart = buffer->getBufferStart();
    unsigned start = SM.getFileOffset(Loc);
    unsigned length = strchr(fileStart + start, '\n') - fileStart - start + 1;

    // strip any empty lines after this import
    auto *c = fileStart + start + length;
    while (isWhitespace(*c) && c++ < buffer->getBufferEnd())
      length++;

    ImportRanges[fid].push_back(Range(start, length));
  }

  // TODO: move this into ImportCallbacks as a helper function
  void ImportMatcher::addType(const FileID InFile, QualType T, const SourceManager &SM) {
    bool isMainFile = SM.getMainFileID() == InFile;

    if (auto *PT = T->getAs<ObjCObjectPointerType>()) {
      // import or forward declare the class type
      if (auto *ID = PT->getInterfaceDecl()) {
        auto Filename = SM.getFilename(ID->getLocation());
        bool isSystemDecl = Filename.startswith(getSysroot());
        addImport(InFile, ID, SM, !isSystemDecl && !isMainFile);
      }

      // import or forward declare any protocols being conformed to
      for (auto i = PT->qual_begin(); i != PT->qual_end(); i++) {
        auto Filename = SM.getFilename((*i)->getLocation());
        bool isSystemDecl = Filename.startswith(getSysroot());
        addImport(InFile, *i, SM, !isSystemDecl && !isMainFile);
      }
    } else if (auto *TD = T->getAs<TypedefType>()) {
      // any typedefs need to be imported
      if (auto *TypeDecl = TD->getDecl()) {
        addImport(InFile, TypeDecl, SM);
      }
    } else if (auto *BP = T->getAs<BlockPointerType>()) {
      // any types used in blocks need to be imported
      if (auto *FT = BP->getPointeeType()->getAs<FunctionProtoType>()) {
        addType(InFile, FT->getReturnType(), SM);
        for (auto PT : FT->param_types()) {
          addType(InFile, PT, SM);
        }
      }
    }
  }

  void ImportMatcher::addHeaderFile(const FileID FID) {
    HeaderFiles.insert(FID);
  }

  void ImportMatcher::flush(const SourceManager &SM) {
    auto &out = llvm::outs();
    HeaderFiles.insert(SM.getMainFileID());

    for (auto &Pair : ImportMap) {
      // only tidy the main file and files with interfaces
      // implemented in the main file
      if (HeaderFiles.count(Pair.first) == 0)
        continue;

      std::string import;
      llvm::raw_string_ostream ImportStr(import);
      auto Imports = sortedUniqueImports(Pair.second);
      for (auto *Import : Imports) {
        ImportStr << *Import << '\n';
        if (Import->getType() == ImportType::Library) {
          LibraryCounts[Import->getName()]++;
        }
      }
      ImportStr << '\n';

      auto Fid = Pair.first;
      auto StartLoc = SM.getLocForStartOfFile(Fid);
      auto Path = SM.getFilename(StartLoc);
      if (haveReplacementForFile(Replacements, Path))
        continue;

      auto ReplacementRanges = collapsedRanges(ImportRanges[Fid]);
      for (auto I = ReplacementRanges.cbegin(); I != ReplacementRanges.cend(); I++) {
        auto Text = I == ReplacementRanges.cbegin() ? ImportStr.str() : "";
        auto Start = StartLoc.getLocWithOffset(I->getOffset());

        Replacements.insert(Replacement(SM, Start, I->getLength(), Text));
      }

      out << "File: " << SM.getFilename(StartLoc) << "\n";
      out << ImportStr.str() << "\n";
    }
    ImportMap.clear();
    ImportRanges.clear();
    HeaderFiles.clear();
  }

  void ImportMatcher::printLibraryCounts(llvm::raw_ostream &OS) {
    if (LibraryCounts.size() == 0)
      return;

    using ImpPair = std::pair<StringRef, unsigned>;
    std::vector<ImpPair> counts(LibraryCounts.begin(), LibraryCounts.end());
    std::sort(counts.begin(), counts.end(), [](const ImpPair &L, const ImpPair &R) {
      return L.second < R.second;
    });

    OS << "\n\n";
    OS << "--------------------------------" << "\n";
    OS << "Libraries sorted by import count" << "\n";
    OS << "--------------------------------" << "\n";
    for (auto I = counts.rbegin(); I != counts.rend(); I++) {
      OS << I->first << " : " << I->second << " times\n";
    }
  }

} // end namespace import_tidy
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/automated_ui_tests/automated_ui_test_base.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"

TEST_F(AutomatedUITestBase, NewTab) {
  int tab_count;
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  NewTab();
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(2, tab_count);
  NewTab();
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(3, tab_count);
}

TEST_F(AutomatedUITestBase, DuplicateTab) {
  int tab_count;
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  DuplicateTab();
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(2, tab_count);
  DuplicateTab();
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(3, tab_count);
}

TEST_F(AutomatedUITestBase, OpenNewBrowserWindow) {
  int num_browser_windows;
  int tab_count;
  automation()->GetBrowserWindowCount(&num_browser_windows);
  ASSERT_EQ(1, num_browser_windows);
  scoped_ptr<BrowserProxy>browser_1(release_active_browser());
  browser_1->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);

  ASSERT_TRUE(OpenAndActivateNewBrowserWindow());
  automation()->GetBrowserWindowCount(&num_browser_windows);
  ASSERT_EQ(2, num_browser_windows);
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  NewTab();
  scoped_ptr<BrowserProxy>browser_2(release_active_browser());
  browser_1->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  browser_2->GetTabCount(&tab_count);
  ASSERT_EQ(2, tab_count);

  ASSERT_TRUE(OpenAndActivateNewBrowserWindow());
  automation()->GetBrowserWindowCount(&num_browser_windows);
  ASSERT_EQ(3, num_browser_windows);
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  NewTab();
  NewTab();
  scoped_ptr<BrowserProxy>browser_3(release_active_browser());
  browser_1->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  browser_2->GetTabCount(&tab_count);
  ASSERT_EQ(2, tab_count);
  browser_3->GetTabCount(&tab_count);
  ASSERT_EQ(3, tab_count);
}
<commit_msg>Disable flakey OpenNewBrowserWindow test.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/automated_ui_tests/automated_ui_test_base.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"

TEST_F(AutomatedUITestBase, NewTab) {
  int tab_count;
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  NewTab();
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(2, tab_count);
  NewTab();
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(3, tab_count);
}

TEST_F(AutomatedUITestBase, DuplicateTab) {
  int tab_count;
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  DuplicateTab();
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(2, tab_count);
  DuplicateTab();
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(3, tab_count);
}

// TODO(huanr) mmoss disabled this test because it's crashing periodically on
// the buildbots and not giving useful debugging info.
TEST_F(AutomatedUITestBase, DISABLED_OpenNewBrowserWindow) {
  int num_browser_windows;
  int tab_count;
  automation()->GetBrowserWindowCount(&num_browser_windows);
  ASSERT_EQ(1, num_browser_windows);
  scoped_ptr<BrowserProxy>browser_1(release_active_browser());
  browser_1->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);

  ASSERT_TRUE(OpenAndActivateNewBrowserWindow());
  automation()->GetBrowserWindowCount(&num_browser_windows);
  ASSERT_EQ(2, num_browser_windows);
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  NewTab();
  scoped_ptr<BrowserProxy>browser_2(release_active_browser());
  browser_1->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  browser_2->GetTabCount(&tab_count);
  ASSERT_EQ(2, tab_count);

  ASSERT_TRUE(OpenAndActivateNewBrowserWindow());
  automation()->GetBrowserWindowCount(&num_browser_windows);
  ASSERT_EQ(3, num_browser_windows);
  active_browser()->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  NewTab();
  NewTab();
  scoped_ptr<BrowserProxy>browser_3(release_active_browser());
  browser_1->GetTabCount(&tab_count);
  ASSERT_EQ(1, tab_count);
  browser_2->GetTabCount(&tab_count);
  ASSERT_EQ(2, tab_count);
  browser_3->GetTabCount(&tab_count);
  ASSERT_EQ(3, tab_count);
}
<|endoftext|>


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

#include "dl_loader.h"
#include "log.h"
#include "target.h"

#if TARGET_OS == GAPID_OS_WINDOWS
#   include <windows.h>
#elif TARGET_OS == GAPID_OS_OSX
#   include <dlfcn.h>
#   include <unistd.h>
#else
#   include <dlfcn.h>
#endif

namespace {

// load defs
void* load(const char* name) {
#if TARGET_OS == GAPID_OS_WINDOWS
    return reinterpret_cast<void*>(LoadLibraryExA(name, NULL, 0));
#elif TARGET_OS == GAPID_OS_OSX
    if (name == nullptr) {
        return nullptr;
    }
    // DYLD_FRAMEWORK_PATH takes precedence even with absolute paths.
    // Use a symlink to get to the real library.
    // Credit to apitrace (https://github.com/apitrace) for this nasty, but
    // effective work-around.
    // TODO: not thread-safe.
    void* res = nullptr;
    char tmp[] = "/tmp/dlopen.XXXXXX";
    if (mktemp(tmp) != nullptr) {
        if (symlink(name, tmp) == 0) {
            res = dlopen(tmp, RTLD_NOW | RTLD_LOCAL | RTLD_FIRST);
            remove(tmp);
        }
    }
    return res;
#else
    return dlopen(name, RTLD_NOW | RTLD_LOCAL);
#endif // TARGET_OS
}

void* must_load(const char* name) {
  void* res = load(name);
  if (res == nullptr) {
#if TARGET_OS == GAPID_OS_WINDOWS
    GAPID_FATAL("Can't load library %s: %d", name, GetLastError());
#else
    GAPID_FATAL("Can't load library %s: %s", name, dlerror());
#endif // TARGET_OS
  }
  return res;
}

// resolve defs
#if TARGET_OS ==  GAPID_OS_WINDOWS
void* resolve(void* handle, const char* name) {
    return reinterpret_cast<void*>(GetProcAddress(reinterpret_cast<HMODULE>(handle), name));
}
#else // TARGET_OS
void* resolve(void* handle, const char* name) {
    return dlsym(handle, name);
}
#endif // TARGET_OS

// close defs
#if TARGET_OS == GAPID_OS_WINDOWS
void close(void* lib) {
    if (lib != nullptr) {
        FreeLibrary(reinterpret_cast<HMODULE>(lib));
    }
}
#else // TARGET_OS
void close(void* lib) {
    if (lib != nullptr) {
        dlclose(lib);
    }
}
#endif // TARGET_OS

}  // anonymous namespace

namespace core {

DlLoader::DlLoader(const char* name) : mLibrary(must_load(name)) {}

DlLoader::~DlLoader() {
    close(mLibrary);
}

#if TARGET_OS == GAPID_OS_WINDOWS
void* DlLoader::lookup(const char* name) {
    return resolve(mLibrary, name);
}
#else  // TARGET_OS
void* DlLoader::lookup(const char* name) {
    return resolve((mLibrary ? mLibrary : RTLD_DEFAULT), name);
}
#endif  // TARGET_OS

bool DlLoader::can_load(const char* lib_name) {
  if (void* lib = load(lib_name)) {
    close(lib);
    return true;
  }
  return false;
}

}  // namespace core
<commit_msg>gapir: Fix crash on gles replay<commit_after>/*
 * Copyright (C) 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "dl_loader.h"
#include "log.h"
#include "target.h"

#if TARGET_OS == GAPID_OS_WINDOWS
#   include <windows.h>
#elif TARGET_OS == GAPID_OS_OSX
#   include <dlfcn.h>
#   include <unistd.h>
#else
#   include <dlfcn.h>
#endif

namespace {

// load defs
void* load(const char* name) {
#if TARGET_OS == GAPID_OS_WINDOWS
    return reinterpret_cast<void*>(LoadLibraryExA(name, NULL, 0));
#elif TARGET_OS == GAPID_OS_OSX
    if (name == nullptr) {
        return nullptr;
    }
    // DYLD_FRAMEWORK_PATH takes precedence even with absolute paths.
    // Use a symlink to get to the real library.
    // Credit to apitrace (https://github.com/apitrace) for this nasty, but
    // effective work-around.
    // TODO: not thread-safe.
    void* res = nullptr;
    char tmp[] = "/tmp/dlopen.XXXXXX";
    if (mktemp(tmp) != nullptr) {
        if (symlink(name, tmp) == 0) {
            res = dlopen(tmp, RTLD_NOW | RTLD_LOCAL | RTLD_FIRST);
            remove(tmp);
        }
    }
    return res;
#else
    return dlopen(name, RTLD_NOW | RTLD_LOCAL);
#endif // TARGET_OS
}

void* must_load(const char* name) {
  void* res = load(name);
  if (res == nullptr) {
#if TARGET_OS == GAPID_OS_WINDOWS
    GAPID_FATAL("Can't load library %s: %d", name, GetLastError());
#else
    if (name != nullptr) {
        GAPID_FATAL("Can't load library %s: %s", name, dlerror());
    }
#endif // TARGET_OS
  }
  return res;
}

// resolve defs
#if TARGET_OS ==  GAPID_OS_WINDOWS
void* resolve(void* handle, const char* name) {
    return reinterpret_cast<void*>(GetProcAddress(reinterpret_cast<HMODULE>(handle), name));
}
#else // TARGET_OS
void* resolve(void* handle, const char* name) {
    return dlsym(handle, name);
}
#endif // TARGET_OS

// close defs
#if TARGET_OS == GAPID_OS_WINDOWS
void close(void* lib) {
    if (lib != nullptr) {
        FreeLibrary(reinterpret_cast<HMODULE>(lib));
    }
}
#else // TARGET_OS
void close(void* lib) {
    if (lib != nullptr) {
        dlclose(lib);
    }
}
#endif // TARGET_OS

}  // anonymous namespace

namespace core {

DlLoader::DlLoader(const char* name) : mLibrary(must_load(name)) {}

DlLoader::~DlLoader() {
    close(mLibrary);
}

#if TARGET_OS == GAPID_OS_WINDOWS
void* DlLoader::lookup(const char* name) {
    return resolve(mLibrary, name);
}
#else  // TARGET_OS
void* DlLoader::lookup(const char* name) {
    return resolve((mLibrary ? mLibrary : RTLD_DEFAULT), name);
}
#endif  // TARGET_OS

bool DlLoader::can_load(const char* lib_name) {
  if (void* lib = load(lib_name)) {
    close(lib);
    return true;
  }
  return false;
}

}  // namespace core
<|endoftext|>


<commit_before>// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2014 A3Wasteland.com *
// ******************************************************************************************
#include "genstoreDefines.sqf"

#define GenStoreButton_textSize (0.04 * TEXT_SCALE)

class genstored
{
	idd = genstore_DIALOG;
	movingEnable = true;
	enableSimulation = true;
	onLoad = "[0] execVM 'client\systems\generalStore\populateGenStore.sqf'";

	class ControlsBackground
	{
		#define GenStoreMainBG_W (0.7333 * SZ_SCALE)
		#define GenStoreMainBG_H (0.65 * SZ_SCALE)
		#define GenStoreMainBG_X CENTER(1, GenStoreMainBG_W)
		#define GenStoreMainBG_Y CENTER(1, GenStoreMainBG_H)

		class MainBackground: IGUIBack
		{
			idc = -1;
			colorBackground[] = {0, 0, 0, 0.6};
			moving = true;

			x = GenStoreMainBG_X;
			y = GenStoreMainBG_Y;
			w = GenStoreMainBG_W;
			h = GenStoreMainBG_H;
		};

		class TopBar: IGUIBack
		{
			idc = -1;
			colorBackground[] = {0.25, 0.51, 0.96, 0.8};

			#define GenStoreTopBar_H (0.05 * SZ_SCALE)

			x = GenStoreMainBG_X;
			y = GenStoreMainBG_Y;
			w = GenStoreMainBG_W;
			h = GenStoreTopBar_H;
		};

		class DialogTitleText: w_RscTextCenter
		{
			idc = -1;
			text = "General Store";
			sizeEx = 0.06 * TEXT_SCALE;

			x = GenStoreMainBG_X;
			y = GenStoreMainBG_Y;
			w = GenStoreMainBG_W;
			h = GenStoreTopBar_H;
		};

		/*
		class PlayerMoneyText: w_RscText
		{
			idc = genstore_money;
			text = "Cash:";
			sizeEx = 0.04 * TEXT_SCALE;

			x = GenStoreMainBG_X + (0.6033 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.005 * SZ_SCALE);
			w = 0.1126 * SZ_SCALE;
			h = 0.0448 * SZ_SCALE;
		};
		*/

		class ItemSelectedPrice: w_RscStructuredTextLeft
		{
			idc = genstore_item_TEXT;
			size = 0.04 * TEXT_SCALE;

			x = GenStoreMainBG_X + (0.15 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.514 * SZ_SCALE);
			w = 0.119 * SZ_SCALE;
			h = 0.0689 * SZ_SCALE;
		};

		class SellSelectedPrice: w_RscStructuredTextLeft
		{
			idc = genstore_sell_TEXT;
			size = 0.04 * TEXT_SCALE;

			x = GenStoreMainBG_X + (0.439 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.514 * SZ_SCALE);
			w = 0.119 * SZ_SCALE;
			h = 0.0689 * SZ_SCALE;
		};
	};

	class Controls
	{
		class SelectionList: w_RscList
		{
			idc = genstore_item_list;
			onLBSelChanged = "[] execVM 'client\systems\generalStore\itemInfo.sqf'";
			sizeEx = 0.04 * TEXT_SCALE;
			rowHeight = 0.04 * TEXT_SCALE;

			x = GenStoreMainBG_X + (0.1533 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.075 * SZ_SCALE);
			w = 0.276 * SZ_SCALE;
			h = 0.3382 * SZ_SCALE;
		};

		class ItemDescription: w_RscStructuredTextLeft
		{
			idc = genstore_item_desc;
			size = 0.04 * TEXT_SCALE;
			colorBackground[] = {0, 0, 0, 0.3};

			x = GenStoreMainBG_X + (0.1533 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.417 * SZ_SCALE);
			w = 0.276 * SZ_SCALE;
			h = 0.088 * SZ_SCALE;
		};

		class SellList: w_RscList
		{
			idc = genstore_sell_list;
			onLBSelChanged = "[] execVM 'client\systems\generalStore\sellInfo.sqf'";
			sizeEx = 0.04 * TEXT_SCALE;
			rowHeight = 0.04 * TEXT_SCALE;

			x = GenStoreMainBG_X + (0.4433 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.075 * SZ_SCALE);
			w = 0.276 * SZ_SCALE;
			h = 0.4222 * SZ_SCALE;
		};

		class BuyItem: w_RscButton
		{
			idc = -1;
			onButtonClick = "[0] execVM 'client\systems\generalStore\buyItems.sqf'";
			text = "Buy";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.334 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.507 * SZ_SCALE);
			w = 0.096 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class SellItem: w_RscButton
		{
			idc = genstore_sell;
			onButtonClick = "[0] execVM 'client\systems\generalStore\sellItems.sqf'";
			text = "Sell";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.6233 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.507 * SZ_SCALE);
			w = 0.096 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton0: w_RscButton
		{
			idc = -1;
			onButtonClick = "[0] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Headgear";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.075 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton1: w_RscButton
		{
			idc = -1;
			onButtonClick = "[1] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Uniforms";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.125 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton2: w_RscButton
		{
			idc = -1;
			onButtonClick = "[2] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Vests";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.175 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton3: w_RscButton
		{
			idc = -1;
			onButtonClick = "[3] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Backpacks";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.225 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton4: w_RscButton
		{
			idc = -1;
			onButtonClick = "[4] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Items";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.275 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton5: w_RscButton
		{
			idc = -1;
			onButtonClick = "[5] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Supplies";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.325 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton6: w_RscButton
		{
			idc = -1;
			onButtonClick = "[6] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Objects";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.375 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class SellWeapon: w_RscButton
		{
			idc = -1;
			onButtonClick = "[] execVM 'client\systems\selling\sellWeapon.sqf'";
			text = "Sell Weapon";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.23 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.59 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class SellUniform: w_RscButton
		{
			idc = -1;
			onButtonClick = "[] execVM 'client\systems\selling\sellUniform.sqf'";
			text = "Sell Uniform";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + ((0.604 - 0.25) * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.59 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class SellVest: w_RscButton
		{
			idc = -1;
			onButtonClick = "[] execVM 'client\systems\selling\sellVest.sqf'";
			text = "Sell Vest";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.478 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.59 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class SellBackpack: w_RscButton
		{
			idc = -1;
			onButtonClick = "[] execVM 'client\systems\selling\sellBackpack.sqf'";
			text = "Sell Backpack";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.602 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.59 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class CancelButton: w_RscButton
		{
			idc = -1;
			onButtonClick = "closeDialog 0";
			text = "Cancel";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.59 * SZ_SCALE);
			w = 0.096 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};
	};
};

<commit_msg>Update genstore_settings.hpp<commit_after>// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2014 A3Wasteland.com *
// ******************************************************************************************
#include "genstoreDefines.sqf"

#define GenStoreButton_textSize (0.04 * TEXT_SCALE)

class genstored
{
	idd = genstore_DIALOG;
	movingEnable = true;
	enableSimulation = true;
	onLoad = "[0] execVM 'client\systems\generalStore\populateGenStore.sqf'";

	class ControlsBackground
	{
		#define GenStoreMainBG_W (0.7333 * SZ_SCALE)
		#define GenStoreMainBG_H (0.65 * SZ_SCALE)
		#define GenStoreMainBG_X CENTER(1, GenStoreMainBG_W)
		#define GenStoreMainBG_Y CENTER(1, GenStoreMainBG_H)

		class MainBackground: IGUIBack
		{
			idc = -1;
			colorBackground[] = {0, 0, 0, 0.6};
			moving = true;

			x = GenStoreMainBG_X;
			y = GenStoreMainBG_Y;
			w = GenStoreMainBG_W;
			h = GenStoreMainBG_H;
		};

		class TopBar: IGUIBack
		{
			idc = -1;
			colorBackground[] = {0.25, 0.51, 0.96, 0.8};

			#define GenStoreTopBar_H (0.05 * SZ_SCALE)

			x = GenStoreMainBG_X;
			y = GenStoreMainBG_Y;
			w = GenStoreMainBG_W;
			h = GenStoreTopBar_H;
		};

		class DialogTitleText: w_RscTextCenter
		{
			idc = -1;
			text = "Objetos generales";
			sizeEx = 0.06 * TEXT_SCALE;

			x = GenStoreMainBG_X;
			y = GenStoreMainBG_Y;
			w = GenStoreMainBG_W;
			h = GenStoreTopBar_H;
		};

		/*
		class PlayerMoneyText: w_RscText
		{
			idc = genstore_money;
			text = "Cash:";
			sizeEx = 0.04 * TEXT_SCALE;

			x = GenStoreMainBG_X + (0.6033 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.005 * SZ_SCALE);
			w = 0.1126 * SZ_SCALE;
			h = 0.0448 * SZ_SCALE;
		};
		*/

		class ItemSelectedPrice: w_RscStructuredTextLeft
		{
			idc = genstore_item_TEXT;
			size = 0.04 * TEXT_SCALE;

			x = GenStoreMainBG_X + (0.15 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.514 * SZ_SCALE);
			w = 0.119 * SZ_SCALE;
			h = 0.0689 * SZ_SCALE;
		};

		class SellSelectedPrice: w_RscStructuredTextLeft
		{
			idc = genstore_sell_TEXT;
			size = 0.04 * TEXT_SCALE;

			x = GenStoreMainBG_X + (0.439 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.514 * SZ_SCALE);
			w = 0.119 * SZ_SCALE;
			h = 0.0689 * SZ_SCALE;
		};
	};

	class Controls
	{
		class SelectionList: w_RscList
		{
			idc = genstore_item_list;
			onLBSelChanged = "[] execVM 'client\systems\generalStore\itemInfo.sqf'";
			sizeEx = 0.04 * TEXT_SCALE;
			rowHeight = 0.04 * TEXT_SCALE;

			x = GenStoreMainBG_X + (0.1533 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.075 * SZ_SCALE);
			w = 0.276 * SZ_SCALE;
			h = 0.3382 * SZ_SCALE;
		};

		class ItemDescription: w_RscStructuredTextLeft
		{
			idc = genstore_item_desc;
			size = 0.04 * TEXT_SCALE;
			colorBackground[] = {0, 0, 0, 0.3};

			x = GenStoreMainBG_X + (0.1533 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.417 * SZ_SCALE);
			w = 0.276 * SZ_SCALE;
			h = 0.088 * SZ_SCALE;
		};

		class SellList: w_RscList
		{
			idc = genstore_sell_list;
			onLBSelChanged = "[] execVM 'client\systems\generalStore\sellInfo.sqf'";
			sizeEx = 0.04 * TEXT_SCALE;
			rowHeight = 0.04 * TEXT_SCALE;

			x = GenStoreMainBG_X + (0.4433 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.075 * SZ_SCALE);
			w = 0.276 * SZ_SCALE;
			h = 0.4222 * SZ_SCALE;
		};

		class BuyItem: w_RscButton
		{
			idc = -1;
			onButtonClick = "[0] execVM 'client\systems\generalStore\buyItems.sqf'";
			text = "Buy";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.334 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.507 * SZ_SCALE);
			w = 0.096 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class SellItem: w_RscButton
		{
			idc = genstore_sell;
			onButtonClick = "[0] execVM 'client\systems\generalStore\sellItems.sqf'";
			text = "Sell";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.6233 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.507 * SZ_SCALE);
			w = 0.096 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton0: w_RscButton
		{
			idc = -1;
			onButtonClick = "[0] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Headgear";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.075 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton1: w_RscButton
		{
			idc = -1;
			onButtonClick = "[1] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Uniforms";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.125 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton2: w_RscButton
		{
			idc = -1;
			onButtonClick = "[2] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Chalecos";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.175 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton3: w_RscButton
		{
			idc = -1;
			onButtonClick = "[3] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Mochilas";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.225 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton4: w_RscButton
		{
			idc = -1;
			onButtonClick = "[4] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Objetos";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.275 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton5: w_RscButton
		{
			idc = -1;
			onButtonClick = "[5] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Suministros";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.325 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class StoreButton6: w_RscButton
		{
			idc = -1;
			onButtonClick = "[6] execVM 'client\systems\generalStore\populateGenStore.sqf'";
			text = "Útiles";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.375 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class SellWeapon: w_RscButton
		{
			idc = -1;
			onButtonClick = "[] execVM 'client\systems\selling\sellWeapon.sqf'";
			text = "Vender arma";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.23 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.59 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class SellUniform: w_RscButton
		{
			idc = -1;
			onButtonClick = "[] execVM 'client\systems\selling\sellUniform.sqf'";
			text = "Vender uniforme";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + ((0.604 - 0.25) * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.59 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class SellVest: w_RscButton
		{
			idc = -1;
			onButtonClick = "[] execVM 'client\systems\selling\sellVest.sqf'";
			text = "Vender chaleco";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.478 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.59 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class SellBackpack: w_RscButton
		{
			idc = -1;
			onButtonClick = "[] execVM 'client\systems\selling\sellBackpack.sqf'";
			text = "Vender mochila";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.602 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.59 * SZ_SCALE);
			w = 0.1173 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};

		class CancelButton: w_RscButton
		{
			idc = -1;
			onButtonClick = "closeDialog 0";
			text = "Cancelar";
			sizeEx = GenStoreButton_textSize;

			x = GenStoreMainBG_X + (0.0167 * SZ_SCALE);
			y = GenStoreMainBG_Y + (0.59 * SZ_SCALE);
			w = 0.096 * SZ_SCALE;
			h = 0.040 * SZ_SCALE;
		};
	};
};

<|endoftext|>


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

#include "FreeLookCameraComponent.hpp"

#include "Mathematics/Transformation_apply.hpp"
#include "Mathematics/Transformation_operators.hpp"
#include "Mathematics/Transformation_rotation.hpp"
#include "Mathematics/Transformation_inverse.hpp"
#include "Mathematics/Transformation_translation.hpp"
#include "Mathematics/Vector2Ops.hpp"
#include "Mathematics/Vector3Ops.hpp"
#include "Mathematics/Point3Ops.hpp"
#include "Mathematics/normalize.hpp"
#include "Simulation/Input.hpp"
#include "Simulation/Simulation.hpp"

using namespace crimild;

void FreeLookCameraComponent::start( void )
{
    _lastMousePos = Vector2::Constants::ZERO;

    registerMessageHandler< crimild::messaging::KeyPressed >(
        [ & ]( crimild::messaging::KeyPressed const &msg ) {
            if ( !isEnabled() ) {
                return;
            }

            float cameraAxisCoeff = 5.0f;

            if ( Input::getInstance()->isKeyDown( CRIMILD_INPUT_KEY_LEFT_SHIFT ) || Input::getInstance()->isKeyDown( CRIMILD_INPUT_KEY_RIGHT_SHIFT ) ) {
                cameraAxisCoeff = 20.0f;
            }

            switch ( msg.key ) {
                case 'A':
                case CRIMILD_INPUT_KEY_LEFT:
                    Input::getInstance()->setAxis( Input::AXIS_HORIZONTAL, -cameraAxisCoeff );
                    break;

                case 'D':
                case CRIMILD_INPUT_KEY_RIGHT:
                    Input::getInstance()->setAxis( Input::AXIS_HORIZONTAL, +cameraAxisCoeff );
                    break;

                case 'W':
                case CRIMILD_INPUT_KEY_UP:
                    Input::getInstance()->setAxis( Input::AXIS_VERTICAL, +cameraAxisCoeff );
                    break;

                case 'S':
                case CRIMILD_INPUT_KEY_DOWN:
                    Input::getInstance()->setAxis( Input::AXIS_VERTICAL, -cameraAxisCoeff );
                    break;

                case 'Q':
                    Input::getInstance()->setAxis( "CameraAxisRoll", -cameraAxisCoeff );
                    break;

                case 'E':
                    Input::getInstance()->setAxis( "CameraAxisRoll", +cameraAxisCoeff );
                    break;
            }
        } );

    registerMessageHandler< crimild::messaging::KeyReleased >(
        [ & ]( crimild::messaging::KeyReleased const &msg ) {
            if ( !isEnabled() ) {
                return;
            }

            switch ( msg.key ) {
                case 'A':
                case 'D':
                case CRIMILD_INPUT_KEY_LEFT:
                case CRIMILD_INPUT_KEY_RIGHT:
                    Input::getInstance()->setAxis( Input::AXIS_HORIZONTAL, 0.0f );
                    break;

                case 'W':
                case CRIMILD_INPUT_KEY_UP:
                case 'S':
                case CRIMILD_INPUT_KEY_DOWN:
                    Input::getInstance()->setAxis( Input::AXIS_VERTICAL, 0.0f );
                    break;

                case 'Q':
                case 'E':
                    Input::getInstance()->setAxis( "CameraAxisRoll", 0.0f );
                    break;
            }
        } );

    registerMessageHandler< crimild::messaging::MouseMotion >(
        [ & ]( crimild::messaging::MouseMotion const &msg ) {
            if ( !isEnabled() ) {
                return;
            }

            auto currentPos = Vector2 { msg.nx, msg.ny };
            auto mouseDelta = _initialized ? currentPos - _lastMousePos : Vector2f::Constants::ZERO;
            _initialized = true;
            _lastMousePos = currentPos;

            if ( Input::getInstance()->isMouseButtonDown( CRIMILD_INPUT_MOUSE_BUTTON_LEFT ) ) {
            	m_pitch -= mouseDelta[ 1 ];
             	m_yaw -= mouseDelta[ 0 ];
            }
        } );

    m_position = location( getNode()->getLocal() );
}

void FreeLookCameraComponent::update( const Clock &c )
{
    if ( Input::getInstance()->isMouseButtonDown( CRIMILD_INPUT_MOUSE_BUTTON_LEFT ) ) {
        Input::getInstance()->setMouseCursorMode( Input::MouseCursorMode::GRAB );
    } else {
        Input::getInstance()->setMouseCursorMode( Input::MouseCursorMode::NORMAL );
    }

    float dSpeed = getSpeed() * Input::getInstance()->getAxis( Input::AXIS_VERTICAL );
    float rSpeed = getSpeed() * Input::getInstance()->getAxis( Input::AXIS_HORIZONTAL );
    float zSpeed = getSpeed() * Input::getInstance()->getAxis( "CameraAxisRoll" );

    m_roll += 0.005f * zSpeed;

    auto root = getNode();

    const auto pitch = rotationX( m_pitch );
    const auto yaw = rotationY( m_yaw );
    const auto roll = rotationZ( m_roll );

    const auto E = yaw * pitch * roll;

    const auto F = forward( E );
    const auto R = right( E );

	m_position = m_position + c.getDeltaTime() * ( dSpeed * F + rSpeed * R );
	const auto T = translation( vector3( m_position ) );

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

#include "FreeLookCameraComponent.hpp"

#include "Mathematics/Point3Ops.hpp"
#include "Mathematics/Transformation_apply.hpp"
#include "Mathematics/Transformation_inverse.hpp"
#include "Mathematics/Transformation_operators.hpp"
#include "Mathematics/Transformation_rotation.hpp"
#include "Mathematics/Transformation_translation.hpp"
#include "Mathematics/Vector2Ops.hpp"
#include "Mathematics/Vector3Ops.hpp"
#include "Mathematics/normalize.hpp"
#include "Simulation/Input.hpp"
#include "Simulation/Simulation.hpp"

using namespace crimild;

void FreeLookCameraComponent::start( void )
{
    _lastMousePos = Vector2::Constants::ZERO;

    registerMessageHandler< crimild::messaging::KeyPressed >(
        [ & ]( crimild::messaging::KeyPressed const &msg ) {
            if ( !isEnabled() ) {
                return;
            }

            float cameraAxisCoeff = 5.0f;

            if ( Input::getInstance()->isKeyDown( CRIMILD_INPUT_KEY_LEFT_SHIFT ) || Input::getInstance()->isKeyDown( CRIMILD_INPUT_KEY_RIGHT_SHIFT ) ) {
                cameraAxisCoeff = 20.0f;
            }

            switch ( msg.key ) {
                case 'A':
                case CRIMILD_INPUT_KEY_LEFT:
                    Input::getInstance()->setAxis( Input::AXIS_HORIZONTAL, -cameraAxisCoeff );
                    break;

                case 'D':
                case CRIMILD_INPUT_KEY_RIGHT:
                    Input::getInstance()->setAxis( Input::AXIS_HORIZONTAL, +cameraAxisCoeff );
                    break;

                case 'W':
                case CRIMILD_INPUT_KEY_UP:
                    Input::getInstance()->setAxis( Input::AXIS_VERTICAL, +cameraAxisCoeff );
                    break;

                case 'S':
                case CRIMILD_INPUT_KEY_DOWN:
                    Input::getInstance()->setAxis( Input::AXIS_VERTICAL, -cameraAxisCoeff );
                    break;

                case 'Q':
                    Input::getInstance()->setAxis( "CameraAxisRoll", -cameraAxisCoeff );
                    break;

                case 'E':
                    Input::getInstance()->setAxis( "CameraAxisRoll", +cameraAxisCoeff );
                    break;
            }
        } );

    registerMessageHandler< crimild::messaging::KeyReleased >(
        [ & ]( crimild::messaging::KeyReleased const &msg ) {
            if ( !isEnabled() ) {
                return;
            }

            switch ( msg.key ) {
                case 'A':
                case 'D':
                case CRIMILD_INPUT_KEY_LEFT:
                case CRIMILD_INPUT_KEY_RIGHT:
                    Input::getInstance()->setAxis( Input::AXIS_HORIZONTAL, 0.0f );
                    break;

                case 'W':
                case CRIMILD_INPUT_KEY_UP:
                case 'S':
                case CRIMILD_INPUT_KEY_DOWN:
                    Input::getInstance()->setAxis( Input::AXIS_VERTICAL, 0.0f );
                    break;

                case 'Q':
                case 'E':
                    Input::getInstance()->setAxis( "CameraAxisRoll", 0.0f );
                    break;
            }
        } );

    registerMessageHandler< crimild::messaging::MouseMotion >(
        [ & ]( crimild::messaging::MouseMotion const &msg ) {
            if ( !isEnabled() ) {
                return;
            }

            auto currentPos = Vector2 { msg.nx, msg.ny };
            auto mouseDelta = _initialized ? currentPos - _lastMousePos : Vector2f::Constants::ZERO;
            _initialized = true;
            _lastMousePos = currentPos;

            if ( Input::getInstance()->isMouseButtonDown( CRIMILD_INPUT_MOUSE_BUTTON_LEFT ) ) {
                m_pitch -= mouseDelta[ 1 ];
                m_yaw -= mouseDelta[ 0 ];
            }
        } );

    m_position = location( getNode()->getLocal() );
}

void FreeLookCameraComponent::update( const Clock &c )
{
    if ( Input::getInstance()->isMouseButtonDown( CRIMILD_INPUT_MOUSE_BUTTON_LEFT ) ) {
        Input::getInstance()->setMouseCursorMode( Input::MouseCursorMode::GRAB );
    } else {
        Input::getInstance()->setMouseCursorMode( Input::MouseCursorMode::NORMAL );
    }

    float dSpeed = getSpeed() * Input::getInstance()->getAxis( Input::AXIS_VERTICAL );
    float rSpeed = getSpeed() * Input::getInstance()->getAxis( Input::AXIS_HORIZONTAL );
    float zSpeed = getSpeed() * Input::getInstance()->getAxis( "CameraAxisRoll" );

    m_roll += 0.005f * zSpeed;

    auto root = getNode();

    const auto pitch = rotationX( m_pitch );
    const auto yaw = rotationY( m_yaw );
    const auto roll = rotationZ( m_roll );

    const auto E = yaw * pitch * roll;

    const auto F = forward( E );
    const auto R = right( E );

    m_position = m_position + c.getDeltaTime() * ( dSpeed * F + rSpeed * R );
    const auto T = translation( vector3( m_position ) );

    root->setLocal( T * E );
}
<|endoftext|>


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

/**
 * @file att_estimator.cpp
 *
 * @author Thomas Gubler <thomasgubler@gmail.com>
 * @author Roman Bapst <romanbapst@yahoo.de>
*/

#include "attitude_estimator.h"

#include <px4/vehicle_attitude.h>
#include <mathlib/mathlib.h>
#include <platforms/px4_defines.h>

AttitudeEstimator::AttitudeEstimator() :
	_n(),
	// _sub_modelstates(_n.subscribe("/gazebo/model_states", 1, &AttitudeEstimator::ModelStatesCallback, this)),
	_sub_imu(_n.subscribe("/ardrone/imu", 1, &AttitudeEstimator::ImuCallback, this)),
	_vehicle_attitude_pub(_n.advertise<px4::vehicle_attitude>("vehicle_attitude", 1))
{
}

void AttitudeEstimator::ModelStatesCallback(const gazebo_msgs::ModelStatesConstPtr &msg)
{
	px4::vehicle_attitude msg_v_att;

	/* Fill px4 attitude topic with contents from modelstates topic */

	/* Convert quaternion to rotation matrix */
	math::Quaternion quat;
	//XXX: search for ardrone or other (other than 'plane') vehicle here
	int index = 1;
	quat(0) = (float)msg->pose[index].orientation.w;
	quat(1) = (float)msg->pose[index].orientation.x;
	quat(2) = (float) - msg->pose[index].orientation.y;
	quat(3) = (float) - msg->pose[index].orientation.z;

	msg_v_att.q[0] = quat(0);
	msg_v_att.q[1] = quat(1);
	msg_v_att.q[2] = quat(2);
	msg_v_att.q[3] = quat(3);

	math::Matrix<3, 3> rot = quat.to_dcm();

	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			PX4_R(msg_v_att.R, i, j) = rot(i, j);
		}
	}

	msg_v_att.R_valid = true;

	math::Vector<3> euler = rot.to_euler();
	msg_v_att.roll = euler(0);
	msg_v_att.pitch = euler(1);
	msg_v_att.yaw = euler(2);

	//XXX this is in inertial frame
	// msg_v_att.rollspeed = (float)msg->twist[index].angular.x;
	// msg_v_att.pitchspeed = -(float)msg->twist[index].angular.y;
	// msg_v_att.yawspeed = -(float)msg->twist[index].angular.z;

	_vehicle_attitude_pub.publish(msg_v_att);
}

void AttitudeEstimator::ImuCallback(const sensor_msgs::ImuConstPtr &msg)
{
	px4::vehicle_attitude msg_v_att;

	/* Fill px4 attitude topic with contents from modelstates topic */

	/* Convert quaternion to rotation matrix */
	math::Quaternion quat;
	//XXX: search for ardrone or other (other than 'plane') vehicle here
	int index = 1;
	quat(0) = (float)msg->orientation.w;
	quat(1) = (float)msg->orientation.x;
	quat(2) = (float) - msg->orientation.y;
	quat(3) = (float) - msg->orientation.z;

	msg_v_att.q[0] = quat(0);
	msg_v_att.q[1] = quat(1);
	msg_v_att.q[2] = quat(2);
	msg_v_att.q[3] = quat(3);

	math::Matrix<3, 3> rot = quat.to_dcm();

	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			PX4_R(msg_v_att.R, i, j) = rot(i, j);
		}
	}

	msg_v_att.R_valid = true;

	math::Vector<3> euler = rot.to_euler();
	msg_v_att.roll = euler(0);
	msg_v_att.pitch = euler(1);
	msg_v_att.yaw = euler(2);

	msg_v_att.rollspeed = (float)msg->angular_velocity.x;
	msg_v_att.pitchspeed = -(float)msg->angular_velocity.y;
	msg_v_att.yawspeed = -(float)msg->angular_velocity.z;

	_vehicle_attitude_pub.publish(msg_v_att);
}

int main(int argc, char **argv)
{
	ros::init(argc, argv, "attitude_estimator");
	AttitudeEstimator m;

	ros::spin();

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

/**
 * @file att_estimator.cpp
 *
 * @author Thomas Gubler <thomasgubler@gmail.com>
 * @author Roman Bapst <romanbapst@yahoo.de>
*/

#include "attitude_estimator.h"

#include <px4/vehicle_attitude.h>
#include <mathlib/mathlib.h>
#include <platforms/px4_defines.h>

AttitudeEstimator::AttitudeEstimator() :
	_n(),
	// _sub_modelstates(_n.subscribe("/gazebo/model_states", 1, &AttitudeEstimator::ModelStatesCallback, this)),
	_sub_imu(_n.subscribe("/px4_multicopter/imu", 1, &AttitudeEstimator::ImuCallback, this)),
	_vehicle_attitude_pub(_n.advertise<px4::vehicle_attitude>("vehicle_attitude", 1))
{
}

void AttitudeEstimator::ModelStatesCallback(const gazebo_msgs::ModelStatesConstPtr &msg)
{
	px4::vehicle_attitude msg_v_att;

	/* Fill px4 attitude topic with contents from modelstates topic */

	/* Convert quaternion to rotation matrix */
	math::Quaternion quat;
	//XXX: search for ardrone or other (other than 'plane') vehicle here
	int index = 1;
	quat(0) = (float)msg->pose[index].orientation.w;
	quat(1) = (float)msg->pose[index].orientation.x;
	quat(2) = (float) - msg->pose[index].orientation.y;
	quat(3) = (float) - msg->pose[index].orientation.z;

	msg_v_att.q[0] = quat(0);
	msg_v_att.q[1] = quat(1);
	msg_v_att.q[2] = quat(2);
	msg_v_att.q[3] = quat(3);

	math::Matrix<3, 3> rot = quat.to_dcm();

	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			PX4_R(msg_v_att.R, i, j) = rot(i, j);
		}
	}

	msg_v_att.R_valid = true;

	math::Vector<3> euler = rot.to_euler();
	msg_v_att.roll = euler(0);
	msg_v_att.pitch = euler(1);
	msg_v_att.yaw = euler(2);

	//XXX this is in inertial frame
	// msg_v_att.rollspeed = (float)msg->twist[index].angular.x;
	// msg_v_att.pitchspeed = -(float)msg->twist[index].angular.y;
	// msg_v_att.yawspeed = -(float)msg->twist[index].angular.z;

	_vehicle_attitude_pub.publish(msg_v_att);
}

void AttitudeEstimator::ImuCallback(const sensor_msgs::ImuConstPtr &msg)
{
	px4::vehicle_attitude msg_v_att;

	/* Fill px4 attitude topic with contents from modelstates topic */

	/* Convert quaternion to rotation matrix */
	math::Quaternion quat;
	//XXX: search for ardrone or other (other than 'plane') vehicle here
	int index = 1;
	quat(0) = (float)msg->orientation.w;
	quat(1) = (float)msg->orientation.x;
	quat(2) = (float) - msg->orientation.y;
	quat(3) = (float) - msg->orientation.z;

	msg_v_att.q[0] = quat(0);
	msg_v_att.q[1] = quat(1);
	msg_v_att.q[2] = quat(2);
	msg_v_att.q[3] = quat(3);

	math::Matrix<3, 3> rot = quat.to_dcm();

	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			PX4_R(msg_v_att.R, i, j) = rot(i, j);
		}
	}

	msg_v_att.R_valid = true;

	math::Vector<3> euler = rot.to_euler();
	msg_v_att.roll = euler(0);
	msg_v_att.pitch = euler(1);
	msg_v_att.yaw = euler(2);

	msg_v_att.rollspeed = (float)msg->angular_velocity.x;
	msg_v_att.pitchspeed = -(float)msg->angular_velocity.y;
	msg_v_att.yawspeed = -(float)msg->angular_velocity.z;

	_vehicle_attitude_pub.publish(msg_v_att);
}

int main(int argc, char **argv)
{
	ros::init(argc, argv, "attitude_estimator");
	AttitudeEstimator m;

	ros::spin();

	return 0;
}
<|endoftext|>