<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_TEXT_SYMBOLIZER_HPP
#define MAPNIK_TEXT_SYMBOLIZER_HPP

// mapnik
#include <mapnik/color.hpp>
#include <mapnik/font_set.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/filter_factory.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/text_placements.hpp>

// boost
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

// stl
#include <string>

namespace mapnik
{

struct MAPNIK_DECL text_symbolizer : public symbolizer_base
{
    // Note - we do not use boost::make_shared below as VC2008 and VC2010 are
    // not able to compile make_shared used within a constructor
    text_symbolizer(text_placements_ptr placements = text_placements_ptr(
                    boost::make_shared<text_placements_dummy>())
                   );
    text_symbolizer(expression_ptr name, std::string const& face_name,
                    float size, color const& fill,
                    text_placements_ptr placements = text_placements_ptr(new text_placements_dummy)
                    );
    text_symbolizer(expression_ptr name, float size, color const& fill,
                    text_placements_ptr placements = text_placements_ptr(new text_placements_dummy)
                    );
    text_symbolizer(text_symbolizer const& rhs);
    text_symbolizer& operator=(text_symbolizer const& rhs);
    expression_ptr get_name() const;
    void set_name(expression_ptr expr);

    expression_ptr get_orientation() const; // orienation (rotation angle atm)
    void set_orientation(expression_ptr expr);

    unsigned get_text_ratio() const; // target ratio for text bounding box in pixels
    void set_text_ratio(unsigned ratio);
    unsigned get_wrap_width() const; // width to wrap text at, or trigger ratio
    void set_wrap_width(unsigned ratio);
    unsigned char get_wrap_char() const; // character used to wrap lines
    std::string get_wrap_char_string() const; // character used to wrap lines as std::string
    void set_wrap_char(unsigned char character);
    void set_wrap_char_from_string(std::string const& character);
    text_transform_e get_text_transform() const; // text conversion on strings before display
    void set_text_transform(text_transform_e convert);
    unsigned get_line_spacing() const; // spacing between lines of text
    void set_line_spacing(unsigned spacing);
    unsigned get_character_spacing() const; // spacing between characters in text
    void set_character_spacing(unsigned spacing);
    unsigned get_label_spacing() const; // spacing between repeated labels on lines
    void set_label_spacing(unsigned spacing);
    unsigned get_label_position_tolerance() const; //distance the label can be moved on the line to fit, if 0 the default is used
    void set_label_position_tolerance(unsigned tolerance);
    bool get_force_odd_labels() const; // try render an odd amount of labels
    void set_force_odd_labels(bool force);
    double get_max_char_angle_delta() const; // maximum change in angle between adjacent characters
    void set_max_char_angle_delta(double angle);
    float get_text_size() const;
    void set_text_size(float size);
    std::string const& get_face_name() const;
    void set_face_name(std::string face_name);
    font_set const& get_fontset() const;
    void set_fontset(font_set const& fset);
    color const& get_fill() const;
    void set_fill(color const& fill);
    void set_halo_fill(color const& fill);
    color const& get_halo_fill() const;
    void set_halo_radius(double radius);
    double get_halo_radius() const;
    void set_label_placement(label_placement_e label_p);
    label_placement_e get_label_placement() const;
    void set_vertical_alignment(vertical_alignment_e valign);
    vertical_alignment_e get_vertical_alignment() const;
    void set_displacement(double x, double y);
    void set_displacement(position const& p);
    position const& get_displacement() const;
    void set_avoid_edges(bool avoid);
    bool get_avoid_edges() const;
    void set_minimum_distance(double distance);
    double get_minimum_distance() const;
    void set_minimum_padding(double distance);
    double get_minimum_padding() const;
    void set_minimum_path_length(double size);
    double get_minimum_path_length() const;
    void set_allow_overlap(bool overlap);
    bool get_allow_overlap() const;
    void set_text_opacity(double opacity);
    double get_text_opacity() const;
    bool get_wrap_before() const; // wrap text at wrap_char immediately before current work
    void set_wrap_before(bool wrap_before);
    void set_horizontal_alignment(horizontal_alignment_e valign);
    horizontal_alignment_e get_horizontal_alignment() const;
    void set_justify_alignment(justify_alignment_e valign);
    justify_alignment_e get_justify_alignment() const;
    text_placements_ptr get_placement_options() const;
    void set_placement_options(text_placements_ptr placement_options);

private:
    expression_ptr name_;
    expression_ptr orientation_;
    std::string face_name_;
    font_set fontset_;
    unsigned text_ratio_;
    unsigned wrap_width_;
    unsigned char wrap_char_;
    text_transform_e text_transform_;
    unsigned line_spacing_;
    unsigned character_spacing_;
    unsigned label_spacing_;
    unsigned label_position_tolerance_;
    bool force_odd_labels_;
    double max_char_angle_delta_;
    color fill_;
    color halo_fill_;
    double halo_radius_;
    label_placement_e label_p_;
    bool avoid_edges_;
    double minimum_distance_;
    double minimum_padding_;
    double minimum_path_length_;
    bool overlap_;
    double text_opacity_;
    bool wrap_before_;
    text_placements_ptr placement_options_;
};
}

#endif // MAPNIK_TEXT_SYMBOLIZER_HPP
<commit_msg>Add deprecation warnings.<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_TEXT_SYMBOLIZER_HPP
#define MAPNIK_TEXT_SYMBOLIZER_HPP

// mapnik
#include <mapnik/color.hpp>
#include <mapnik/font_set.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/filter_factory.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/text_placements.hpp>

// boost
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

// stl
#include <string>

// Warning disabled for the moment
#if (0 && __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define func_deprecated __attribute__ ((deprecated))
#else
#define func_deprecated
#endif

namespace mapnik
{

struct MAPNIK_DECL text_symbolizer : public symbolizer_base
{
    // Note - we do not use boost::make_shared below as VC2008 and VC2010 are
    // not able to compile make_shared used within a constructor
    text_symbolizer(text_placements_ptr placements = text_placements_ptr(
                    boost::make_shared<text_placements_dummy>())
                   );
    text_symbolizer(expression_ptr name, std::string const& face_name,
                    float size, color const& fill,
                    text_placements_ptr placements = text_placements_ptr(new text_placements_dummy)
                    );
    text_symbolizer(expression_ptr name, float size, color const& fill,
                    text_placements_ptr placements = text_placements_ptr(new text_placements_dummy)
                    );
    text_symbolizer(text_symbolizer const& rhs);
    text_symbolizer& operator=(text_symbolizer const& rhs);
    expression_ptr get_name() const func_deprecated;
    void set_name(expression_ptr expr);

    expression_ptr get_orientation() const func_deprecated; // orienation (rotation angle atm)
    void set_orientation(expression_ptr expr);

    unsigned get_text_ratio() const func_deprecated; // target ratio for text bounding box in pixels
    void set_text_ratio(unsigned ratio);
    unsigned get_wrap_width() const func_deprecated; // width to wrap text at, or trigger ratio
    void set_wrap_width(unsigned ratio);
    unsigned char get_wrap_char() const func_deprecated; // character used to wrap lines
    std::string get_wrap_char_string() const func_deprecated; // character used to wrap lines as std::string
    void set_wrap_char(unsigned char character);
    void set_wrap_char_from_string(std::string const& character);
    text_transform_e get_text_transform() const func_deprecated; // text conversion on strings before display
    void set_text_transform(text_transform_e convert);
    unsigned get_line_spacing() const func_deprecated; // spacing between lines of text
    void set_line_spacing(unsigned spacing);
    unsigned get_character_spacing() const func_deprecated; // spacing between characters in text
    void set_character_spacing(unsigned spacing);
    unsigned get_label_spacing() const func_deprecated; // spacing between repeated labels on lines
    void set_label_spacing(unsigned spacing);
    unsigned get_label_position_tolerance() const func_deprecated; //distance the label can be moved on the line to fit, if 0 the default is used
    void set_label_position_tolerance(unsigned tolerance);
    bool get_force_odd_labels() const func_deprecated; // try render an odd amount of labels
    void set_force_odd_labels(bool force);
    double get_max_char_angle_delta() const func_deprecated; // maximum change in angle between adjacent characters
    void set_max_char_angle_delta(double angle);
    float get_text_size() const func_deprecated;
    void set_text_size(float size);
    std::string const& get_face_name() const func_deprecated;
    void set_face_name(std::string face_name);
    font_set const& get_fontset() const func_deprecated;
    void set_fontset(font_set const& fset);
    color const& get_fill() const func_deprecated;
    void set_fill(color const& fill);
    void set_halo_fill(color const& fill);
    color const& get_halo_fill() const func_deprecated;
    void set_halo_radius(double radius);
    double get_halo_radius() const func_deprecated;
    void set_label_placement(label_placement_e label_p);
    label_placement_e get_label_placement() const func_deprecated;
    void set_vertical_alignment(vertical_alignment_e valign);
    vertical_alignment_e get_vertical_alignment() const func_deprecated;
    void set_displacement(double x, double y);
    void set_displacement(position const& p);
    position const& get_displacement() const func_deprecated;
    void set_avoid_edges(bool avoid);
    bool get_avoid_edges() const func_deprecated;
    void set_minimum_distance(double distance);
    double get_minimum_distance() const func_deprecated;
    void set_minimum_padding(double distance);
    double get_minimum_padding() const func_deprecated;
    void set_minimum_path_length(double size);
    double get_minimum_path_length() const func_deprecated;
    void set_allow_overlap(bool overlap);
    bool get_allow_overlap() const func_deprecated;
    void set_text_opacity(double opacity);
    double get_text_opacity() const func_deprecated;
    void set_wrap_before(bool wrap_before);
    bool get_wrap_before() const func_deprecated; // wrap text at wrap_char immediately before current work
    void set_horizontal_alignment(horizontal_alignment_e valign);
    horizontal_alignment_e get_horizontal_alignment() const func_deprecated;
    void set_justify_alignment(justify_alignment_e valign);
    justify_alignment_e get_justify_alignment() const func_deprecated;
    text_placements_ptr get_placement_options() const;
    void set_placement_options(text_placements_ptr placement_options);

private:
    expression_ptr name_;
    expression_ptr orientation_;
    std::string face_name_;
    font_set fontset_;
    unsigned text_ratio_;
    unsigned wrap_width_;
    unsigned char wrap_char_;
    text_transform_e text_transform_;
    unsigned line_spacing_;
    unsigned character_spacing_;
    unsigned label_spacing_;
    unsigned label_position_tolerance_;
    bool force_odd_labels_;
    double max_char_angle_delta_;
    color fill_;
    color halo_fill_;
    double halo_radius_;
    label_placement_e label_p_;
    bool avoid_edges_;
    double minimum_distance_;
    double minimum_padding_;
    double minimum_path_length_;
    bool overlap_;
    double text_opacity_;
    bool wrap_before_;
    text_placements_ptr placement_options_;
};
}

