1// SuperTux
2// Copyright (C) 2018 Ingo Ruhnke <grumbel@gmail.com>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#ifndef HEADER_SUPERTUX_SUPERTUX_GAME_OBJECT_ITERATOR_HPP
18#define HEADER_SUPERTUX_SUPERTUX_GAME_OBJECT_ITERATOR_HPP
19
20#include <vector>
21
22#include "game_object_manager.hpp"
23
24template<typename T>
25class GameObjectIterator
26{
27public:
28 typedef std::vector<std::unique_ptr<GameObject> >::const_iterator Iterator;
29
30public:
31 GameObjectIterator(Iterator it, Iterator end) :
32 m_it(it),
33 m_end(end),
34 m_object()
35 {
36 if (m_it != m_end)
37 {
38 m_object = dynamic_cast<T*>(m_it->get());
39 if (!m_object)
40 {
41 skip_to_next();
42 }
43 }
44 }
45
46 GameObjectIterator& operator++()
47 {
48 skip_to_next();
49 return *this;
50 }
51
52 GameObjectIterator operator++(int)
53 {
54 GameObjectIterator tmp(*this);
55 skip_to_next();
56 return tmp;
57 }
58
59 T* operator->() {
60 return m_object;
61 }
62
63 const T* operator->() const {
64 return m_object;
65 }
66
67 T& operator*() const {
68 return *m_object;
69 }
70
71 T& operator*() {
72 return *m_object;
73 }
74
75 bool operator==(const GameObjectIterator& other) const
76 {
77 return m_it == other.m_it;
78 }
79
80 bool operator!=(const GameObjectIterator& other) const
81 {
82 return !(*this == other);
83 }
84
85private:
86 void skip_to_next()
87 {
88 do
89 {
90 ++m_it;
91 if (m_it == m_end)
92 {
93 break;
94 }
95 else
96 {
97 m_object = dynamic_cast<T*>(m_it->get());
98 }
99 }
100 while (!m_object);
101 }
102
103private:
104 Iterator m_it;
105 Iterator m_end;
106 T* m_object;
107};
108
109template<typename T>
110class GameObjectRange
111{
112public:
113 GameObjectRange(const GameObjectManager& manager) :
114 m_manager(manager)
115 {}
116
117 GameObjectIterator<T> begin() const {
118 return GameObjectIterator<T>(m_manager.get_objects().begin(), m_manager.get_objects().end());
119 }
120
121 GameObjectIterator<T> end() const {
122 return GameObjectIterator<T>(m_manager.get_objects().end(), m_manager.get_objects().end());
123 }
124
125private:
126 const GameObjectManager& m_manager;
127};
128
129#endif
130
131/* EOF */
132