diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2019-02-23 12:02:00 -0500 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2019-02-23 12:02:00 -0500 |
commit | 15b511e694f976686fdec1fb9f959f8a92f3b594 (patch) | |
tree | 18c0a234bbbfd34592a371d15dbfbecbede906c8 | |
parent | 26fbd8c1edaf94513d9750681edbe449b699efe4 (diff) | |
download | dispatcher-15b511e694f976686fdec1fb9f959f8a92f3b594.tar.gz dispatcher-15b511e694f976686fdec1fb9f959f8a92f3b594.tar.bz2 dispatcher-15b511e694f976686fdec1fb9f959f8a92f3b594.zip |
More ranges stuff! Now with custom views
-rw-r--r-- | src/entity.h | 11 | ||||
-rw-r--r-- | src/renderer.cpp | 4 | ||||
-rw-r--r-- | src/simulation.cpp | 231 | ||||
-rw-r--r-- | src/simulation.h | 19 | ||||
-rw-r--r-- | src/views.h | 62 |
5 files changed, 200 insertions, 127 deletions
diff --git a/src/entity.h b/src/entity.h index c47f1e7..3387219 100644 --- a/src/entity.h +++ b/src/entity.h | |||
@@ -2,13 +2,24 @@ | |||
2 | #define ENTITY_H_0D6CB29A | 2 | #define ENTITY_H_0D6CB29A |
3 | 3 | ||
4 | #include <set> | 4 | #include <set> |
5 | #include <vector> | ||
5 | #include "vector.h" | 6 | #include "vector.h" |
6 | #include "enums.h" | 7 | #include "enums.h" |
7 | #include "direction.h" | 8 | #include "direction.h" |
8 | 9 | ||
10 | class Entity; | ||
11 | |||
12 | using id_type = std::vector<Entity>::size_type; | ||
13 | |||
9 | class Entity { | 14 | class Entity { |
10 | public: | 15 | public: |
11 | 16 | ||
17 | Entity(id_type id) : id(id) | ||
18 | { | ||
19 | } | ||
20 | |||
21 | id_type id; | ||
22 | |||
12 | // Transform | 23 | // Transform |
13 | vec2s pos; | 24 | vec2s pos; |
14 | vec2s size; | 25 | vec2s size; |
diff --git a/src/renderer.cpp b/src/renderer.cpp index 64b3a8e..0feee50 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp | |||
@@ -76,10 +76,8 @@ void Renderer::render(const Simulation& sim) | |||
76 | } | 76 | } |
77 | } | 77 | } |
78 | 78 | ||
79 | for (Simulation::id_type id : sim.getActive()) | 79 | for (const Entity& entity : sim.getActive() | sim.entityView()) |
80 | { | 80 | { |
81 | const Entity& entity = sim.getEntity(id); | ||
82 | |||
83 | SDL_SetRenderDrawColor(ren_.get(), entity.colorVal, entity.colorVal, 65, 255); | 81 | SDL_SetRenderDrawColor(ren_.get(), entity.colorVal, entity.colorVal, 65, 255); |
84 | 82 | ||
85 | SDL_Rect rect { | 83 | SDL_Rect rect { |
diff --git a/src/simulation.cpp b/src/simulation.cpp index 77a9a3e..f75bd3d 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp | |||
@@ -1,8 +1,8 @@ | |||
1 | #include "simulation.h" | 1 | #include "simulation.h" |
2 | 2 | ||
3 | #include <range/v3/all.hpp> | ||
4 | #include "consts.h" | 3 | #include "consts.h" |
5 | #include "level.h" | 4 | #include "level.h" |
5 | #include "views.h" | ||
6 | 6 | ||
7 | Simulation::Simulation( | 7 | Simulation::Simulation( |
8 | const Level& level) : | 8 | const Level& level) : |
@@ -61,14 +61,14 @@ Simulation::Simulation( | |||
61 | train.gridPos = vec2s { 6, 1 }; | 61 | train.gridPos = vec2s { 6, 1 }; |
62 | train.moveDir = Direction::left; | 62 | train.moveDir = Direction::left; |
63 | 63 | ||
64 | id_type player = emplaceEntity(); | 64 | id_type playerId = emplaceEntity(); |
65 | Entity& entity = getEntity(player); | 65 | Entity& player = getEntity(playerId); |
66 | entity.size = TILE_SIZE; | 66 | player.size = TILE_SIZE; |
67 | entity.speed = 3.0; | 67 | player.speed = 3.0; |
68 | entity.controllable = true; | 68 | player.controllable = true; |
69 | entity.colliderType = ColliderType::player; | 69 | player.colliderType = ColliderType::player; |
70 | entity.colorVal = 180; | 70 | player.colorVal = 180; |
71 | entity.gridPos = vec2s { 1, 5 }; | 71 | player.gridPos = vec2s { 1, 5 }; |
72 | 72 | ||
73 | id_type crateId = emplaceEntity(); | 73 | id_type crateId = emplaceEntity(); |
74 | Entity& crate = getEntity(crateId); | 74 | Entity& crate = getEntity(crateId); |
@@ -91,11 +91,9 @@ Simulation::Simulation( | |||
91 | crate2.gridPos = vec2s { 6, 7 }; | 91 | crate2.gridPos = vec2s { 6, 7 }; |
92 | 92 | ||
93 | 93 | ||
94 | for (id_type id : active_) | 94 | for (Entity& entity : active_ | entityView()) |
95 | { | 95 | { |
96 | Entity& entity = entities_.at(id); | 96 | posCache_.set(entity.id, entity.gridPos); |
97 | |||
98 | posCache_.set(id, entity.gridPos); | ||
99 | } | 97 | } |
100 | } | 98 | } |
101 | 99 | ||
@@ -104,75 +102,73 @@ void Simulation::tick( | |||
104 | const Uint8* keystate) | 102 | const Uint8* keystate) |
105 | { | 103 | { |
106 | // Control | 104 | // Control |
107 | for (id_type id : active_) | 105 | for (Entity& entity : |
106 | active_ | | ||
107 | entityView() | | ||
108 | views::isControllable() | | ||
109 | views::isNotMoving()) | ||
108 | { | 110 | { |
109 | Entity& entity = entities_.at(id); | 111 | if (keystate[SDL_SCANCODE_LSHIFT] || keystate[SDL_SCANCODE_RSHIFT]) |
110 | |||
111 | if (entity.controllable && | ||
112 | !entity.moving) | ||
113 | { | 112 | { |
114 | if (keystate[SDL_SCANCODE_LSHIFT] || keystate[SDL_SCANCODE_RSHIFT]) | 113 | Direction lookDir = Direction::none; |
115 | { | ||
116 | Direction lookDir = Direction::none; | ||
117 | 114 | ||
118 | if (keystate[SDL_SCANCODE_LEFT]) | 115 | if (keystate[SDL_SCANCODE_LEFT]) |
119 | { | 116 | { |
120 | lookDir = Direction::left; | 117 | lookDir = Direction::left; |
121 | } | 118 | } |
122 | else if (keystate[SDL_SCANCODE_UP]) | 119 | else if (keystate[SDL_SCANCODE_UP]) |
123 | { | 120 | { |
124 | lookDir = Direction::up; | 121 | lookDir = Direction::up; |
125 | } | 122 | } |
126 | else if (keystate[SDL_SCANCODE_RIGHT]) | 123 | else if (keystate[SDL_SCANCODE_RIGHT]) |
127 | { | 124 | { |
128 | lookDir = Direction::right; | 125 | lookDir = Direction::right; |
129 | } | 126 | } |
130 | else if (keystate[SDL_SCANCODE_DOWN]) | 127 | else if (keystate[SDL_SCANCODE_DOWN]) |
131 | { | 128 | { |
132 | lookDir = Direction::down; | 129 | lookDir = Direction::down; |
133 | } | 130 | } |
134 | |||
135 | vec2s lookPos = posInDir(entity.gridPos, lookDir); | ||
136 | 131 | ||
137 | for (id_type blockId : posCache_.at(lookPos)) | 132 | vec2s lookPos = posInDir(entity.gridPos, lookDir); |
138 | { | ||
139 | Entity& block = entities_.at(blockId); | ||
140 | 133 | ||
141 | if (!block.moving && block.canBePushedBy.count(ColliderType::player)) | 134 | for (Entity& block : |
142 | { | 135 | posCache_.at(lookPos) | |
143 | moveEntityOnGrid(blockId, lookDir); | 136 | entityView() | |
144 | } | 137 | views::isNotMoving() | |
145 | } | 138 | views::canBePushedBy(entity.colliderType) | |
146 | } else { | 139 | views::isOnLayer(entity.layer)) |
147 | if (keystate[SDL_SCANCODE_LEFT] && | 140 | { |
148 | moveEntityOnGrid(id, Direction::left, true)) | 141 | moveEntityOnGrid(block, lookDir); |
149 | { | 142 | } |
150 | entity.shouldMoveTo = Direction::left; | 143 | } else { |
151 | } | 144 | if (keystate[SDL_SCANCODE_LEFT] && |
152 | else if (keystate[SDL_SCANCODE_UP] && | 145 | moveEntityOnGrid(entity, Direction::left, true)) |
153 | moveEntityOnGrid(id, Direction::up, true)) | 146 | { |
154 | { | 147 | entity.shouldMoveTo = Direction::left; |
155 | entity.shouldMoveTo = Direction::up; | 148 | } |
156 | } | 149 | else if (keystate[SDL_SCANCODE_UP] && |
157 | else if (keystate[SDL_SCANCODE_RIGHT] && | 150 | moveEntityOnGrid(entity, Direction::up, true)) |
158 | moveEntityOnGrid(id, Direction::right, true)) | 151 | { |
159 | { | 152 | entity.shouldMoveTo = Direction::up; |
160 | entity.shouldMoveTo = Direction::right; | 153 | } |
161 | } | 154 | else if (keystate[SDL_SCANCODE_RIGHT] && |
162 | else if (keystate[SDL_SCANCODE_DOWN] && | 155 | moveEntityOnGrid(entity, Direction::right, true)) |
163 | moveEntityOnGrid(id, Direction::down, true)) | 156 | { |
164 | { | 157 | entity.shouldMoveTo = Direction::right; |
165 | entity.shouldMoveTo = Direction::down; | 158 | } |
166 | } | 159 | else if (keystate[SDL_SCANCODE_DOWN] && |
167 | else | 160 | moveEntityOnGrid(entity, Direction::down, true)) |
168 | { | 161 | { |
169 | entity.shouldMoveTo = Direction::none; | 162 | entity.shouldMoveTo = Direction::down; |
170 | } | 163 | } |
164 | else | ||
165 | { | ||
166 | entity.shouldMoveTo = Direction::none; | ||
167 | } | ||
171 | 168 | ||
172 | if (entity.shouldMoveTo != Direction::none) | 169 | if (entity.shouldMoveTo != Direction::none) |
173 | { | 170 | { |
174 | moveEntityOnGrid(id, entity.shouldMoveTo); | 171 | moveEntityOnGrid(entity, entity.shouldMoveTo); |
175 | } | ||
176 | } | 172 | } |
177 | } | 173 | } |
178 | } | 174 | } |
@@ -182,34 +178,33 @@ void Simulation::tick( | |||
182 | 178 | ||
183 | if (schedule_.step()) | 179 | if (schedule_.step()) |
184 | { | 180 | { |
185 | for (id_type id : active_) | 181 | for (Entity& entity : |
182 | active_ | | ||
183 | entityView() | | ||
184 | views::isScheduled() | | ||
185 | views::isNotMoving()) | ||
186 | { | 186 | { |
187 | Entity& entity = entities_.at(id); | 187 | auto tracks = |
188 | posCache_.at(entity.gridPos) | | ||
189 | entityView() | | ||
190 | views::isTrack(); | ||
188 | 191 | ||
189 | if (entity.scheduled && !entity.moving) | 192 | if (!ranges::empty(tracks)) |
190 | { | 193 | { |
191 | auto tracks = | 194 | Entity& track = ranges::front(tracks); |
192 | posCache_.at(entity.gridPos) | | ||
193 | ranges::view::transform([&] (id_type id) -> Entity& { return entities_.at(id); }) | | ||
194 | ranges::view::filter([&] (Entity& other) { return other.isTrack; }); | ||
195 | |||
196 | if (!ranges::empty(tracks)) | ||
197 | { | ||
198 | Entity& track = ranges::front(tracks); | ||
199 | |||
200 | Direction dir = Direction::none; | ||
201 | Direction from = oppositeDir(entity.moveDir); | ||
202 | 195 | ||
203 | if (from == track.trackDir1) | 196 | Direction dir = Direction::none; |
204 | { | 197 | Direction from = oppositeDir(entity.moveDir); |
205 | dir = track.trackDir2; | ||
206 | } else if (from == track.trackDir2) | ||
207 | { | ||
208 | dir = track.trackDir1; | ||
209 | } | ||
210 | 198 | ||
211 | moveEntityOnGrid(id, dir); | 199 | if (from == track.trackDir1) |
200 | { | ||
201 | dir = track.trackDir2; | ||
202 | } else if (from == track.trackDir2) | ||
203 | { | ||
204 | dir = track.trackDir1; | ||
212 | } | 205 | } |
206 | |||
207 | moveEntityOnGrid(entity, dir); | ||
213 | } | 208 | } |
214 | } | 209 | } |
215 | } | 210 | } |
@@ -226,10 +221,10 @@ void Simulation::tick( | |||
226 | 221 | ||
227 | 222 | ||
228 | // Movement | 223 | // Movement |
229 | for (id_type id : active_) | 224 | for (Entity& entity : |
225 | active_ | | ||
226 | entityView()) | ||
230 | { | 227 | { |
231 | Entity& entity = entities_.at(id); | ||
232 | |||
233 | if (entity.moving) | 228 | if (entity.moving) |
234 | { | 229 | { |
235 | entity.movementTween += entity.speed * dt; | 230 | entity.movementTween += entity.speed * dt; |
@@ -238,8 +233,8 @@ void Simulation::tick( | |||
238 | { | 233 | { |
239 | entity.moving = false; | 234 | entity.moving = false; |
240 | entity.gridPos = entity.destPos; | 235 | entity.gridPos = entity.destPos; |
241 | posCache_.set(id, entity.gridPos); | 236 | posCache_.set(entity.id, entity.gridPos); |
242 | moveToCache_.remove(id); | 237 | moveToCache_.remove(entity.id); |
243 | } | 238 | } |
244 | } | 239 | } |
245 | 240 | ||
@@ -258,7 +253,7 @@ void Simulation::tick( | |||
258 | } | 253 | } |
259 | } | 254 | } |
260 | 255 | ||
261 | Simulation::id_type Simulation::emplaceEntity() | 256 | id_type Simulation::emplaceEntity() |
262 | { | 257 | { |
263 | id_type nextId; | 258 | id_type nextId; |
264 | 259 | ||
@@ -267,10 +262,10 @@ Simulation::id_type Simulation::emplaceEntity() | |||
267 | nextId = available_.front(); | 262 | nextId = available_.front(); |
268 | available_.pop_front(); | 263 | available_.pop_front(); |
269 | 264 | ||
270 | entities_.at(nextId) = Entity(); | 265 | entities_.at(nextId) = Entity(nextId); |
271 | } else { | 266 | } else { |
272 | nextId = entities_.size(); | 267 | nextId = entities_.size(); |
273 | entities_.emplace_back(); | 268 | entities_.emplace_back(nextId); |
274 | } | 269 | } |
275 | 270 | ||
276 | active_.insert(nextId); | 271 | active_.insert(nextId); |
@@ -285,14 +280,12 @@ void Simulation::deleteEntity(id_type id) | |||
285 | } | 280 | } |
286 | 281 | ||
287 | bool Simulation::moveEntityOnGrid( | 282 | bool Simulation::moveEntityOnGrid( |
288 | id_type id, | 283 | Entity& entity, |
289 | Direction moveDir, | 284 | Direction moveDir, |
290 | bool validate) | 285 | bool validate) |
291 | { | 286 | { |
292 | bool actuallyMove = true; | 287 | bool actuallyMove = true; |
293 | 288 | ||
294 | Entity& entity = entities_.at(id); | ||
295 | |||
296 | vec2s shouldMoveTo = posInDir(entity.gridPos, moveDir); | 289 | vec2s shouldMoveTo = posInDir(entity.gridPos, moveDir); |
297 | 290 | ||
298 | switch (moveDir) | 291 | switch (moveDir) |
@@ -348,21 +341,17 @@ bool Simulation::moveEntityOnGrid( | |||
348 | // Can't move into a space that something else is already moving into. | 341 | // Can't move into a space that something else is already moving into. |
349 | if (!ranges::empty( | 342 | if (!ranges::empty( |
350 | moveToCache_.at(shouldMoveTo) | | 343 | moveToCache_.at(shouldMoveTo) | |
351 | ranges::view::transform([&] (id_type id) -> Entity& { return entities_.at(id); }) | | 344 | entityView() | |
352 | ranges::view::filter([&] (Entity& other) { return other.layer == entity.layer; }))) | 345 | views::isOnLayer(entity.layer))) |
353 | { | 346 | { |
354 | return false; | 347 | return false; |
355 | } | 348 | } |
356 | 349 | ||
357 | for (id_type blockId : posCache_.at(shouldMoveTo)) | 350 | for (Entity& block : |
351 | posCache_.at(shouldMoveTo) | | ||
352 | entityView() | | ||
353 | views::isOnLayer(entity.layer)) | ||
358 | { | 354 | { |
359 | Entity& block = entities_.at(blockId); | ||
360 | |||
361 | if (block.layer != entity.layer) | ||
362 | { | ||
363 | continue; | ||
364 | } | ||
365 | |||
366 | if (!block.moving) | 355 | if (!block.moving) |
367 | { | 356 | { |
368 | if (!block.canBePushedBy.count(entity.colliderType)) | 357 | if (!block.canBePushedBy.count(entity.colliderType)) |
@@ -370,7 +359,7 @@ bool Simulation::moveEntityOnGrid( | |||
370 | return false; | 359 | return false; |
371 | } | 360 | } |
372 | 361 | ||
373 | if (!moveEntityOnGrid(blockId, moveDir, validate)) | 362 | if (!moveEntityOnGrid(block, moveDir, validate)) |
374 | { | 363 | { |
375 | return false; | 364 | return false; |
376 | } | 365 | } |
@@ -401,7 +390,7 @@ bool Simulation::moveEntityOnGrid( | |||
401 | entity.movementTween = 0.0; | 390 | entity.movementTween = 0.0; |
402 | entity.moveDir = moveDir; | 391 | entity.moveDir = moveDir; |
403 | 392 | ||
404 | moveToCache_.set(id, entity.destPos); | 393 | moveToCache_.set(entity.id, entity.destPos); |
405 | } | 394 | } |
406 | 395 | ||
407 | return true; | 396 | return true; |
diff --git a/src/simulation.h b/src/simulation.h index fbe0a43..a205796 100644 --- a/src/simulation.h +++ b/src/simulation.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include "renderer.h" | 5 | #include "renderer.h" |
6 | #include "schedule.h" | 6 | #include "schedule.h" |
7 | #include "grid_cache.h" | 7 | #include "grid_cache.h" |
8 | #include <range/v3/all.hpp> | ||
8 | #include <vector> | 9 | #include <vector> |
9 | #include <deque> | 10 | #include <deque> |
10 | #include <set> | 11 | #include <set> |
@@ -14,8 +15,6 @@ class Level; | |||
14 | class Simulation { | 15 | class Simulation { |
15 | public: | 16 | public: |
16 | 17 | ||
17 | using id_type = std::vector<Entity>::size_type; | ||
18 | |||
19 | // Constructor | 18 | // Constructor |
20 | explicit Simulation(const Level& level); | 19 | explicit Simulation(const Level& level); |
21 | 20 | ||
@@ -47,13 +46,27 @@ public: | |||
47 | return level_; | 46 | return level_; |
48 | } | 47 | } |
49 | 48 | ||
49 | auto entityView() | ||
50 | { | ||
51 | return ranges::view::transform([&] (id_type id) -> Entity& { | ||
52 | return entities_.at(id); | ||
53 | }); | ||
54 | } | ||
55 | |||
56 | auto entityView() const | ||
57 | { | ||
58 | return ranges::view::transform([&] (id_type id) -> const Entity& { | ||
59 | return entities_.at(id); | ||
60 | }); | ||
61 | } | ||
62 | |||
50 | private: | 63 | private: |
51 | 64 | ||
52 | 65 | ||
53 | 66 | ||
54 | 67 | ||
55 | bool moveEntityOnGrid( | 68 | bool moveEntityOnGrid( |
56 | id_type id, | 69 | Entity& entity, |
57 | Direction moveDir, | 70 | Direction moveDir, |
58 | bool validate = false); | 71 | bool validate = false); |
59 | 72 | ||
diff --git a/src/views.h b/src/views.h new file mode 100644 index 0000000..69bd2b5 --- /dev/null +++ b/src/views.h | |||
@@ -0,0 +1,62 @@ | |||
1 | #ifndef VIEWS_H_98651096 | ||
2 | #define VIEWS_H_98651096 | ||
3 | |||
4 | #include "entity.h" | ||
5 | #include <range/v3/all.hpp> | ||
6 | |||
7 | namespace views { | ||
8 | |||
9 | inline auto isMoving() | ||
10 | { | ||
11 | return ranges::view::filter([] (const Entity& entity) { | ||
12 | return entity.moving; | ||
13 | }); | ||
14 | } | ||
15 | |||
16 | inline auto isNotMoving() | ||
17 | { | ||
18 | return ranges::view::filter([] (const Entity& entity) { | ||
19 | return !entity.moving; | ||
20 | }); | ||
21 | } | ||
22 | |||
23 | inline auto isControllable() | ||
24 | { | ||
25 | return ranges::view::filter([] (const Entity& entity) { | ||
26 | return entity.controllable; | ||
27 | }); | ||
28 | } | ||
29 | |||
30 | inline auto isTrack() | ||
31 | { | ||
32 | return ranges::view::filter([] (const Entity& entity) { | ||
33 | return entity.isTrack; | ||
34 | }); | ||
35 | } | ||
36 | |||
37 | inline auto isScheduled() | ||
38 | { | ||
39 | return ranges::view::filter([] (const Entity& entity) { | ||
40 | return entity.scheduled; | ||
41 | }); | ||
42 | } | ||
43 | |||
44 | inline auto isOnLayer(Layer layer) | ||
45 | { | ||
46 | return ranges::view::filter([layer] (const Entity& entity) { | ||
47 | return entity.layer == layer; | ||
48 | }); | ||
49 | } | ||
50 | |||
51 | inline auto canBePushedBy(ColliderType ctype) | ||
52 | { | ||
53 | return ranges::view::filter([ctype] (const Entity& entity) { | ||
54 | return entity.canBePushedBy.count(ctype); | ||
55 | }); | ||
56 | } | ||
57 | |||
58 | |||
59 | |||
60 | } | ||
61 | |||
62 | #endif /* end of include guard: VIEWS_H_98651096 */ | ||