#endif // MAPNIK_TEXT_SYMBOLIZER_HPP
<|endoftext|>


<commit_before>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#ifndef IMPL_CONTAINER_H
#define IMPL_CONTAINER_H

#include <memory>

namespace nix {
namespace base {

template<typename T>
class ImplContainer {

protected:

    std::shared_ptr<T> impl_ptr;

public:

    ImplContainer() {}

    ImplContainer(T *p_impl)
        : impl_ptr(p_impl)
    {
    }

    ImplContainer(const std::shared_ptr<T> &p_impl)
        : impl_ptr(p_impl)
    {
    }

    ImplContainer(const ImplContainer<T> &other)
        : impl_ptr(other.impl_ptr)
    {
    }

    virtual ImplContainer<T> &operator=(const ImplContainer<T> &other) {
        if (*this != other) {
            ImplContainer tmp(other);
            swap(tmp);
        }
        return *this;
    }

    virtual bool operator==(const ImplContainer<T> &other) {
        return this->impl_ptr == other.impl_ptr;
    }

    virtual bool operator!=(const ImplContainer<T> &other) {
        return !(*this == other);
    }

    virtual void swap(ImplContainer<T> &second) {
        using std::swap;

        swap(impl_ptr, second.impl_ptr);
    }

    virtual ~ImplContainer() {}

    std::shared_ptr<T> impl() const {
        return impl_ptr;
    }

};

} // namespace base
} // namespace nix

#endif
<commit_msg>ImplContainer: support for assignment and comparison with NULL and nullptr<commit_after>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#ifndef IMPL_CONTAINER_H
#define IMPL_CONTAINER_H

#include <memory>

namespace nix {
namespace base {

template<typename T>
class ImplContainer {

protected:

    std::shared_ptr<T> impl_ptr;

public:

    ImplContainer() {}

    ImplContainer(T *p_impl)
        : impl_ptr(p_impl)
    {
    }

    ImplContainer(const std::shared_ptr<T> &p_impl)
        : impl_ptr(p_impl)
    {
    }

    ImplContainer(const ImplContainer<T> &other)
        : impl_ptr(other.impl_ptr)
    {
    }

    virtual ImplContainer<T> &operator=(const ImplContainer<T> &other) {
        if (*this != other) {
            ImplContainer tmp(other);
            swap(tmp);
        }
        return *this;
    }

    virtual ImplContainer<T> &operator=(std::nullptr_t nullp) {
        impl_ptr = nullp;
        return *this;
    }

    virtual bool operator==(const ImplContainer<T> &other) {
        return this->impl_ptr == other.impl_ptr;
    }

    virtual bool operator!=(const ImplContainer<T> &other) {
        return !(*this == other);
    }

    virtual bool operator==(std::nullptr_t nullp) {
        return impl_ptr == nullp;
    }

    virtual bool operator!=(std::nullptr_t nullp) {
        return impl_ptr != nullp;
    }

    virtual void swap(ImplContainer<T> &second) {
        using std::swap;

        swap(impl_ptr, second.impl_ptr);
    }

    virtual ~ImplContainer() {}

    std::shared_ptr<T> impl() const {
        return impl_ptr;
    }

};

} // namespace base
} // namespace nix

#endif
<|endoftext|>


<commit_before>#ifndef PLANET_BASIC_OPERATION_HPP
#define PLANET_BASIC_OPERATION_HPP

#include <planet/common.hpp>

namespace planet {

class file_entry;

//
// planet core handler
//
class planet_operation {
protected:
    static std::vector<char>& data_vector(file_entry& file);
public:
    virtual ~planet_operation() noexcept
    {
    }

    // Create new instance of this file operation
    virtual shared_ptr<planet_operation> new_instance() const = 0;

    // Open, read, write and close hook functions
    virtual int open(shared_ptr<file_entry>, path_type const&) = 0;
    virtual int read(shared_ptr<file_entry>, char *buf, size_t size, off_t offset) = 0;
    virtual int write(shared_ptr<file_entry>, char const *buf, size_t size, off_t offset) = 0;
    virtual int release(shared_ptr<file_entry>) = 0;

    // Initialize the first arguemnt of file_entry
    // shared_ptr<file_entry> is the new file entry which a new file operation will use
    virtual int mknod(shared_ptr<file_entry>, path_type const&, mode_t, dev_t) = 0;
    // Destoroy the first arguments of file_entry
    // shared_ptr<file_entry> was used by an other file operation, and now no one never uses it
    virtual int rmnod(shared_ptr<file_entry>, path_type const&) = 0;
};

//
// Note: All of planetfs operations must inherit planet_operation
//       and implement static function named `is_matching_path()`
//       which returns true if the given path is for the operation
//

// default file operation which is used if no other operations match the target path
class default_file_op final : public planet_operation {
public:
    ~default_file_op() = default;

    shared_ptr<planet_operation> new_instance() const;
    int open(shared_ptr<file_entry> file_ent, path_type const& path) override;
    int read(shared_ptr<file_entry> file_ent, char *buf, size_t size, off_t offset) override;
    int write(shared_ptr<file_entry> file_ent, char const *buf, size_t size, off_t offset) override;
    int release(shared_ptr<file_entry> file_ent) override;
    int mknod(shared_ptr<file_entry>, path_type const&, mode_t, dev_t) override;
    int rmnod(shared_ptr<file_entry>, path_type const&) override;
    static bool is_matching_path(path_type const&)
    {
        return true;
    }
};

}   //namespace planet

#endif  // PLANET_BASIC_OPERATION_HPP
<commit_msg>Fix typo in basic_operation.hpp<commit_after>#ifndef PLANET_BASIC_OPERATION_HPP
#define PLANET_BASIC_OPERATION_HPP

#include <planet/common.hpp>

namespace planet {

class file_entry;

//
// planet core handler
//
class planet_operation {
protected:
    static std::vector<char>& data_vector(file_entry& file);
public:
    virtual ~planet_operation() noexcept
    {
    }

    // Create new instance of this file operation
    virtual shared_ptr<planet_operation> new_instance() const = 0;

    // Open, read, write and close hook functions
    virtual int open(shared_ptr<file_entry>, path_type const&) = 0;
    virtual int read(shared_ptr<file_entry>, char *buf, size_t size, off_t offset) = 0;
    virtual int write(shared_ptr<file_entry>, char const *buf, size_t size, off_t offset) = 0;
    virtual int release(shared_ptr<file_entry>) = 0;

    // Initialize the first arguemnt of file_entry
    // shared_ptr<file_entry> is the new file entry which a new file operation will use
    virtual int mknod(shared_ptr<file_entry>, path_type const&, mode_t, dev_t) = 0;
    // Destoroy the first argument of file_entry
    // shared_ptr<file_entry> was used by an other file operation, and now no one never uses it
    virtual int rmnod(shared_ptr<file_entry>, path_type const&) = 0;
};

//
// Note: All of planetfs operations must inherit planet_operation
//       and implement static function named `is_matching_path()`
//       which returns true if the given path is for the operation
//

// default file operation which is used if no other operations match the target path
class default_file_op final : public planet_operation {
public:
    ~default_file_op() = default;

    shared_ptr<planet_operation> new_instance() const;
    int open(shared_ptr<file_entry> file_ent, path_type const& path) override;
    int read(shared_ptr<file_entry> file_ent, char *buf, size_t size, off_t offset) override;
    int write(shared_ptr<file_entry> file_ent, char const *buf, size_t size, off_t offset) override;
    int release(shared_ptr<file_entry> file_ent) override;
    int mknod(shared_ptr<file_entry>, path_type const&, mode_t, dev_t) override;
    int rmnod(shared_ptr<file_entry>, path_type const&) override;
    static bool is_matching_path(path_type const&)
    {
        return true;
    }
};

}   //namespace planet

#endif  // PLANET_BASIC_OPERATION_HPP
<|endoftext|>


<commit_before>//===- include/seec/Trace/TraceFormat.hpp --------------------------- C++ -===//
//
//                                    SeeC
//
// This file is distributed under The MIT License (MIT). See LICENSE.TXT for
// details.
//
//===----------------------------------------------------------------------===//
///
/// \file
///
//===----------------------------------------------------------------------===//

#ifndef SEEC_TRACE_TRACEFORMAT_HPP
#define SEEC_TRACE_TRACEFORMAT_HPP

#include "seec/Preprocessor/Apply.h"
#include "seec/Util/Maybe.hpp"

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

#include <cstdint>
#include <utility>
#include <memory>
#include <type_traits>

namespace seec {

namespace runtime_errors {

class Arg;

}

namespace trace {

/// Type used for offsets into trace files.
typedef uint64_t offset_uint;

/// Value used to represent an invalid or nonexistant offset.
inline offset_uint noOffset() {
  return std::numeric_limits<offset_uint>::max();
}

/// Version of the trace storage format.
constexpr inline uint64_t formatVersion() { return 3; }

/// ThreadID used to indicate that an event location refers to the initial
/// state of the process.
constexpr inline uint32_t initialDataThreadID() { return 0; }

/// ProcessTime used to refer to the initial state of the process.
constexpr inline uint64_t initialDataProcessTime() { return 0; }

/// Enumeration of possible event types.
enum class EventType : uint8_t {
  None = 0,
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) NAME,
#include "seec/Trace/Events.def"
  Highest
};

/// \brief Get a string indicating describing the value of Type.
char const *describe(EventType Type);

//------------------------------------------------------------------------------
// Event traits
//------------------------------------------------------------------------------

/// For events that represent the start of an event block. That is, events with
/// this trait can be applied separately to any prior events.
template<EventType ET>
struct is_block_start { static bool const value = false; };

/// For events that contain additional information for a preceding event.
template<EventType ET>
struct is_subservient { static bool const value = false; };

/// For events that affect the currently active function.
template<EventType ET>
struct is_function_level { static bool const value = false; };

/// For events that set the currently active instruction.
template<EventType ET>
struct is_instruction { static bool const value = false; };

/// For events that affect the shared process state.
template<EventType ET>
struct modifies_shared_state { static bool const value = false; };

/// For events that set memory state (not clearing).
template<EventType ET>
struct is_memory_state { static bool const value = false; };

/// Dummy trait for events that define no other traits.
template<EventType ET>
struct no_traits { static bool const value = false; };

#define SEEC_PP_TRAIT(EVENT_NAME, TRAIT_NAME)                                  \
template<>                                                                     \
struct TRAIT_NAME<EventType::EVENT_NAME> { static bool const value = true; };  \

#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) \
SEEC_PP_APPLY(SEEC_PP_TRAIT, TRAITS)
#include "seec/Trace/Events.def"

#undef SEEC_PP_TRAIT

//------------------------------------------------------------------------------
// FunctionRecord
//------------------------------------------------------------------------------

///
struct FunctionRecord {
  uint32_t Index;

