NasNas
An intuitive and beginner friendly 2D game framework for C++
core/Layer.hpp
1 
6 #pragma once
7 
8 #include <functional>
9 #include <iostream>
10 #include <limits>
11 #include <memory>
12 #include <string>
13 #include <type_traits>
14 #include <unordered_map>
15 #include <vector>
16 
17 #include <SFML/Graphics/Drawable.hpp>
18 #include <SFML/Graphics/Rect.hpp>
19 #include <SFML/System/Vector2.hpp>
20 
21 #include <NasNas/core/data/Introspection.hpp>
22 
23 namespace ns {
24  class Scene;
25 
26  class Layer {
27  public:
36  explicit Layer(std::string name);
37 
38  Layer(const Layer&) = delete;
39  Layer(Layer&&) = default;
40  Layer& operator=(const Layer&) = delete;
41  Layer& operator=(Layer&&) = default;
42 
46  void clear();
47 
53  template <typename T, typename = std::enable_if_t<std::is_base_of_v<sf::Drawable, T>>>
54  void add(const T& dr);
55 
56  template <typename T, typename = std::enable_if_t<std::is_pointer_v<T>>, typename = std::enable_if_t<std::is_base_of_v<sf::Drawable, std::remove_pointer_t<T>>>>
57  void add(T dr);
58 
66  template <typename T, typename = std::enable_if_t<std::is_pointer_v<T>>, typename = std::enable_if_t<std::is_base_of_v<sf::Drawable, std::remove_pointer_t<T>>>>
67  void addRaw(T dr);
68 
74  template <typename T, typename = std::enable_if_t<std::is_base_of_v<sf::Drawable, T>>>
75  void remove(const T& dr);
76 
77  template <typename T, typename = std::enable_if_t<std::is_pointer_v<T>>, typename = std::enable_if_t<std::is_base_of_v<sf::Drawable, std::remove_pointer_t<T>>>>
78  void remove(T dr);
79 
85  auto allDrawables() const -> const std::vector<const sf::Drawable*>&;
86 
87  auto getDrawablePosition(const sf::Drawable* dr) const -> sf::Vector2f;
88  auto getDrawableBounds(const sf::Drawable* dr) const -> sf::FloatRect;
89 
95  void ySort();
96 
102  auto getName() const -> const std::string&;
103 
104  private:
105  std::string m_name;
106  std::vector<const sf::Drawable*> m_drawables;
107  std::vector<std::unique_ptr<const sf::Drawable>> m_gc;
108  std::unordered_map<const sf::Drawable*, std::function<sf::Vector2f()>> m_position_getters;
109  std::unordered_map<const sf::Drawable*, std::function<sf::FloatRect()>> m_bounds_getters;
110  };
111 
112  template <typename T, typename>
113  void Layer::add(const T& dr) {
114  static constexpr auto float_min = std::numeric_limits<float>::lowest();
115  static constexpr auto float_max = std::numeric_limits<float>::max();
116 
117  m_drawables.emplace_back(&dr);
118  if constexpr(introspect::has_getPosition_v<T>)
119  m_position_getters[&dr] = [&dr]() { return dr.getPosition(); };
120  else
121  m_position_getters[&dr] = []() { return sf::Vector2f{0, float_min}; };
122 
123  if constexpr(introspect::has_getGlobalBounds_v<T>)
124  m_bounds_getters[&dr] = [&dr]() { return dr.getGlobalBounds(); };
125  else if constexpr(introspect::has_getBounds_v<T>)
126  m_bounds_getters[&dr] = [&dr]() { return dr.getBounds(); };
127  else
128  m_bounds_getters[&dr] = []() { return sf::FloatRect(float_min/2.f, float_min/2.f, float_max, float_max); };
129  }
130 
131  template <typename T, typename, typename>
132  void Layer::add(const T dr) {
133  add(*dr);
134  m_gc.emplace_back(dr);
135  }
136 
137  template <typename T, typename, typename>
138  void Layer::addRaw(const T dr) {
139  add(*dr);
140  }
141 
142  template <typename T, typename>
143  void Layer::remove(const T& dr) {
144  auto it = std::find(m_drawables.begin(), m_drawables.end(), &dr);
145  if (it != m_drawables.end()) {
146  m_drawables.erase(it);
147  m_position_getters.erase(&dr);
148  m_bounds_getters.erase(&dr);
149  }
150  else
151  std::cout << "Warning : trying to remove a non existent drawable from Layer.\n";
152  }
153 
154  template <typename T, typename, typename>
155  void Layer::remove(const T dr) {
156  remove(*dr);
157  m_gc.erase(
158  std::remove_if(m_gc.begin(), m_gc.end(), [dr](auto& uptr) { return uptr.get() == dr; }),
159  m_gc.end()
160  );
161  }
162 
163 }
void add(const T &dr)
Add a drawable to the Layer.
Definition: core/Layer.hpp:113
void clear()
Removes all the drawables.
void ySort()
Sorts Layer drawables by their Y coordinate.
auto allDrawables() const -> const std::vector< const sf::Drawable *> &
Get a vector of all drawables added to the Layer.
Layer(std::string name)
Construct a Layer object.
void remove(const T &dr)
Remove a drawable from the Layer.
Definition: core/Layer.hpp:143
auto getName() const -> const std::string &
Get the name of the Layer.
void addRaw(T dr)
Add a drawable to the layer The pointer is not managed by the Layer, and you have to delete it manual...
Definition: core/Layer.hpp:138