  offset_uint EventOffsetStart;

  offset_uint EventOffsetEnd;

  uint64_t ThreadTimeEntered;

  uint64_t ThreadTimeExited;

  offset_uint ChildListOffset;

  offset_uint NonLocalChangeListOffset;
};

//------------------------------------------------------------------------------
// RuntimeValueRecord
//------------------------------------------------------------------------------

union RuntimeValueRecord {
  uint64_t UInt64;

  uintptr_t UIntPtr;

  float Float;

  double Double;

  long double LongDouble;

  /// \brief Default construct.
  RuntimeValueRecord()
  {}

  /// \brief Copy construct.
  RuntimeValueRecord(RuntimeValueRecord const &Other) = default;

  /// \brief Construct a new record holding a uint32_t.
  explicit RuntimeValueRecord(uint32_t Value)
  : UInt64(Value)
  {}

  /// \brief Construct a new record holding a uint64_t.
  explicit RuntimeValueRecord(uint64_t Value)
  : UInt64(Value)
  {}

  /// \brief Create a new record holding a uintptr_t.
  explicit RuntimeValueRecord(void const *Value)
  : UIntPtr(reinterpret_cast<uintptr_t>(Value))
  {}

  /// \brief Construct a new record holding a float.
  explicit RuntimeValueRecord(float Value)
  : Float(Value)
  {}

  /// \brief Construct a new record holding a double.
  explicit RuntimeValueRecord(double Value)
  : Double(Value)
  {}

  /// \brief Construct a new record holding a long double.
  explicit RuntimeValueRecord(long double Value)
  : LongDouble(Value)
  {}

  /// \brief Copy assign.
  RuntimeValueRecord &operator=(RuntimeValueRecord const &RHS) = default;
};

llvm::raw_ostream & operator<<(llvm::raw_ostream &Out,
                               RuntimeValueRecord const &Record);

//------------------------------------------------------------------------------
// EventRecordBase
//------------------------------------------------------------------------------

// forward-declaration
template<EventType ET>
class EventRecord;

/// \brief Base class for all event records.
class EventRecordBase {
  EventType Type;

  uint8_t PreviousEventSize;

public:
  EventRecordBase(EventType Type, uint8_t PreviousEventSize)
  : Type(Type),
    PreviousEventSize(PreviousEventSize)
  {}

  /// \name Conversion
  /// @{

  template<EventType ET>
  EventRecord<ET> const &as() const {
    assert(Type == ET);
    return *(static_cast<EventRecord<ET> const *>(this));
  }

  /// @}

  /// \name Query event properties
  /// @{

  /// Get the type of this event.
  EventType getType() const { return Type; }

  /// Get the size of the event immediately preceding this event.
  uint8_t getPreviousEventSize() const { return PreviousEventSize; }

  /// Get the size of this event.
  std::size_t getEventSize() const;

  /// Get the value of this event's ProcessTime, if it has one.
  seec::Maybe<uint64_t> getProcessTime() const;

  /// Get the value of this event's ThreadTime, if it has one.
  seec::Maybe<uint64_t> getThreadTime() const;

  /// Get the value of this event's Index member, if it has one.
  seec::Maybe<uint32_t> getIndex() const;

  /// Check if this event has the is_block_start trait.
  bool isBlockStart() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) \
      case EventType::NAME: return is_block_start<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// Check if this event has the is_subservient trait.
  bool isSubservient() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) \
      case EventType::NAME: return is_subservient<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// Check if this event has the is_function_level trait.
  bool isFunctionLevel() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) \
      case EventType::NAME: return is_function_level<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// Check if this event has the is_instruction trait.
  bool isInstruction() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) \
      case EventType::NAME: return is_instruction<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// Check if this event has the modifies_shared_state trait.
  bool modifiesSharedState() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS)                                \
      case EventType::NAME:                                                    \
        return modifies_shared_state<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// Check if this event has the is_memory_state trait.
  bool isMemoryState() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS)                                \
      case EventType::NAME:                                                    \
        return is_memory_state<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// @} (Query event properties)
};

llvm::raw_ostream & operator<<(llvm::raw_ostream &Out,
                               EventRecordBase const &Event);

//------------------------------------------------------------------------------
// Event records
//------------------------------------------------------------------------------

template<EventType ET>
class EventRecord : public EventRecordBase {};

#define SEEC_PP_MEMBER(TYPE, NAME) TYPE NAME;
#define SEEC_PP_ACCESSOR(TYPE, NAME)                                           \
  TYPE const &get##NAME() const { return NAME; }                               \
  static std::size_t sizeof##NAME() { return sizeof(NAME); }                   \
  typedef TYPE typeof##NAME;
#define SEEC_PP_PARAMETER(TYPE, NAME) , TYPE NAME
#define SEEC_PP_INITIALIZE(TYPE, NAME) , NAME(NAME)

#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS)                                \
template<>                                                                     \
class EventRecord<EventType::NAME> : public EventRecordBase {                  \
private:                                                                       \
  SEEC_PP_APPLY(SEEC_PP_MEMBER, MEMBERS)                                       \
public:                                                                        \
  SEEC_PP_APPLY(SEEC_PP_ACCESSOR, MEMBERS)                                     \
                                                                               \
  EventRecord(uint8_t PreviousEventSize                                        \
              SEEC_PP_APPLY(SEEC_PP_PARAMETER, MEMBERS)                        \
              )                                                                \
  : EventRecordBase(EventType::NAME, PreviousEventSize)                        \
    SEEC_PP_APPLY(SEEC_PP_INITIALIZE, MEMBERS)                                 \
  {}                                                                           \
};

#include "seec/Trace/Events.def"

#undef SEEC_PP_MEMBER
#undef SEEC_PP_ACCESSOR
#undef SEEC_PP_PARAMETER
#undef SEEC_PP_INITIALIZE

// Declare raw_ostream output for all event records.
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS)                                \
llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,                          \
                              EventRecord<EventType::NAME> const &Event);

#include "seec/Trace/Events.def"

/// \brief Holds the thread and offset of an event record.
///
class EventLocation {
  /// The thread that contains the event.
  uint32_t ThreadID;

  /// The offset of the event in the thread's event trace.
  offset_uint Offset;

public:
  /// Construct a new empty EventLocation.
  EventLocation()
  : ThreadID(0),
    Offset(noOffset())
  {}

  /// Construct a new EventLocation.
  EventLocation(uint32_t EventThreadID, offset_uint EventOffset)
  : ThreadID(EventThreadID),
    Offset(EventOffset)
  {}

  EventLocation(EventLocation const &) = default;

  EventLocation &operator=(EventLocation const &) = default;

  /// Get the thread ID of the thread that contains the event.
  uint32_t getThreadID() const { return ThreadID; }

  /// Check whether this event location has a legitimate offset.
  bool hasOffset() const { return Offset != noOffset(); }

  /// Get the offset of the event in the thread's event trace.
  offset_uint getOffset() const { return Offset; }

  /// \name Comparison
  /// @{

  /// \brief Check if this EventLocation is equal to another EventLocation.
  bool operator==(EventLocation const &RHS) const {
    return ThreadID == RHS.ThreadID && Offset == RHS.Offset;
  }

  /// \brief Check if this EventLocation differs from another EventLocation.
  bool operator!=(EventLocation const &RHS) const {
    return !operator==(RHS);
  }

  /// @} (Comparison)
};

} // namespace trace (in seec)

} // namespace seec

#endif // SEEC_TRACE_TRACEFORMAT_HPP
<commit_msg>Remove unused dummy trait "no_traits".<commit_after>//===- include/seec/Trace/TraceFormat.hpp --------------------------- C++ -===//
//
//                                    SeeC
//
// This file is distributed under The MIT License (MIT). See LICENSE.TXT for
// details.
//
//===----------------------------------------------------------------------===//
///
/// \file
///
//===----------------------------------------------------------------------===//

#ifndef SEEC_TRACE_TRACEFORMAT_HPP
#define SEEC_TRACE_TRACEFORMAT_HPP

#include "seec/Preprocessor/Apply.h"
#include "seec/Util/Maybe.hpp"

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

#include <cstdint>
#include <utility>
#include <memory>
#include <type_traits>

namespace seec {

namespace runtime_errors {

class Arg;

}

namespace trace {

/// Type used for offsets into trace files.
typedef uint64_t offset_uint;

/// Value used to represent an invalid or nonexistant offset.
inline offset_uint noOffset() {
  return std::numeric_limits<offset_uint>::max();
}

/// Version of the trace storage format.
constexpr inline uint64_t formatVersion() { return 3; }

/// ThreadID used to indicate that an event location refers to the initial
/// state of the process.
constexpr inline uint32_t initialDataThreadID() { return 0; }

/// ProcessTime used to refer to the initial state of the process.
constexpr inline uint64_t initialDataProcessTime() { return 0; }

/// Enumeration of possible event types.
enum class EventType : uint8_t {
  None = 0,
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) NAME,
#include "seec/Trace/Events.def"
  Highest
};

/// \brief Get a string indicating describing the value of Type.
char const *describe(EventType Type);

//------------------------------------------------------------------------------
// Event traits
//------------------------------------------------------------------------------

/// For events that represent the start of an event block. That is, events with
/// this trait can be applied separately to any prior events.
template<EventType ET>
struct is_block_start { static bool const value = false; };

/// For events that contain additional information for a preceding event.
template<EventType ET>
struct is_subservient { static bool const value = false; };

/// For events that affect the currently active function.
template<EventType ET>
struct is_function_level { static bool const value = false; };

/// For events that set the currently active instruction.
template<EventType ET>
struct is_instruction { static bool const value = false; };

/// For events that affect the shared process state.
template<EventType ET>
struct modifies_shared_state { static bool const value = false; };

/// For events that set memory state (not clearing).
template<EventType ET>
struct is_memory_state { static bool const value = false; };

#define SEEC_PP_TRAIT(EVENT_NAME, TRAIT_NAME)                                  \
template<>                                                                     \
struct TRAIT_NAME<EventType::EVENT_NAME> { static bool const value = true; };  \

#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) \
SEEC_PP_APPLY(SEEC_PP_TRAIT, TRAITS)
#include "seec/Trace/Events.def"

#undef SEEC_PP_TRAIT

//------------------------------------------------------------------------------
// FunctionRecord
//------------------------------------------------------------------------------

///
struct FunctionRecord {
  uint32_t Index;

  offset_uint EventOffsetStart;

  offset_uint EventOffsetEnd;

  uint64_t ThreadTimeEntered;

  uint64_t ThreadTimeExited;

  offset_uint ChildListOffset;

  offset_uint NonLocalChangeListOffset;
};

//------------------------------------------------------------------------------
// RuntimeValueRecord
//------------------------------------------------------------------------------

union RuntimeValueRecord {
  uint64_t UInt64;

  uintptr_t UIntPtr;

  float Float;

  double Double;

  long double LongDouble;

  /// \brief Default construct.
  RuntimeValueRecord()
  {}

  /// \brief Copy construct.
  RuntimeValueRecord(RuntimeValueRecord const &Other) = default;

  /// \brief Construct a new record holding a uint32_t.
  explicit RuntimeValueRecord(uint32_t Value)
  : UInt64(Value)
  {}

  /// \brief Construct a new record holding a uint64_t.
  explicit RuntimeValueRecord(uint64_t Value)
  : UInt64(Value)
  {}

  /// \brief Create a new record holding a uintptr_t.
  explicit RuntimeValueRecord(void const *Value)
  : UIntPtr(reinterpret_cast<uintptr_t>(Value))
  {}

  /// \brief Construct a new record holding a float.
  explicit RuntimeValueRecord(float Value)
  : Float(Value)
  {}

  /// \brief Construct a new record holding a double.
  explicit RuntimeValueRecord(double Value)
  : Double(Value)
  {}

  /// \brief Construct a new record holding a long double.
  explicit RuntimeValueRecord(long double Value)
  : LongDouble(Value)
  {}

  /// \brief Copy assign.
  RuntimeValueRecord &operator=(RuntimeValueRecord const &RHS) = default;
};

llvm::raw_ostream & operator<<(llvm::raw_ostream &Out,
                               RuntimeValueRecord const &Record);

//------------------------------------------------------------------------------
// EventRecordBase
//------------------------------------------------------------------------------

// forward-declaration
template<EventType ET>
class EventRecord;

/// \brief Base class for all event records.
class EventRecordBase {
  EventType Type;

  uint8_t PreviousEventSize;

public:
  EventRecordBase(EventType Type, uint8_t PreviousEventSize)
  : Type(Type),
    PreviousEventSize(PreviousEventSize)
  {}

  /// \name Conversion
  /// @{

  template<EventType ET>
  EventRecord<ET> const &as() const {
    assert(Type == ET);
    return *(static_cast<EventRecord<ET> const *>(this));
  }

  /// @}

  /// \name Query event properties
  /// @{

  /// Get the type of this event.
  EventType getType() const { return Type; }

  /// Get the size of the event immediately preceding this event.
  uint8_t getPreviousEventSize() const { return PreviousEventSize; }

  /// Get the size of this event.
  std::size_t getEventSize() const;

  /// Get the value of this event's ProcessTime, if it has one.
  seec::Maybe<uint64_t> getProcessTime() const;

  /// Get the value of this event's ThreadTime, if it has one.
  seec::Maybe<uint64_t> getThreadTime() const;

  /// Get the value of this event's Index member, if it has one.
  seec::Maybe<uint32_t> getIndex() const;

  /// Check if this event has the is_block_start trait.
  bool isBlockStart() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) \
      case EventType::NAME: return is_block_start<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// Check if this event has the is_subservient trait.
  bool isSubservient() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) \
      case EventType::NAME: return is_subservient<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// Check if this event has the is_function_level trait.
  bool isFunctionLevel() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) \
      case EventType::NAME: return is_function_level<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// Check if this event has the is_instruction trait.
  bool isInstruction() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS) \
      case EventType::NAME: return is_instruction<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// Check if this event has the modifies_shared_state trait.
  bool modifiesSharedState() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS)                                \
      case EventType::NAME:                                                    \
        return modifies_shared_state<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// Check if this event has the is_memory_state trait.
  bool isMemoryState() const {
    switch (Type) {
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS)                                \
      case EventType::NAME:                                                    \
        return is_memory_state<EventType::NAME>::value;
#include "seec/Trace/Events.def"
      default: llvm_unreachable("Reference to unknown event type!");
    }

    return false;
  }

  /// @} (Query event properties)
};

llvm::raw_ostream & operator<<(llvm::raw_ostream &Out,
                               EventRecordBase const &Event);

//------------------------------------------------------------------------------
// Event records
//------------------------------------------------------------------------------

template<EventType ET>
class EventRecord : public EventRecordBase {};

#define SEEC_PP_MEMBER(TYPE, NAME) TYPE NAME;
#define SEEC_PP_ACCESSOR(TYPE, NAME)                                           \
  TYPE const &get##NAME() const { return NAME; }                               \
  static std::size_t sizeof##NAME() { return sizeof(NAME); }                   \
  typedef TYPE typeof##NAME;
#define SEEC_PP_PARAMETER(TYPE, NAME) , TYPE NAME
#define SEEC_PP_INITIALIZE(TYPE, NAME) , NAME(NAME)

#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS)                                \
template<>                                                                     \
class EventRecord<EventType::NAME> : public EventRecordBase {                  \
private:                                                                       \
  SEEC_PP_APPLY(SEEC_PP_MEMBER, MEMBERS)                                       \
public:                                                                        \
  SEEC_PP_APPLY(SEEC_PP_ACCESSOR, MEMBERS)                                     \
                                                                               \
  EventRecord(uint8_t PreviousEventSize                                        \
              SEEC_PP_APPLY(SEEC_PP_PARAMETER, MEMBERS)                        \
              )                                                                \
  : EventRecordBase(EventType::NAME, PreviousEventSize)                        \
    SEEC_PP_APPLY(SEEC_PP_INITIALIZE, MEMBERS)                                 \
  {}                                                                           \
};

#include "seec/Trace/Events.def"

#undef SEEC_PP_MEMBER
#undef SEEC_PP_ACCESSOR
#undef SEEC_PP_PARAMETER
#undef SEEC_PP_INITIALIZE

// Declare raw_ostream output for all event records.
#define SEEC_TRACE_EVENT(NAME, MEMBERS, TRAITS)                                \
llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,                          \
                              EventRecord<EventType::NAME> const &Event);

#include "seec/Trace/Events.def"

/// \brief Holds the thread and offset of an event record.
///
class EventLocation {
  /// The thread that contains the event.
  uint32_t ThreadID;

  /// The offset of the event in the thread's event trace.
  offset_uint Offset;

public:
  /// Construct a new empty EventLocation.
  EventLocation()
  : ThreadID(0),
    Offset(noOffset())
  {}

  /// Construct a new EventLocation.
  EventLocation(uint32_t EventThreadID, offset_uint EventOffset)
  : ThreadID(EventThreadID),
    Offset(EventOffset)
  {}

  EventLocation(EventLocation const &) = default;

  EventLocation &operator=(EventLocation const &) = default;

  /// Get the thread ID of the thread that contains the event.
  uint32_t getThreadID() const { return ThreadID; }

  /// Check whether this event location has a legitimate offset.
  bool hasOffset() const { return Offset != noOffset(); }

  /// Get the offset of the event in the thread's event trace.
  offset_uint getOffset() const { return Offset; }

  /// \name Comparison
  /// @{

  /// \brief Check if this EventLocation is equal to another EventLocation.
  bool operator==(EventLocation const &RHS) const {
    return ThreadID == RHS.ThreadID && Offset == RHS.Offset;
  }

  /// \brief Check if this EventLocation differs from another EventLocation.
  bool operator!=(EventLocation const &RHS) const {
    return !operator==(RHS);
  }

  /// @} (Comparison)
};

} // namespace trace (in seec)

} // namespace seec

#endif // SEEC_TRACE_TRACEFORMAT_HPP
<|endoftext|>


<commit_before>#include "Player.h"
#include "Logger.h"
#include "Configuration.h"

Player::Player(double x_, double y_, Sprite* sprite_) :
    Entity(x_, y_, sprite_),
    vx(0),
    vy(0),
    speed(15),
    maxSpeed(500),
    cameraX(0),
    cameraY(0),
    levelW(0),
    levelH(0)
{
    this->state = STATE_JUMPING;
	if(this->sprite != nullptr){
        this->width = this->sprite->getWidth();
        this->height = this->sprite->getHeight();
	}
    else{
        Logger::warning("No sprite set for the player! Null sprite.");
    }
}

Player::~Player(){
    if(this->sprite != nullptr){
        this->sprite->free();
        delete this->sprite;
        this->sprite = nullptr;
    }
}

void Player::update(double dt_){
    /// @todo Fix all these magic/weird numbers.
    this->x += this->vx * dt_;

    // Left wall.
    if(this->x < 0){
        this->x = 0;
        this->vx = 0;
    }
    // Right wall.
    else if(this->x + this->width > this->levelW){
        this->x = this->levelW - this->width;
        this->vx = 0;
    }

    this->y += this->vy * dt_;

    // Top wall.
    if(this->y < 0){
        this->y = 0;
        this->vy = 0;
    }
    // Bottom wall.
    else if(this->y + this->height + 40 > this->levelH){
        this->y = this->levelH - this->height - 40;
        this->vy = 0;
        this->state = STATE_STANDING;
    }

}

void Player::render(){
    const int dx = this->x - this->cameraX;
    const int dy = this->y - this->cameraY;
	this->sprite->render(dx, dy);
}

void Player::updateInput(array<bool, GameKeys::MAX> keyStates_){
    /// @todo Fix all these magic/weird numbers.
    switch(this->state){
        case STATE_STANDING:
            if(keyStates_[GameKeys::UP]){
                this->state = STATE_JUMPING;
                this->vy = -40*this->speed;
            }
            if(keyStates_[GameKeys::ROLL]){
                 this->state = STATE_ROLLING;
                 this->vx = 100*this->speed;
            }
            if(keyStates_[GameKeys::DOWN]){
                this->speed = 7.5;
                this->maxSpeed = 350;
                this->state = STATE_CROUCHING;
            }
            break;

        case STATE_JUMPING:
            this->vy += 2*this->speed;
            break;

        case STATE_CROUCHING:
            if(!keyStates_[GameKeys::DOWN]){
                this->speed = 15;
                this->maxSpeed = 500;
                this->state = STATE_STANDING;
            }
            break;

        case STATE_ROLLING:
            this->vx *= 0.95;
            if(this->vx < 3 && this->vx > (-3)){
                this->state = STATE_STANDING;
                this->vx = 0;
            }
            break;

        default:
            break;
    }

    // Movement.
    if(keyStates_[GameKeys::LEFT]){
        if(this->vx > -this->maxSpeed){
            this->vx -= this->speed;
        }
    }
    else if(keyStates_[GameKeys::RIGHT]){
        if(this->vx < this->maxSpeed){
            this->vx += this->speed;
        }
    }
    else{
        this->vx *= 0.95;
    }

}

void Player::setCameraXY(double x_, double y_){
    this->cameraX = x_;
    this->cameraY = y_;
}

void Player::setLevelWH(unsigned int width_, unsigned int height_){
    this->levelW = width_;
    this->levelH = height_;
}
<commit_msg>improving rolling<commit_after>#include "Player.h"
#include "Logger.h"
#include "Configuration.h"

Player::Player(double x_, double y_, Sprite* sprite_) :
    Entity(x_, y_, sprite_),
    vx(0),
    vy(0),
    speed(15),
    maxSpeed(500),
    cameraX(0),
    cameraY(0),
    levelW(0),
    levelH(0)
{
    this->state = STATE_JUMPING;
	if(this->sprite != nullptr){
        this->width = this->sprite->getWidth();
        this->height = this->sprite->getHeight();
	}
    else{
        Logger::warning("No sprite set for the player! Null sprite.");
    }
}

Player::~Player(){
    if(this->sprite != nullptr){
        this->sprite->free();
        delete this->sprite;
        this->sprite = nullptr;
    }
}

void Player::update(double dt_){
    /// @todo Fix all these magic/weird numbers.
    this->x += this->vx * dt_;

    // Left wall.
    if(this->x < 0){
        this->x = 0;
        this->vx = 0;
    }
    // Right wall.
    else if(this->x + this->width > this->levelW){
        this->x = this->levelW - this->width;
        this->vx = 0;
    }

    this->y += this->vy * dt_;

    // Top wall.
    if(this->y < 0){
        this->y = 0;
        this->vy = 0;
    }
    // Bottom wall.
    else if(this->y + this->height + 40 > this->levelH){
        this->y = this->levelH - this->height - 40;
        this->vy = 0;
        this->state = STATE_STANDING;
    }

}

void Player::render(){
    const int dx = this->x - this->cameraX;
    const int dy = this->y - this->cameraY;
	this->sprite->render(dx, dy);
}

void Player::updateInput(array<bool, GameKeys::MAX> keyStates_){
    /// @todo Fix all these magic/weird numbers.
    switch(this->state){
        case STATE_STANDING:
            if(keyStates_[GameKeys::UP]){
                this->state = STATE_JUMPING;
                this->vy = -40*this->speed;
            }
            if(keyStates_[GameKeys::ROLL]){
                 this->state = STATE_ROLLING;
            }
            if(keyStates_[GameKeys::DOWN]){
                this->speed = 7.5;
                this->maxSpeed = 350;
                this->state = STATE_CROUCHING;
            }
            break;

        case STATE_JUMPING:
            this->vy += 2*this->speed;
            break;

        case STATE_CROUCHING:
            if(!keyStates_[GameKeys::DOWN]){
                this->speed = 15;
                this->maxSpeed = 500;
                this->state = STATE_STANDING;
            }
            break;

        case STATE_ROLLING:
            this->vx = 70*this->speed;
            this->state = STATE_STANDING;
            break;

        default:
            break;
    }

    // X movement.
    if(keyStates_[GameKeys::LEFT]){
        if(this->vx > -this->maxSpeed){
            this->vx -= this->speed;
        }
    }
    else if(keyStates_[GameKeys::RIGHT]){
        if(this->vx < this->maxSpeed){
            this->vx += this->speed;
        }
    }
    else{
        this->vx *= 0.95;
    }

}

void Player::setCameraXY(double x_, double y_){
    this->cameraX = x_;
    this->cameraY = y_;
}

void Player::setLevelWH(unsigned int width_, unsigned int height_){
    this->levelW = width_;
    this->levelH = height_;
}
<|endoftext|>


<commit_before>/// @file
/// @author  Boris Mikic
/// @version 2.5
///
/// @section LICENSE
///
/// This program is free software; you can redistribute it and/or modify it under
/// the terms of the BSD license: http://www.opensource.org/licenses/bsd-license.php

#include <hltypes/hltypesUtil.h>

#include "Buffer.h"
#include "Category.h"
#include "Player.h"
#include "Sound.h"

namespace xal
{
	Player::Player(Sound* sound, Buffer* buffer) : gain(1.0f), pitch(1.0f), paused(false),
		looping(false), fadeSpeed(0.0f), fadeTime(0.0f), offset(0.0f), bufferIndex(0),
		processedByteCount(0)
	{
		this->sound = sound;
		this->buffer = buffer;
	}

	Player::~Player()
	{
	}

	float Player::getGain()
	{
		xal::mgr->_lock();
		float gain = this->_getGain();
		xal::mgr->_unlock();
		return gain;
	}

	float Player::_getGain()
	{
		return this->gain;
	}

	void Player::setGain(float value)
	{
		xal::mgr->_lock();
		this->_setGain(value);
		xal::mgr->_unlock();
	}

	void Player::_setGain(float value)
	{
		this->gain = hclamp(value, 0.0f, 1.0f);
		this->_systemUpdateGain(this->gain);
	}

	float Player::getPitch()
	{
		xal::mgr->_lock();
		float pitch = this->_getPitch();
		xal::mgr->_unlock();
		return pitch;
	}

	float Player::_getPitch()
	{
		return this->pitch;
	}

	void Player::setPitch(float value)
	{
		xal::mgr->_lock();
		this->_setPitch(value);
		xal::mgr->_unlock();
	}

	void Player::_setPitch(float value)
	{
		this->pitch = hclamp(value, 0.01f, 100.0f);
		this->_systemUpdatePitch();
	}

	float Player::getTimePosition()
	{
		return ((float)this->getSamplePosition() / this->buffer->getSamplingRate());
	}

	unsigned int Player::getSamplePosition()
	{
		xal::mgr->_lock();
		unsigned int position = this->_systemGetBufferPosition();
		if (this->sound->isStreamed())
		{
			// corrects position by using number of processed bytes (circular)
			position = (position + (STREAM_BUFFER_COUNT - this->bufferIndex) * STREAM_BUFFER_SIZE) % STREAM_BUFFER;
			// adds streamed processed byte count
			position += this->processedByteCount;
		}
		position = hmin(position, (unsigned int)this->sound->getSize());
		unsigned int samplePosition = (unsigned int)(position /
			(this->buffer->getChannels() * this->buffer->getBitsPerSample() * 0.125f));
		xal::mgr->_unlock();
		return samplePosition;
	}

	hstr Player::getName()
	{
		return this->sound->getName();
	}

	hstr Player::getFilename()
	{
		return this->sound->getFilename();
	}

	hstr Player::getRealFilename()
	{
		return this->sound->getRealFilename();
	}

    float Player::getDuration()
    {
        return this->buffer->getDuration();
    }

    int Player::getSize()
    {
		return this->buffer->getSize();
    }

	bool Player::isPlaying()
	{
		return (!this->isFadingOut() && this->_systemIsPlaying());
	}

	bool Player::isPaused()
	{
		return (this->paused && !this->isFading());
	}

	bool Player::isFading()
	{
		return (this->fadeSpeed != 0.0f);
	}

	bool Player::isFadingIn()
	{
		return (this->fadeSpeed > 0.0f);
	}

	bool Player::isFadingOut()
	{
		return (this->fadeSpeed < 0.0f);
	}

	Category* Player::getCategory()
	{
		return this->sound->getCategory();
	}

	void Player::_update(float k)
	{
		if (this->sound->isStreamed() && this->_systemIsPlaying())
		{
			this->processedByteCount += this->_systemUpdateStream();
		}
		if (this->isFading())
		{
			this->fadeTime += this->fadeSpeed * k;
			if (this->fadeTime >= 1.0f && this->fadeSpeed > 0.0f)
			{
				this->_setGain(this->gain);
				this->fadeTime = 1.0f;
				this->fadeSpeed = 0.0f;
			}
			else if (this->fadeTime <= 0.0f && this->fadeSpeed < 0.0f)
			{
				this->fadeTime = 0.0f;
				this->fadeSpeed = 0.0f;
				if (!this->paused)
				{
					this->_stop();
					return;
				}
				this->_pause();
			}
			else
			{
				this->_systemUpdateGain(this->_calcFadeGain());
			}
		}
	}

	void Player::play(float fadeTime, bool looping)
	{
		xal::mgr->_lock();
		this->_play(fadeTime, looping);
		xal::mgr->_unlock();
	}

	void Player::stop(float fadeTime)
	{
		xal::mgr->_lock();
		this->_stop(fadeTime);
		xal::mgr->_unlock();
	}

	void Player::pause(float fadeTime)
	{
		xal::mgr->_lock();
		this->_pause(fadeTime);
		xal::mgr->_unlock();
	}

	void Player::_play(float fadeTime, bool looping)
	{
		if (!xal::mgr->isEnabled())
		{
			return;
		}
		if (xal::mgr->isSuspended())
		{
			if (!xal::mgr->suspendedPlayers.contains(this))
			{
				xal::mgr->suspendedPlayers += this;
				if (!this->paused)
				{
					this->looping = looping;
					this->paused = true;
				}
			}
			return;
		}
		if (!this->_systemPreparePlay())
		{
			return;
		}
		if (!this->paused)
		{
			this->looping = looping;
		}
		bool alreadyFading = this->isFading();
		if (!alreadyFading && !this->_systemIsPlaying())
		{
			this->buffer->prepare();
			this->_systemPrepareBuffer();
			if (this->paused)
			{
				this->_systemSetOffset(this->offset);
			}
		}
		if (fadeTime > 0.0f)
		{
			this->fadeSpeed = 1.0f / fadeTime;
		}
		else
		{
			this->fadeTime = 1.0f;
			this->fadeSpeed = 0.0f;
		}
		this->_systemUpdateGain(this->_calcFadeGain());
		if (!alreadyFading)
		{
			this->_systemPlay();
		}
		this->paused = false;
	}

	void Player::_stop(float fadeTime)
	{
		if (xal::mgr->isSuspended() && xal::mgr->suspendedPlayers.contains(this))
		{
			xal::mgr->suspendedPlayers -= this;
		}
		this->paused = false;
		this->_stopSound(fadeTime);
		this->offset = 0.0f;
		this->processedByteCount = 0;
	}

	void Player::_pause(float fadeTime)
	{
		this->paused = true;
		this->_stopSound(fadeTime);
	}

	float Player::_calcGain()
	{
		return (this->gain * this->sound->getCategory()->getGain() * xal::mgr->getGlobalGain());
	}

	float Player::_calcFadeGain()
	{
		return (this->gain * this->sound->getCategory()->getGain() * xal::mgr->getGlobalGain() * this->fadeTime);
	}

	void Player::_stopSound(float fadeTime)
	{
		if (fadeTime > 0.0f)
		{
			this->fadeSpeed = -1.0f / fadeTime;
			return;
		}
		this->offset = this->_systemGetOffset();
		this->processedByteCount += this->_systemStop();
		this->buffer->release();
		this->fadeTime = 0.0f;
		this->fadeSpeed = 0.0f;
	}

}
<commit_msg>fixed gain calculation bug<commit_after>/// @file
/// @author  Boris Mikic
/// @version 2.5
///
/// @section LICENSE
///
/// This program is free software; you can redistribute it and/or modify it under
/// the terms of the BSD license: http://www.opensource.org/licenses/bsd-license.php

#include <hltypes/hltypesUtil.h>

#include "Buffer.h"
#include "Category.h"
#include "Player.h"
#include "Sound.h"

namespace xal
{
	Player::Player(Sound* sound, Buffer* buffer) : gain(1.0f), pitch(1.0f), paused(false),
		looping(false), fadeSpeed(0.0f), fadeTime(0.0f), offset(0.0f), bufferIndex(0),
		processedByteCount(0)
	{
		this->sound = sound;
		this->buffer = buffer;
	}

	Player::~Player()
	{
	}

	float Player::getGain()
	{
		xal::mgr->_lock();
		float gain = this->_getGain();
		xal::mgr->_unlock();
		return gain;
	}

	float Player::_getGain()
	{
		return this->gain;
	}

	void Player::setGain(float value)
	{
		xal::mgr->_lock();
		this->_setGain(value);
		xal::mgr->_unlock();
	}

	void Player::_setGain(float value)
	{
		this->gain = hclamp(value, 0.0f, 1.0f);
		this->_systemUpdateGain(this->_calcGain());
	}

	float Player::getPitch()
	{
		xal::mgr->_lock();
		float pitch = this->_getPitch();
		xal::mgr->_unlock();
		return pitch;
	}

	float Player::_getPitch()
	{
		return this->pitch;
	}

	void Player::setPitch(float value)
	{
		xal::mgr->_lock();
		this->_setPitch(value);
		xal::mgr->_unlock();
	}

	void Player::_setPitch(float value)
	{
		this->pitch = hclamp(value, 0.01f, 100.0f);
		this->_systemUpdatePitch();
	}

	float Player::getTimePosition()
	{
		return ((float)this->getSamplePosition() / this->buffer->getSamplingRate());
	}

	unsigned int Player::getSamplePosition()
	{
		xal::mgr->_lock();
		unsigned int position = this->_systemGetBufferPosition();
		if (this->sound->isStreamed())
		{
			// corrects position by using number of processed bytes (circular)
			position = (position + (STREAM_BUFFER_COUNT - this->bufferIndex) * STREAM_BUFFER_SIZE) % STREAM_BUFFER;
			// adds streamed processed byte count
			position += this->processedByteCount;
		}
		position = hmin(position, (unsigned int)this->sound->getSize());
		unsigned int samplePosition = (unsigned int)(position /
			(this->buffer->getChannels() * this->buffer->getBitsPerSample() * 0.125f));
		xal::mgr->_unlock();
		return samplePosition;
	}

	hstr Player::getName()
	{
		return this->sound->getName();
	}

	hstr Player::getFilename()
	{
		return this->sound->getFilename();
	}

	hstr Player::getRealFilename()
	{
		return this->sound->getRealFilename();
	}

    float Player::getDuration()
    {
        return this->buffer->getDuration();
    }

    int Player::getSize()
    {
		return this->buffer->getSize();
    }

	bool Player::isPlaying()
	{
		return (!this->isFadingOut() && this->_systemIsPlaying());
	}

	bool Player::isPaused()
	{
		return (this->paused && !this->isFading());
	}

	bool Player::isFading()
	{
		return (this->fadeSpeed != 0.0f);
	}

	bool Player::isFadingIn()
	{
		return (this->fadeSpeed > 0.0f);
	}

	bool Player::isFadingOut()
	{
		return (this->fadeSpeed < 0.0f);
	}

	Category* Player::getCategory()
	{
		return this->sound->getCategory();
	}

	void Player::_update(float k)
	{
		if (this->sound->isStreamed() && this->_systemIsPlaying())
		{
			this->processedByteCount += this->_systemUpdateStream();
		}
		if (this->isFading())
		{
			this->fadeTime += this->fadeSpeed * k;
			if (this->fadeTime >= 1.0f && this->fadeSpeed > 0.0f)
			{
				this->_setGain(this->gain);
				this->fadeTime = 1.0f;
				this->fadeSpeed = 0.0f;
			}
			else if (this->fadeTime <= 0.0f && this->fadeSpeed < 0.0f)
			{
				this->fadeTime = 0.0f;
				this->fadeSpeed = 0.0f;
				if (!this->paused)
				{
					this->_stop();
					return;
				}
				this->_pause();
			}
			else
			{
				this->_systemUpdateGain(this->_calcFadeGain());
			}
		}
	}

	void Player::play(float fadeTime, bool looping)
	{
		xal::mgr->_lock();
		this->_play(fadeTime, looping);
		xal::mgr->_unlock();
	}

	void Player::stop(float fadeTime)
	{
		xal::mgr->_lock();
		this->_stop(fadeTime);
		xal::mgr->_unlock();
	}

	void Player::pause(float fadeTime)
	{
		xal::mgr->_lock();
		this->_pause(fadeTime);
		xal::mgr->_unlock();
	}

	void Player::_play(float fadeTime, bool looping)
	{
		if (!xal::mgr->isEnabled())
		{
			return;
		}
		if (xal::mgr->isSuspended())
		{
			if (!xal::mgr->suspendedPlayers.contains(this))
			{
				xal::mgr->suspendedPlayers += this;
				if (!this->paused)
				{
					this->looping = looping;
					this->paused = true;
				}
			}
			return;
		}
		if (!this->_systemPreparePlay())
		{
			return;
		}
		if (!this->paused)
		{
			this->looping = looping;
		}
		bool alreadyFading = this->isFading();
		if (!alreadyFading && !this->_systemIsPlaying())
		{
			this->buffer->prepare();
			this->_systemPrepareBuffer();
			if (this->paused)
			{
				this->_systemSetOffset(this->offset);
			}
		}
		if (fadeTime > 0.0f)
		{
			this->fadeSpeed = 1.0f / fadeTime;
		}
		else
		{
			this->fadeTime = 1.0f;
			this->fadeSpeed = 0.0f;
		}
		this->_systemUpdateGain(this->_calcFadeGain());
		if (!alreadyFading)
		{
			this->_systemPlay();
		}
		this->paused = false;
	}

	void Player::_stop(float fadeTime)
	{
		if (xal::mgr->isSuspended() && xal::mgr->suspendedPlayers.contains(this))
		{
			xal::mgr->suspendedPlayers -= this;
		}
		this->paused = false;
		this->_stopSound(fadeTime);
		this->offset = 0.0f;
		this->processedByteCount = 0;
	}

	void Player::_pause(float fadeTime)
	{
		this->paused = true;
		this->_stopSound(fadeTime);
	}

	float Player::_calcGain()
	{
		return (this->gain * this->sound->getCategory()->getGain() * xal::mgr->getGlobalGain());
	}

	float Player::_calcFadeGain()
	{
		return (this->gain * this->sound->getCategory()->getGain() * xal::mgr->getGlobalGain() * this->fadeTime);
	}

	void Player::_stopSound(float fadeTime)
	{
		if (fadeTime > 0.0f)
		{
			this->fadeSpeed = -1.0f / fadeTime;
			return;
		}
		this->offset = this->_systemGetOffset();
		this->processedByteCount += this->_systemStop();
		this->buffer->release();
		this->fadeTime = 0.0f;
		this->fadeSpeed = 0.0f;
	}

}
<|endoftext|>


<commit_before>// cpsm - fuzzy path matcher
// Copyright (C) 2015 Jamie Liu
//
// 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 "matcher.h"

#include <algorithm>
#include <cstdint>
#include <limits>
#include <utility>

#include <boost/range/adaptor/reversed.hpp>

#include "path_util.h"
#include "str_util.h"

namespace cpsm {

Matcher::Matcher(boost::string_ref const query, MatcherOpts opts,
                 StringHandler strings)
    : opts_(std::move(opts)), strings_(std::move(strings)) {
  strings_.decode(query, query_);
  if (opts_.is_path) {
    // Store the index of the first character after the rightmost path
    // separator in the query. (Store an index rather than an iterator to keep
    // Matcher copyable/moveable.)
    query_key_begin_index_ =
        std::find(query_.crbegin(), query_.crend(), path_separator()).base() -
        query_.cbegin();
    switch (opts_.query_path_mode) {
      case MatcherOpts::QueryPathMode::NORMAL:
        require_full_part_ = false;
        break;
      case MatcherOpts::QueryPathMode::STRICT:
        require_full_part_ = true;
        break;
      case MatcherOpts::QueryPathMode::AUTO:
        require_full_part_ =
            (query.find_first_of(path_separator()) != std::string::npos);
        break;
    }
  } else {
    query_key_begin_index_ = 0;
    require_full_part_ = false;
  }

  // Queries are smartcased (case-sensitive only if any uppercase appears in the
  // query).
  is_case_sensitive_ =
      std::any_of(query_.begin(), query_.end(),
                  [&](char32_t const c) { return strings_.is_uppercase(c); });

  cur_file_parts_ = path_components_of(opts_.cur_file);
  if (!cur_file_parts_.empty()) {
    cur_file_key_ = cur_file_parts_.back();
    // Strip the extension from cur_file_key_, if any (but not the trailing .)
    auto const ext_sep_pos = cur_file_key_.find_last_of('.');
    if (ext_sep_pos != boost::string_ref::npos) {
      cur_file_key_ = cur_file_key_.substr(0, ext_sep_pos + 1);
    }
  }
}

bool Matcher::match_base(boost::string_ref const item, MatchBase& m,
                         std::set<CharCount>* match_positions,
                         std::vector<char32_t>* const buf,
                         std::vector<char32_t>* const buf2) const {
  m = MatchBase();

  std::vector<char32_t> key_chars_local;
  std::vector<char32_t>& key_chars = buf ? *buf : key_chars_local;
  std::vector<char32_t> temp_chars_local;
  std::vector<char32_t>& temp_chars = buf2 ? *buf2 : temp_chars_local;
  std::vector<CharCount> key_char_positions;
  std::vector<CharCount> temp_char_positions;

  std::vector<boost::string_ref> item_parts;
  if (opts_.is_path) {
    item_parts = path_components_of(item);
  } else {
    item_parts.push_back(item);
  }
  if (!item_parts.empty()) {
    m.unmatched_len = item_parts.back().size();
  }

  if (query_.empty()) {
    match_path(item_parts, m);
    return true;
  }

  // Since for paths (the common case) we prefer rightmost path components, we
  // scan path components right-to-left.
  auto query_it = query_.crbegin();
  auto const query_end = query_.crend();
  auto query_key_begin = query_.cend();
  // Index into item_parts, counting from the right.
  CharCount item_part_index = 0;
  // Offset of the beginning of the current item part from the beginning of the
  // item, in bytes.
  CharCount item_part_first_byte = item.size();
  std::set<CharCount> match_part_positions;
  for (boost::string_ref const item_part :
       boost::adaptors::reverse(item_parts)) {
    if (query_it == query_end) {
      break;
    }

    std::vector<char32_t>& item_part_chars =
        (item_part_index == 0) ? key_chars : temp_chars;
    item_part_chars.clear();
    std::vector<CharCount>* item_part_char_positions = nullptr;
    if (match_positions) {
      item_part_first_byte -= item_part.size();
      match_part_positions.clear();
      item_part_char_positions =
          (item_part_index == 0) ? &key_char_positions : &temp_char_positions;
      item_part_char_positions->clear();
    }
    strings_.decode(item_part, item_part_chars, item_part_char_positions);

    // Since path components are matched right-to-left, query characters must be
    // consumed greedily right-to-left.
    auto query_prev = query_it;
    for (auto it = item_part_chars.crbegin(), end = item_part_chars.crend();
         it != end; ++it) {
      if (match_char(*it, *query_it)) {
        // Don't store match positions for the key yet, since match_key will
        // refine them.
        if (match_positions && item_part_index != 0) {
          std::size_t const i =
              item_part_chars.size() - (it - item_part_chars.crbegin());
          CharCount begin = (*item_part_char_positions)[i - 1];
          CharCount end;
          if (i == item_part_chars.size()) {
            end = item_part.size();
          } else {
            end = (*item_part_char_positions)[i];
          }
          for (; begin < end; begin++) {
            match_part_positions.insert(item_part_first_byte + begin);
          }
        }
        ++query_it;
        if (query_it == query_end) {
          break;
        }
      }
    }

    // If strict query path mode is on, the match must have run to a path
    // separator. If not, discard the match.
    if (require_full_part_ &&
        !((query_it == query_end) || (*query_it == path_separator()))) {
      query_it = query_prev;
    }

    // Ok, done matching this part.
    if (query_it != query_prev) {
      m.parts++;
    }
    if (item_part_index == 0) {
      query_key_begin = query_it.base();
    }
    item_part_index++;
    if (match_positions) {
      for (auto const pos : match_part_positions) {
        match_positions->insert(pos);
      }
    }
  }

  // Did all characters match?
  if (query_it != query_end) {
    return false;
  }

  // Fill path match data.
  match_path(item_parts, m);

  // Now do more refined matching on the key (the rightmost path component of
  // the item for a path match, and just the full item otherwise).
  if (match_positions) {
    // Adjust key_char_positions to be relative to the beginning of the string
    // rather than the beginning of the key. item_parts can't be empty because
    // query is non-empty and matching was successful.
    CharCount const item_key_first_byte =
        item.size() - item_parts.back().size();
    for (auto& pos : key_char_positions) {
      pos += item_key_first_byte;
    }
    // Push item.size() to simplify key_char_positions indexing in match_key
    // and save an extra parameter.
    key_char_positions.push_back(item.size());
  }
  match_key(key_chars, query_key_begin, m, match_positions, key_char_positions);
  return true;
}

void Matcher::match_path(std::vector<boost::string_ref> const& item_parts,
                         MatchBase& m) const {
  if (!opts_.is_path) {
    return;
  }
  m.path_distance = path_distance_between(cur_file_parts_, item_parts);
  // We don't want to exclude cur_file as a match, but we also don't want it
  // to be the top match, so force cur_file_prefix_len to 0 for cur_file (i.e.
  // if path_distance is 0).
  if (m.path_distance != 0 && !item_parts.empty()) {
    m.cur_file_prefix_len = common_prefix(cur_file_key_, item_parts.back());
  }
}

void Matcher::match_key(
    std::vector<char32_t> const& key,
    std::vector<char32_t>::const_iterator const query_key, MatchBase& m,
    std::set<CharCount>* const match_positions,
    std::vector<CharCount> const& key_char_positions) const {
  auto const query_key_end = query_.cend();
  if (query_key == query_key_end) {
    return;
  }
  // key can't be empty since [query_key, query_.end()) is non-empty.
  const auto is_word_prefix = [&](std::size_t const i) -> bool {
    if (i == 0) {
      return true;
    }
    if (strings_.is_alphanumeric(key[i]) &&
        !strings_.is_alphanumeric(key[i - 1])) {
      return true;
    }
    if (strings_.is_uppercase(key[i]) && !strings_.is_uppercase(key[i - 1])) {
      return true;
    }
    return false;
  };

  // Attempt two matches. In the first pass, only match word prefixes and
  // non-alphanumeric characters to try and get a word prefix-only match. In
  // the second pass, match greedily.
  for (int pass = 0; pass < 2; pass++) {
    auto query_it = query_key;
    CharCount word_index = 0;
    CharCount2 word_index_sum = 0;
    CharCount word_prefix_len = 0;
    bool start_matched = false;
    bool at_word_start = true;
    bool word_matched = false;
    std::set<CharCount> match_positions_pass;
    for (std::size_t i = 0; i < key.size(); i++) {
      if (is_word_prefix(i)) {
        word_index++;
        at_word_start = true;
        word_matched = false;
      }
      if (pass == 0 && strings_.is_alphanumeric(*query_it) && !at_word_start) {
        continue;
      }
      if (match_char(key[i], *query_it)) {
        if (at_word_start) {
          word_prefix_len++;
        }
        if (!word_matched) {
          word_index_sum += word_index;
          word_matched = true;
        }
        if (i == 0) {
          start_matched = true;
        }
        if (match_positions) {
          CharCount begin = key_char_positions[i];
          CharCount const end = key_char_positions[i+1];
          for (; begin < end; begin++) {
            match_positions_pass.insert(begin);
          }
        }
        ++query_it;
        if (query_it == query_key_end) {
          auto const query_key_begin = query_.cbegin() + query_key_begin_index_;
          if (query_key != query_key_begin) {
            m.prefix_score = std::numeric_limits<CharCount2>::max();
            if (start_matched) {
              m.prefix_score = std::numeric_limits<CharCount2>::max() - 1;
            }
          } else if ((i + 1) == std::size_t(query_key_end - query_key_begin)) {
            m.prefix_score = 0;
          } else if (pass == 0) {
            m.prefix_score = word_index_sum;
          } else if (start_matched) {
            m.prefix_score = std::numeric_limits<CharCount2>::max() - 3;
          } else {
            m.prefix_score = std::numeric_limits<CharCount2>::max() - 2;
          }
          m.word_prefix_len = word_prefix_len;
          m.unmatched_len = key.size() - (i + 1);
          if (match_positions) {
            for (auto const pos : match_positions_pass) {
              match_positions->insert(pos);
            }
          }
          return;
        }
      } else {
        at_word_start = false;
      }
    }
  }
}

bool Matcher::match_char(char32_t item, char32_t const query) const {
  if (!is_case_sensitive_) {
    // The query must not contain any uppercase letters since otherwise the
    // query would be case-sensitive, so just force all uppercase characters to
    // lowercase.
    if (strings_.is_uppercase(item)) {
      item = strings_.to_lowercase(item);
    }
  }
  return item == query;
}

}  // namespace cpsm
<commit_msg>Fix repeated highlighting of path separators<commit_after>// cpsm - fuzzy path matcher
// Copyright (C) 2015 Jamie Liu
//
// 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 "matcher.h"

#include <algorithm>
#include <cstdint>
#include <limits>
#include <utility>

#include <boost/range/adaptor/reversed.hpp>

#include "path_util.h"
#include "str_util.h"

namespace cpsm {

Matcher::Matcher(boost::string_ref const query, MatcherOpts opts,
                 StringHandler strings)
    : opts_(std::move(opts)), strings_(std::move(strings)) {
  strings_.decode(query, query_);
  if (opts_.is_path) {
    // Store the index of the first character after the rightmost path
    // separator in the query. (Store an index rather than an iterator to keep
    // Matcher copyable/moveable.)
    query_key_begin_index_ =
        std::find(query_.crbegin(), query_.crend(), path_separator()).base() -
        query_.cbegin();
    switch (opts_.query_path_mode) {
      case MatcherOpts::QueryPathMode::NORMAL:
        require_full_part_ = false;
        break;
      case MatcherOpts::QueryPathMode::STRICT:
        require_full_part_ = true;
        break;
      case MatcherOpts::QueryPathMode::AUTO:
        require_full_part_ =
            (query.find_first_of(path_separator()) != std::string::npos);
        break;
    }
  } else {
    query_key_begin_index_ = 0;
    require_full_part_ = false;
  }

  // Queries are smartcased (case-sensitive only if any uppercase appears in the
  // query).
  is_case_sensitive_ =
      std::any_of(query_.begin(), query_.end(),
                  [&](char32_t const c) { return strings_.is_uppercase(c); });

  cur_file_parts_ = path_components_of(opts_.cur_file);
  if (!cur_file_parts_.empty()) {
    cur_file_key_ = cur_file_parts_.back();
    // Strip the extension from cur_file_key_, if any (but not the trailing .)
    auto const ext_sep_pos = cur_file_key_.find_last_of('.');
    if (ext_sep_pos != boost::string_ref::npos) {
      cur_file_key_ = cur_file_key_.substr(0, ext_sep_pos + 1);
    }
  }
}

bool Matcher::match_base(boost::string_ref const item, MatchBase& m,
                         std::set<CharCount>* match_positions,
                         std::vector<char32_t>* const buf,
                         std::vector<char32_t>* const buf2) const {
  m = MatchBase();

  std::vector<char32_t> key_chars_local;
  std::vector<char32_t>& key_chars = buf ? *buf : key_chars_local;
  std::vector<char32_t> temp_chars_local;
  std::vector<char32_t>& temp_chars = buf2 ? *buf2 : temp_chars_local;
  std::vector<CharCount> key_char_positions;
  std::vector<CharCount> temp_char_positions;

  std::vector<boost::string_ref> item_parts;
  if (opts_.is_path) {
    item_parts = path_components_of(item);
  } else {
    item_parts.push_back(item);
  }
  if (!item_parts.empty()) {
    m.unmatched_len = item_parts.back().size();
  }

  if (query_.empty()) {
    match_path(item_parts, m);
    return true;
  }

  // Since for paths (the common case) we prefer rightmost path components, we
  // scan path components right-to-left.
  auto query_it = query_.crbegin();
  auto const query_end = query_.crend();
  auto query_key_begin = query_.cend();
  // Index into item_parts, counting from the right.
  CharCount item_part_index = 0;
  // Offset of the beginning of the current item part from the beginning of the
  // item, in bytes.
  CharCount item_part_first_byte = item.size();
  std::set<CharCount> match_part_positions;
  for (boost::string_ref const item_part :
       boost::adaptors::reverse(item_parts)) {
    if (query_it == query_end) {
      break;
    }

    std::vector<char32_t>& item_part_chars =
        (item_part_index == 0) ? key_chars : temp_chars;
    item_part_chars.clear();
    std::vector<CharCount>* item_part_char_positions = nullptr;
    if (match_positions) {
      item_part_first_byte -= item_part.size();
      match_part_positions.clear();
      item_part_char_positions =
          (item_part_index == 0) ? &key_char_positions : &temp_char_positions;
      item_part_char_positions->clear();
    }
    strings_.decode(item_part, item_part_chars, item_part_char_positions);

    // Since path components are matched right-to-left, query characters must be
    // consumed greedily right-to-left.
    auto query_prev = query_it;
    for (auto it = item_part_chars.crbegin(), end = item_part_chars.crend();
         it != end; ++it) {
      if (match_char(*it, *query_it)) {
        // Don't store match positions for the key yet, since match_key will
        // refine them.
        if (match_positions && item_part_index != 0) {
          std::size_t const i =
              item_part_chars.size() - (it - item_part_chars.crbegin());
          CharCount begin = (*item_part_char_positions)[i - 1];
          CharCount end;
          if (i == item_part_chars.size()) {
            end = item_part.size();
          } else {
            end = (*item_part_char_positions)[i];
          }
          for (; begin < end; begin++) {
            match_part_positions.insert(item_part_first_byte + begin);
          }
        }
        ++query_it;
        if (query_it == query_end) {
          break;
        }
      }
    }

    // If strict query path mode is on, the match must have run to a path
    // separator. If not, discard the match.
    if (require_full_part_ &&
        !((query_it == query_end) || (*query_it == path_separator()))) {
      query_it = query_prev;
      if (match_positions) {
        match_part_positions.clear();
      }
    }

    // Ok, done matching this part.
    if (query_it != query_prev) {
      m.parts++;
    }
    if (item_part_index == 0) {
      query_key_begin = query_it.base();
    }
    item_part_index++;
    if (match_positions) {
      for (auto const pos : match_part_positions) {
        match_positions->insert(pos);
      }
    }
  }

  // Did all characters match?
  if (query_it != query_end) {
    return false;
  }

  // Fill path match data.
  match_path(item_parts, m);

  // Now do more refined matching on the key (the rightmost path component of
  // the item for a path match, and just the full item otherwise).
  if (match_positions) {
    // Adjust key_char_positions to be relative to the beginning of the string
    // rather than the beginning of the key. item_parts can't be empty because
    // query is non-empty and matching was successful.
    CharCount const item_key_first_byte =
        item.size() - item_parts.back().size();
    for (auto& pos : key_char_positions) {
      pos += item_key_first_byte;
    }
    // Push item.size() to simplify key_char_positions indexing in match_key
    // and save an extra parameter.
    key_char_positions.push_back(item.size());
  }
  match_key(key_chars, query_key_begin, m, match_positions, key_char_positions);
  return true;
}

void Matcher::match_path(std::vector<boost::string_ref> const& item_parts,
                         MatchBase& m) const {
  if (!opts_.is_path) {
    return;
  }
  m.path_distance = path_distance_between(cur_file_parts_, item_parts);
  // We don't want to exclude cur_file as a match, but we also don't want it
  // to be the top match, so force cur_file_prefix_len to 0 for cur_file (i.e.
  // if path_distance is 0).
  if (m.path_distance != 0 && !item_parts.empty()) {
    m.cur_file_prefix_len = common_prefix(cur_file_key_, item_parts.back());
  }
}

void Matcher::match_key(
    std::vector<char32_t> const& key,
    std::vector<char32_t>::const_iterator const query_key, MatchBase& m,
    std::set<CharCount>* const match_positions,
    std::vector<CharCount> const& key_char_positions) const {
  auto const query_key_end = query_.cend();
  if (query_key == query_key_end) {
    return;
  }
  // key can't be empty since [query_key, query_.end()) is non-empty.
  const auto is_word_prefix = [&](std::size_t const i) -> bool {
    if (i == 0) {
      return true;
    }
    if (strings_.is_alphanumeric(key[i]) &&
        !strings_.is_alphanumeric(key[i - 1])) {
      return true;
    }
    if (strings_.is_uppercase(key[i]) && !strings_.is_uppercase(key[i - 1])) {
      return true;
    }
    return false;
  };

  // Attempt two matches. In the first pass, only match word prefixes and
  // non-alphanumeric characters to try and get a word prefix-only match. In
  // the second pass, match greedily.
  for (int pass = 0; pass < 2; pass++) {
    auto query_it = query_key;
    CharCount word_index = 0;
    CharCount2 word_index_sum = 0;
    CharCount word_prefix_len = 0;
    bool start_matched = false;
    bool at_word_start = true;
    bool word_matched = false;
    std::set<CharCount> match_positions_pass;
    for (std::size_t i = 0; i < key.size(); i++) {
      if (is_word_prefix(i)) {
        word_index++;
        at_word_start = true;
        word_matched = false;
      }
      if (pass == 0 && strings_.is_alphanumeric(*query_it) && !at_word_start) {
        continue;
      }
      if (match_char(key[i], *query_it)) {
        if (at_word_start) {
          word_prefix_len++;
        }
        if (!word_matched) {
          word_index_sum += word_index;
          word_matched = true;
        }
        if (i == 0) {
          start_matched = true;
        }
        if (match_positions) {
          CharCount begin = key_char_positions[i];
          CharCount const end = key_char_positions[i+1];
          for (; begin < end; begin++) {
            match_positions_pass.insert(begin);
          }
        }
        ++query_it;
        if (query_it == query_key_end) {
          auto const query_key_begin = query_.cbegin() + query_key_begin_index_;
          if (query_key != query_key_begin) {
            m.prefix_score = std::numeric_limits<CharCount2>::max();
            if (start_matched) {
              m.prefix_score = std::numeric_limits<CharCount2>::max() - 1;
            }
          } else if ((i + 1) == std::size_t(query_key_end - query_key_begin)) {
            m.prefix_score = 0;
          } else if (pass == 0) {
            m.prefix_score = word_index_sum;
          } else if (start_matched) {
            m.prefix_score = std::numeric_limits<CharCount2>::max() - 3;
          } else {
            m.prefix_score = std::numeric_limits<CharCount2>::max() - 2;
          }
          m.word_prefix_len = word_prefix_len;
          m.unmatched_len = key.size() - (i + 1);
          if (match_positions) {
            for (auto const pos : match_positions_pass) {
              match_positions->insert(pos);
            }
          }
          return;
        }
      } else {
        at_word_start = false;
      }
    }
  }
}

bool Matcher::match_char(char32_t item, char32_t const query) const {
  if (!is_case_sensitive_) {
    // The query must not contain any uppercase letters since otherwise the
    // query would be case-sensitive, so just force all uppercase characters to
    // lowercase.
    if (strings_.is_uppercase(item)) {
      item = strings_.to_lowercase(item);
    }
  }
  return item == query;
}

}  // namespace cpsm
<|endoftext|>


<commit_before>// Copyright (c) 2016 ZZBGames
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef ZZB_CORE_TILESET_HPP
#define ZZB_CORE_TILESET_HPP

#include <string>

#include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/Texture.hpp>

#include <zzbgames/util/Dimension.hpp>
#include <zzbgames/util/Insets.hpp>

namespace zzbgames {

namespace tiles {

/**
 * @brief The Tileset class represents an image split in a tile grid.
 */
class Tileset {
public:
    /**
     * @brief Creates a new Tileset object from a file.
     *
     * @param filename The name of the tileset image file.
     * @param tileSize The size of each tile in pixels.
     * @param margin The inner margin of this tileset.
     * @param spacing The spacing between each tile in pixels.
     *
     * @throw std::ios_base::failure if the loading of the image fails.
     */
    Tileset(const std::string &filename, const util::Dimension &tileSize, const util::Insets &margin,
            const util::Insets &spacing);

    ~Tileset();

    /**
     * ]brief Returns the number of tiles of this tileset.
     *
     * @return The number of tiles of this tileset.
     */
    unsigned long tileCount() const;

private:
    /**
     * @brief Computes and initializes the grid size.
     */
    void computeGridSize();

private:
    /// \brief The size of this tileset in squares.
    util::Dimension m_gridSize;

    /// @brief The image used by this tileset.
    sf::Image m_image;

    /// @brief The inner margin of this tileset.
    util::Insets m_margin;

    /// @brief The spacing between each tile in pixels.
    util::Insets m_spacing;

    /// @brief The texture used by this tileset.
    sf::Texture m_texture;

    /// @brief The size of each tile in pixels.
    util::Dimension m_tileSize;
};

}

}

#endif //ZZB_CORE_TILESET_HPP
<commit_msg>Fix docs<commit_after>// Copyright (c) 2016 ZZBGames
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef ZZB_CORE_TILESET_HPP
#define ZZB_CORE_TILESET_HPP

#include <string>

#include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/Texture.hpp>

#include <zzbgames/util/Dimension.hpp>
#include <zzbgames/util/Insets.hpp>

namespace zzbgames {

namespace tiles {

/**
 * @brief The Tileset class represents an image split in a tile grid.
 */
class Tileset {
public:
    /**
     * @brief Creates a new Tileset object from a file.
     *
     * @param filename The name of the tileset image file.
     * @param tileSize The size of each tile in pixels.
     * @param margin The inner margin of this tileset.
     * @param spacing The spacing between each tile in pixels.
     *
     * @throw std::ios_base::failure if the loading of the image fails.
     */
    Tileset(const std::string &filename, const util::Dimension &tileSize, const util::Insets &margin,
            const util::Insets &spacing);

    ~Tileset();

    /**
     * @brief Returns the number of tiles of this tileset.
     *
     * @return The number of tiles of this tileset.
     */
    unsigned long tileCount() const;

private:
    /**
     * @brief Computes and initializes the grid size.
     */
    void computeGridSize();

private:
    /// @brief The size of this tileset in squares.
    util::Dimension m_gridSize;

    /// @brief The image used by this tileset.
    sf::Image m_image;

    /// @brief The inner margin of this tileset.
    util::Insets m_margin;

    /// @brief The spacing between each tile in pixels.
    util::Insets m_spacing;

    /// @brief The texture used by this tileset.
    sf::Texture m_texture;

    /// @brief The size of each tile in pixels.
    util::Dimension m_tileSize;
};

}

}

#endif //ZZB_CORE_TILESET_HPP
<|endoftext|>